Moving the htmlpage API into a submodule in preparation of adding in an example of its usage
1.1 --- a/htmlpage/pom.xml Fri Nov 09 09:00:46 2012 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,55 +0,0 @@
1.4 -<?xml version="1.0"?>
1.5 -<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
1.6 - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1.7 - <modelVersion>4.0.0</modelVersion>
1.8 - <parent>
1.9 - <groupId>org.apidesign</groupId>
1.10 - <artifactId>bck2brwsr</artifactId>
1.11 - <version>1.0-SNAPSHOT</version>
1.12 - </parent>
1.13 - <groupId>org.apidesign.bck2brwsr</groupId>
1.14 - <artifactId>htmlpage</artifactId>
1.15 - <version>1.0-SNAPSHOT</version>
1.16 - <name>htmlpage</name>
1.17 - <url>http://maven.apache.org</url>
1.18 - <properties>
1.19 - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1.20 - </properties>
1.21 - <dependencies>
1.22 - <dependency>
1.23 - <groupId>org.testng</groupId>
1.24 - <artifactId>testng</artifactId>
1.25 - <scope>test</scope>
1.26 - <exclusions>
1.27 - <exclusion>
1.28 - <artifactId>junit</artifactId>
1.29 - <groupId>junit</groupId>
1.30 - </exclusion>
1.31 - </exclusions>
1.32 - </dependency>
1.33 - <dependency>
1.34 - <groupId>org.netbeans.api</groupId>
1.35 - <artifactId>org-openide-util-lookup</artifactId>
1.36 - </dependency>
1.37 - <dependency>
1.38 - <groupId>org.apidesign.bck2brwsr</groupId>
1.39 - <artifactId>core</artifactId>
1.40 - <version>1.0-SNAPSHOT</version>
1.41 - <type>jar</type>
1.42 - </dependency>
1.43 - <dependency>
1.44 - <groupId>org.apidesign.bck2brwsr</groupId>
1.45 - <artifactId>emul</artifactId>
1.46 - <version>1.0-SNAPSHOT</version>
1.47 - <type>jar</type>
1.48 - <scope>runtime</scope>
1.49 - </dependency>
1.50 - <dependency>
1.51 - <groupId>org.apidesign.bck2brwsr</groupId>
1.52 - <artifactId>vm4brwsr</artifactId>
1.53 - <version>0.1-SNAPSHOT</version>
1.54 - <type>jar</type>
1.55 - <scope>test</scope>
1.56 - </dependency>
1.57 - </dependencies>
1.58 -</project>
2.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Fri Nov 09 09:00:46 2012 +0100
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,233 +0,0 @@
2.4 -/**
2.5 - * Back 2 Browser Bytecode Translator
2.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.7 - *
2.8 - * This program is free software: you can redistribute it and/or modify
2.9 - * it under the terms of the GNU General Public License as published by
2.10 - * the Free Software Foundation, version 2 of the License.
2.11 - *
2.12 - * This program is distributed in the hope that it will be useful,
2.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 - * GNU General Public License for more details.
2.16 - *
2.17 - * You should have received a copy of the GNU General Public License
2.18 - * along with this program. Look for COPYING file in the top folder.
2.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
2.20 - */
2.21 -package org.apidesign.bck2brwsr.htmlpage;
2.22 -
2.23 -import java.io.IOException;
2.24 -import java.io.InputStream;
2.25 -import java.io.OutputStreamWriter;
2.26 -import java.io.Writer;
2.27 -import java.util.ArrayList;
2.28 -import java.util.Collections;
2.29 -import java.util.List;
2.30 -import java.util.Locale;
2.31 -import java.util.Set;
2.32 -import javax.annotation.processing.AbstractProcessor;
2.33 -import javax.annotation.processing.Completion;
2.34 -import javax.annotation.processing.Completions;
2.35 -import javax.annotation.processing.Processor;
2.36 -import javax.annotation.processing.RoundEnvironment;
2.37 -import javax.annotation.processing.SupportedAnnotationTypes;
2.38 -import javax.lang.model.element.AnnotationMirror;
2.39 -import javax.lang.model.element.Element;
2.40 -import javax.lang.model.element.ElementKind;
2.41 -import javax.lang.model.element.ExecutableElement;
2.42 -import javax.lang.model.element.Modifier;
2.43 -import javax.lang.model.element.PackageElement;
2.44 -import javax.lang.model.element.TypeElement;
2.45 -import javax.lang.model.type.TypeMirror;
2.46 -import javax.tools.Diagnostic;
2.47 -import javax.tools.FileObject;
2.48 -import javax.tools.StandardLocation;
2.49 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
2.50 -import org.apidesign.bck2brwsr.htmlpage.api.Page;
2.51 -import org.openide.util.lookup.ServiceProvider;
2.52 -
2.53 -/** Annotation processor to process an XHTML page and generate appropriate
2.54 - * "id" file.
2.55 - *
2.56 - * @author Jaroslav Tulach <jtulach@netbeans.org>
2.57 - */
2.58 -@ServiceProvider(service=Processor.class)
2.59 -@SupportedAnnotationTypes({
2.60 - "org.apidesign.bck2brwsr.htmlpage.api.Page",
2.61 - "org.apidesign.bck2brwsr.htmlpage.api.OnClick"
2.62 -})
2.63 -public final class PageProcessor extends AbstractProcessor {
2.64 - @Override
2.65 - public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
2.66 - for (Element e : roundEnv.getElementsAnnotatedWith(Page.class)) {
2.67 - Page p = e.getAnnotation(Page.class);
2.68 - PackageElement pe = (PackageElement)e.getEnclosingElement();
2.69 - String pkg = pe.getQualifiedName().toString();
2.70 -
2.71 - ProcessPage pp;
2.72 - try {
2.73 - InputStream is = openStream(pkg, p.xhtml());
2.74 - pp = ProcessPage.readPage(is);
2.75 - is.close();
2.76 - } catch (IOException iOException) {
2.77 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Can't read " + p.xhtml(), e);
2.78 - return false;
2.79 - }
2.80 - Writer w;
2.81 - String className = p.className();
2.82 - if (className.isEmpty()) {
2.83 - int indx = p.xhtml().indexOf('.');
2.84 - className = p.xhtml().substring(0, indx);
2.85 - }
2.86 - try {
2.87 - FileObject java = processingEnv.getFiler().createSourceFile(pkg + '.' + className, e);
2.88 - w = new OutputStreamWriter(java.openOutputStream());
2.89 - try {
2.90 - w.append("package " + pkg + ";\n");
2.91 - w.append("import org.apidesign.bck2brwsr.htmlpage.api.*;\n");
2.92 - w.append("class ").append(className).append(" {\n");
2.93 - for (String id : pp.ids()) {
2.94 - String tag = pp.tagNameForId(id);
2.95 - String type = type(tag);
2.96 - w.append(" ").append("public static final ").
2.97 - append(type).append(' ').append(cnstnt(id)).append(" = new ").
2.98 - append(type).append("(\"").append(id).append("\");\n");
2.99 - }
2.100 - w.append(" static {\n");
2.101 - if (!initializeOnClick(pe, w, pp)) {
2.102 - return false;
2.103 - }
2.104 - w.append(" }\n");
2.105 - w.append("}\n");
2.106 - } finally {
2.107 - w.close();
2.108 - }
2.109 - } catch (IOException ex) {
2.110 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Can't create " + className + ".java", e);
2.111 - return false;
2.112 - }
2.113 - }
2.114 - return true;
2.115 - }
2.116 -
2.117 - private InputStream openStream(String pkg, String name) throws IOException {
2.118 - try {
2.119 - FileObject fo = processingEnv.getFiler().getResource(
2.120 - StandardLocation.SOURCE_PATH, pkg, name);
2.121 - return fo.openInputStream();
2.122 - } catch (IOException ex) {
2.123 - return processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, pkg, name).openInputStream();
2.124 - }
2.125 - }
2.126 -
2.127 - private static String type(String tag) {
2.128 - if (tag.equals("title")) {
2.129 - return "Title";
2.130 - }
2.131 - if (tag.equals("button")) {
2.132 - return "Button";
2.133 - }
2.134 - if (tag.equals("input")) {
2.135 - return "Input";
2.136 - }
2.137 - return "Element";
2.138 - }
2.139 -
2.140 - private static String cnstnt(String id) {
2.141 - return id.toUpperCase(Locale.ENGLISH).replace('.', '_');
2.142 - }
2.143 -
2.144 - private boolean initializeOnClick(PackageElement pe, Writer w, ProcessPage pp) throws IOException {
2.145 - TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType();
2.146 - for (Element clazz : pe.getEnclosedElements()) {
2.147 - if (clazz.getKind() != ElementKind.CLASS) {
2.148 - continue;
2.149 - }
2.150 - TypeElement type = (TypeElement)clazz;
2.151 - for (Element method : clazz.getEnclosedElements()) {
2.152 - OnClick oc = method.getAnnotation(OnClick.class);
2.153 - if (oc != null) {
2.154 - for (String id : oc.id()) {
2.155 - if (pp.tagNameForId(id) == null) {
2.156 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
2.157 - return false;
2.158 - }
2.159 - ExecutableElement ee = (ExecutableElement)method;
2.160 - boolean hasParam;
2.161 - if (ee.getParameters().isEmpty()) {
2.162 - hasParam = false;
2.163 - } else {
2.164 - if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
2.165 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
2.166 - return false;
2.167 - }
2.168 - hasParam = true;
2.169 - }
2.170 - if (!ee.getModifiers().contains(Modifier.STATIC)) {
2.171 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
2.172 - return false;
2.173 - }
2.174 - if (ee.getModifiers().contains(Modifier.PRIVATE)) {
2.175 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
2.176 - return false;
2.177 - }
2.178 - w.append(" ").append(cnstnt(id)).
2.179 - append(".addOnClick(new Runnable() { public void run() {\n");
2.180 - w.append(" ").append(type.getSimpleName().toString()).
2.181 - append('.').append(ee.getSimpleName()).append("(");
2.182 - if (hasParam) {
2.183 - w.append("\"").append(id).append("\"");
2.184 - }
2.185 - w.append(");\n");
2.186 - w.append(" }});\n");
2.187 - }
2.188 - }
2.189 - }
2.190 - }
2.191 - return true;
2.192 - }
2.193 -
2.194 - @Override
2.195 - public Iterable<? extends Completion> getCompletions(
2.196 - Element element, AnnotationMirror annotation,
2.197 - ExecutableElement member, String userText
2.198 - ) {
2.199 - if (!userText.startsWith("\"")) {
2.200 - return Collections.emptyList();
2.201 - }
2.202 -
2.203 - Element cls = findClass(element);
2.204 - Page p = cls.getAnnotation(Page.class);
2.205 - PackageElement pe = (PackageElement) cls.getEnclosingElement();
2.206 - String pkg = pe.getQualifiedName().toString();
2.207 - ProcessPage pp;
2.208 - try {
2.209 - InputStream is = openStream(pkg, p.xhtml());
2.210 - pp = ProcessPage.readPage(is);
2.211 - is.close();
2.212 - } catch (IOException iOException) {
2.213 - return Collections.emptyList();
2.214 - }
2.215 -
2.216 - List<Completion> cc = new ArrayList<Completion>();
2.217 - userText = userText.substring(1);
2.218 - for (String id : pp.ids()) {
2.219 - if (id.startsWith(userText)) {
2.220 - cc.add(Completions.of("\"" + id + "\"", id));
2.221 - }
2.222 - }
2.223 - return cc;
2.224 - }
2.225 -
2.226 - private static Element findClass(Element e) {
2.227 - if (e == null) {
2.228 - return null;
2.229 - }
2.230 - Page p = e.getAnnotation(Page.class);
2.231 - if (p != null) {
2.232 - return e;
2.233 - }
2.234 - return e.getEnclosingElement();
2.235 - }
2.236 -}
3.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/ProcessPage.java Fri Nov 09 09:00:46 2012 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,78 +0,0 @@
3.4 -/**
3.5 - * Back 2 Browser Bytecode Translator
3.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 - *
3.8 - * This program is free software: you can redistribute it and/or modify
3.9 - * it under the terms of the GNU General Public License as published by
3.10 - * the Free Software Foundation, version 2 of the License.
3.11 - *
3.12 - * This program is distributed in the hope that it will be useful,
3.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 - * GNU General Public License for more details.
3.16 - *
3.17 - * You should have received a copy of the GNU General Public License
3.18 - * along with this program. Look for COPYING file in the top folder.
3.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
3.20 - */
3.21 -package org.apidesign.bck2brwsr.htmlpage;
3.22 -
3.23 -import java.io.IOException;
3.24 -import java.io.InputStream;
3.25 -import java.util.Collections;
3.26 -import java.util.Map;
3.27 -import java.util.Set;
3.28 -import java.util.TreeMap;
3.29 -import javax.xml.parsers.DocumentBuilder;
3.30 -import javax.xml.parsers.DocumentBuilderFactory;
3.31 -import org.w3c.dom.Document;
3.32 -import org.w3c.dom.Element;
3.33 -import org.w3c.dom.Node;
3.34 -import org.w3c.dom.NodeList;
3.35 -
3.36 -class ProcessPage {
3.37 - private final Map<String,String> ids2Elems = new TreeMap<String, String>();
3.38 -
3.39 - public Set<String> ids() {
3.40 - return Collections.unmodifiableSet(ids2Elems.keySet());
3.41 - }
3.42 -
3.43 - public String tagNameForId(String id) {
3.44 - return ids2Elems.get(id);
3.45 - }
3.46 -
3.47 - public static ProcessPage readPage(InputStream is) throws IOException {
3.48 - DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
3.49 - f.setValidating(false);
3.50 - f.setIgnoringComments(true);
3.51 -
3.52 - Document doc = null;
3.53 - try {
3.54 - DocumentBuilder b = f.newDocumentBuilder();
3.55 - doc = b.parse(is);
3.56 - } catch (IOException ex) {
3.57 - throw ex;
3.58 - } catch (Exception e) {
3.59 - throw new IOException(e);
3.60 - }
3.61 - Element root = doc.getDocumentElement();
3.62 -
3.63 - ProcessPage pp = new ProcessPage();
3.64 - pp.seekForIds(root);
3.65 - return pp;
3.66 - }
3.67 -
3.68 - private void seekForIds(Element e) {
3.69 - String val = e.getAttribute("id");
3.70 - if (val != null && !val.isEmpty()) {
3.71 - String prev = ids2Elems.put(val, e.getTagName());
3.72 - }
3.73 - NodeList arr = e.getChildNodes();
3.74 - for (int i = 0; i < arr.getLength(); i++) {
3.75 - final Node n = arr.item(i);
3.76 - if (n instanceof Element) {
3.77 - seekForIds((Element)n);
3.78 - }
3.79 - }
3.80 - }
3.81 -}
4.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Button.java Fri Nov 09 09:00:46 2012 +0100
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,36 +0,0 @@
4.4 -/**
4.5 - * Back 2 Browser Bytecode Translator
4.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.7 - *
4.8 - * This program is free software: you can redistribute it and/or modify
4.9 - * it under the terms of the GNU General Public License as published by
4.10 - * the Free Software Foundation, version 2 of the License.
4.11 - *
4.12 - * This program is distributed in the hope that it will be useful,
4.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 - * GNU General Public License for more details.
4.16 - *
4.17 - * You should have received a copy of the GNU General Public License
4.18 - * along with this program. Look for COPYING file in the top folder.
4.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
4.20 - */
4.21 -package org.apidesign.bck2brwsr.htmlpage.api;
4.22 -
4.23 -/**
4.24 - *
4.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
4.26 - */
4.27 -public final class Button extends Element {
4.28 - public Button(String id) {
4.29 - super(id);
4.30 - }
4.31 -
4.32 - @Override
4.33 - void dontSubclass() {
4.34 - }
4.35 -
4.36 - public void setDisabled(boolean state) {
4.37 - setAttribute(this, "disabled", state);
4.38 - }
4.39 -}
5.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java Fri Nov 09 09:00:46 2012 +0100
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,65 +0,0 @@
5.4 -/**
5.5 - * Back 2 Browser Bytecode Translator
5.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 - *
5.8 - * This program is free software: you can redistribute it and/or modify
5.9 - * it under the terms of the GNU General Public License as published by
5.10 - * the Free Software Foundation, version 2 of the License.
5.11 - *
5.12 - * This program is distributed in the hope that it will be useful,
5.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 - * GNU General Public License for more details.
5.16 - *
5.17 - * You should have received a copy of the GNU General Public License
5.18 - * along with this program. Look for COPYING file in the top folder.
5.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
5.20 - */
5.21 -package org.apidesign.bck2brwsr.htmlpage.api;
5.22 -
5.23 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
5.24 -
5.25 -/** Represents a generic HTML element.
5.26 - *
5.27 - * @author Jaroslav Tulach <jtulach@netbeans.org>
5.28 - */
5.29 -public abstract class Element {
5.30 - private final String id;
5.31 -
5.32 - public Element(String id) {
5.33 - this.id = id;
5.34 - }
5.35 -
5.36 - abstract void dontSubclass();
5.37 -
5.38 - @JavaScriptBody(
5.39 - args={"el", "property", "value"},
5.40 - body="var e = window.document.getElementById(el.fld_id);\n"
5.41 - + "e[property] = value;\n"
5.42 - )
5.43 - static void setAttribute(Element el, String property, Object value) {
5.44 - throw new UnsupportedOperationException("Needs JavaScript!");
5.45 - }
5.46 -
5.47 - @JavaScriptBody(
5.48 - args={"el", "property"},
5.49 - body="var e = window.document.getElementById(el.fld_id);\n"
5.50 - + "return e[property];\n"
5.51 - )
5.52 - static Object getAttribute(Element el, String property) {
5.53 - throw new UnsupportedOperationException("Needs JavaScript!");
5.54 - }
5.55 -
5.56 - /** Executes given runnable when user performs a "click" on the given
5.57 - * element.
5.58 - * @param r the runnable to execute, never null
5.59 - */
5.60 - @JavaScriptBody(
5.61 - args={"el", "r"},
5.62 - body="var e = window.document.getElementById(el.fld_id);\n"
5.63 - + "e.onclick = function() { r.runV(); };\n"
5.64 - )
5.65 - public final void addOnClick(Runnable r) {
5.66 - throw new UnsupportedOperationException("Needs JavaScript!");
5.67 - }
5.68 -}
6.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java Fri Nov 09 09:00:46 2012 +0100
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,44 +0,0 @@
6.4 -/**
6.5 - * Back 2 Browser Bytecode Translator
6.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.7 - *
6.8 - * This program is free software: you can redistribute it and/or modify
6.9 - * it under the terms of the GNU General Public License as published by
6.10 - * the Free Software Foundation, version 2 of the License.
6.11 - *
6.12 - * This program is distributed in the hope that it will be useful,
6.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 - * GNU General Public License for more details.
6.16 - *
6.17 - * You should have received a copy of the GNU General Public License
6.18 - * along with this program. Look for COPYING file in the top folder.
6.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
6.20 - */
6.21 -package org.apidesign.bck2brwsr.htmlpage.api;
6.22 -
6.23 -/**
6.24 - *
6.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
6.26 - */
6.27 -public final class Input extends Element {
6.28 - public Input(String id) {
6.29 - super(id);
6.30 - }
6.31 -
6.32 - @Override
6.33 - void dontSubclass() {
6.34 - }
6.35 -
6.36 - public void setAutocomplete(boolean state) {
6.37 - setAttribute(this, "autocomplete", state);
6.38 - }
6.39 -
6.40 - public final String getValue() {
6.41 - return (String)getAttribute(this, "value");
6.42 - }
6.43 -
6.44 - public final void setValue(String txt) {
6.45 - setAttribute(this, "value", txt);
6.46 - }
6.47 -}
7.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Fri Nov 09 09:00:46 2012 +0100
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,34 +0,0 @@
7.4 -/**
7.5 - * Back 2 Browser Bytecode Translator
7.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.7 - *
7.8 - * This program is free software: you can redistribute it and/or modify
7.9 - * it under the terms of the GNU General Public License as published by
7.10 - * the Free Software Foundation, version 2 of the License.
7.11 - *
7.12 - * This program is distributed in the hope that it will be useful,
7.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 - * GNU General Public License for more details.
7.16 - *
7.17 - * You should have received a copy of the GNU General Public License
7.18 - * along with this program. Look for COPYING file in the top folder.
7.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
7.20 - */
7.21 -package org.apidesign.bck2brwsr.htmlpage.api;
7.22 -
7.23 -import java.lang.annotation.ElementType;
7.24 -import java.lang.annotation.Retention;
7.25 -import java.lang.annotation.RetentionPolicy;
7.26 -import java.lang.annotation.Target;
7.27 -
7.28 -/** Adds an onClick handler to an element identified by given <em>id</em>.
7.29 - * Apply on a <code>public static void</code> method with no arguments.
7.30 - *
7.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
7.32 - */
7.33 -@Retention(RetentionPolicy.SOURCE)
7.34 -@Target(ElementType.METHOD)
7.35 -public @interface OnClick {
7.36 - String[] id();
7.37 -}
8.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java Fri Nov 09 09:00:46 2012 +0100
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,39 +0,0 @@
8.4 -/**
8.5 - * Back 2 Browser Bytecode Translator
8.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.7 - *
8.8 - * This program is free software: you can redistribute it and/or modify
8.9 - * it under the terms of the GNU General Public License as published by
8.10 - * the Free Software Foundation, version 2 of the License.
8.11 - *
8.12 - * This program is distributed in the hope that it will be useful,
8.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 - * GNU General Public License for more details.
8.16 - *
8.17 - * You should have received a copy of the GNU General Public License
8.18 - * along with this program. Look for COPYING file in the top folder.
8.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
8.20 - */
8.21 -package org.apidesign.bck2brwsr.htmlpage.api;
8.22 -
8.23 -import java.lang.annotation.ElementType;
8.24 -import java.lang.annotation.Retention;
8.25 -import java.lang.annotation.RetentionPolicy;
8.26 -import java.lang.annotation.Target;
8.27 -
8.28 -/** Converts an XHTML page into a Java class that contains
8.29 - * references to all IDs.
8.30 - *
8.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
8.32 - */
8.33 -@Retention(RetentionPolicy.SOURCE)
8.34 -@Target(ElementType.TYPE)
8.35 -public @interface Page {
8.36 - /** Path to the XHTML page to read in */
8.37 - String xhtml();
8.38 - /** Name of a Java class to generate. It will contain constants for all
8.39 - * found elements with IDs.
8.40 - */
8.41 - String className() default "";
8.42 -}
9.1 --- a/htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java Fri Nov 09 09:00:46 2012 +0100
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,36 +0,0 @@
9.4 -/**
9.5 - * Back 2 Browser Bytecode Translator
9.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.7 - *
9.8 - * This program is free software: you can redistribute it and/or modify
9.9 - * it under the terms of the GNU General Public License as published by
9.10 - * the Free Software Foundation, version 2 of the License.
9.11 - *
9.12 - * This program is distributed in the hope that it will be useful,
9.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.15 - * GNU General Public License for more details.
9.16 - *
9.17 - * You should have received a copy of the GNU General Public License
9.18 - * along with this program. Look for COPYING file in the top folder.
9.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
9.20 - */
9.21 -package org.apidesign.bck2brwsr.htmlpage.api;
9.22 -
9.23 -/**
9.24 - *
9.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
9.26 - */
9.27 -public class Title extends Element {
9.28 - public Title(String id) {
9.29 - super(id);
9.30 - }
9.31 -
9.32 - @Override
9.33 - void dontSubclass() {
9.34 - }
9.35 -
9.36 - public final void setText(String text) {
9.37 - setAttribute(this, "innerHTML", text);
9.38 - }
9.39 -}
10.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Fri Nov 09 09:00:46 2012 +0100
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,57 +0,0 @@
10.4 -/**
10.5 - * Back 2 Browser Bytecode Translator
10.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.7 - *
10.8 - * This program is free software: you can redistribute it and/or modify
10.9 - * it under the terms of the GNU General Public License as published by
10.10 - * the Free Software Foundation, version 2 of the License.
10.11 - *
10.12 - * This program is distributed in the hope that it will be useful,
10.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 - * GNU General Public License for more details.
10.16 - *
10.17 - * You should have received a copy of the GNU General Public License
10.18 - * along with this program. Look for COPYING file in the top folder.
10.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
10.20 - */
10.21 -package org.apidesign.bck2brwsr.htmlpage;
10.22 -
10.23 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
10.24 -import org.apidesign.bck2brwsr.htmlpage.api.Page;
10.25 -
10.26 -/** Trivial demo for the bck2brwsr project. First of all start
10.27 - * with <a href="TestPage.html">your XHTML page</a>. Include there
10.28 - * a script that will <em>boot Java</em> in your browser.
10.29 - * <p>
10.30 - * Then use <code>@Page</code> annotation to
10.31 - * generate a Java representation of elements with IDs in that page.
10.32 - * Depending on the type of the elements, they will have different
10.33 - * methods (e.g. <code>PG_TITLE</code> has <code>setText</code>, etc.).
10.34 - * Use <code>@OnClick</code> annotation to associate behavior
10.35 - * with existing elements. Use the generated elements
10.36 - * (<code>PG_TITLE</code>, <code>PG_TEXT</code>) to modify the page.
10.37 - * <p>
10.38 - * Everything is type-safe. As soon as somebody modifies the page and
10.39 - * removes the IDs or re-assigns them to wrong elements. Java compiler
10.40 - * will emit an error.
10.41 - * <p>
10.42 - * Welcome to the type-safe HTML5 world!
10.43 - *
10.44 - * @author Jaroslav Tulach <jtulach@netbeans.org>
10.45 - */
10.46 -@Page(xhtml="TestPage.html")
10.47 -public class PageController {
10.48 - @OnClick(id="pg.button")
10.49 - static void updateTitle() {
10.50 - TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
10.51 - }
10.52 -
10.53 - @OnClick(id={ "pg.title", "pg.text" })
10.54 - static void click(String id) {
10.55 - if (!id.equals("pg.title")) {
10.56 - throw new IllegalStateException();
10.57 - }
10.58 - TestPage.PG_TITLE.setText(id);
10.59 - }
10.60 -}
11.1 --- a/htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Fri Nov 09 09:00:46 2012 +0100
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,148 +0,0 @@
11.4 -/**
11.5 - * Back 2 Browser Bytecode Translator
11.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
11.7 - *
11.8 - * This program is free software: you can redistribute it and/or modify
11.9 - * it under the terms of the GNU General Public License as published by
11.10 - * the Free Software Foundation, version 2 of the License.
11.11 - *
11.12 - * This program is distributed in the hope that it will be useful,
11.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.15 - * GNU General Public License for more details.
11.16 - *
11.17 - * You should have received a copy of the GNU General Public License
11.18 - * along with this program. Look for COPYING file in the top folder.
11.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
11.20 - */
11.21 -package org.apidesign.bck2brwsr.htmlpage;
11.22 -
11.23 -import java.io.IOException;
11.24 -import java.io.InputStream;
11.25 -import java.lang.reflect.Method;
11.26 -import java.util.Set;
11.27 -import javax.script.Invocable;
11.28 -import javax.script.ScriptEngine;
11.29 -import javax.script.ScriptEngineManager;
11.30 -import javax.script.ScriptException;
11.31 -import org.testng.annotations.Test;
11.32 -import static org.testng.Assert.*;
11.33 -
11.34 -public class ProcessPageTest {
11.35 -
11.36 -
11.37 - @Test public void findsThreeIds() throws IOException {
11.38 - InputStream is = ProcessPageTest.class.getResourceAsStream("TestPage.html");
11.39 - assertNotNull(is, "Sample HTML page found");
11.40 - ProcessPage res = ProcessPage.readPage(is);
11.41 - final Set<String> ids = res.ids();
11.42 - assertEquals(ids.size(), 3, "Three ids found: " + ids);
11.43 -
11.44 - assertEquals(res.tagNameForId("pg.title"), "title");
11.45 - assertEquals(res.tagNameForId("pg.button"), "button");
11.46 - assertEquals(res.tagNameForId("pg.text"), "input");
11.47 - }
11.48 -
11.49 - @Test public void testCompileAndRunPageController() throws Exception {
11.50 - StringBuilder sb = new StringBuilder();
11.51 - sb.append(
11.52 - "var window = new Object();\n"
11.53 - + "var doc = new Object();\n"
11.54 - + "doc.button = new Object();\n"
11.55 - + "doc.title = new Object();\n"
11.56 - + "doc.title.innerHTML = 'nothing';\n"
11.57 - + "doc.text = new Object();\n"
11.58 - + "doc.text.value = 'something';\n"
11.59 - + "doc.getElementById = function(id) {\n"
11.60 - + " switch(id) {\n"
11.61 - + " case 'pg.button': return doc.button;\n"
11.62 - + " case 'pg.title': return doc.title;\n"
11.63 - + " case 'pg.text': return doc.text;\n"
11.64 - + " }\n"
11.65 - + " throw id;\n"
11.66 - + " }\n"
11.67 - + "\n"
11.68 - + "function clickAndCheck() {\n"
11.69 - + " doc.button.onclick();\n"
11.70 - + " return doc.title.innerHTML.toString();\n"
11.71 - + "};\n"
11.72 - + "\n"
11.73 - + "window.document = doc;\n"
11.74 - );
11.75 - Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
11.76 -
11.77 - Object ret = null;
11.78 - try {
11.79 - ret = i.invokeFunction("clickAndCheck");
11.80 - } catch (ScriptException ex) {
11.81 - fail("Execution failed in " + sb, ex);
11.82 - } catch (NoSuchMethodException ex) {
11.83 - fail("Cannot find method in " + sb, ex);
11.84 - }
11.85 - assertEquals(ret, "You want this window to be named something", "We expect that the JavaCode performs all the wiring");
11.86 - }
11.87 -
11.88 - @Test public void clickWithArgumentCalled() throws Exception {
11.89 - StringBuilder sb = new StringBuilder();
11.90 - sb.append(
11.91 - "var window = new Object();\n"
11.92 - + "var doc = new Object();\n"
11.93 - + "doc.button = new Object();\n"
11.94 - + "doc.title = new Object();\n"
11.95 - + "doc.title.innerHTML = 'nothing';\n"
11.96 - + "doc.text = new Object();\n"
11.97 - + "doc.text.value = 'something';\n"
11.98 - + "doc.getElementById = function(id) {\n"
11.99 - + " switch(id) {\n"
11.100 - + " case 'pg.button': return doc.button;\n"
11.101 - + " case 'pg.title': return doc.title;\n"
11.102 - + " case 'pg.text': return doc.text;\n"
11.103 - + " }\n"
11.104 - + " throw id;\n"
11.105 - + " }\n"
11.106 - + "\n"
11.107 - + "function clickAndCheck() {\n"
11.108 - + " doc.title.onclick();\n"
11.109 - + " return doc.title.innerHTML.toString();\n"
11.110 - + "};\n"
11.111 - + "\n"
11.112 - + "window.document = doc;\n"
11.113 - );
11.114 - Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
11.115 -
11.116 - Object ret = null;
11.117 - try {
11.118 - ret = i.invokeFunction("clickAndCheck");
11.119 - } catch (ScriptException ex) {
11.120 - fail("Execution failed in " + sb, ex);
11.121 - } catch (NoSuchMethodException ex) {
11.122 - fail("Cannot find method in " + sb, ex);
11.123 - }
11.124 - assertEquals(ret, "pg.title", "Title has been passed to the method argument");
11.125 - }
11.126 -
11.127 - static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
11.128 - if (sb == null) {
11.129 - sb = new StringBuilder();
11.130 - }
11.131 - try {
11.132 - Method m;
11.133 - Class<?> genJS = Class.forName("org.apidesign.vm4brwsr.GenJS");
11.134 - m = genJS.getDeclaredMethod("compile", Appendable.class, String[].class);
11.135 - m.setAccessible(true);
11.136 - m.invoke(null, sb, names);
11.137 - } catch (Exception exception) {
11.138 - throw new IOException(exception);
11.139 - }
11.140 - ScriptEngineManager sem = new ScriptEngineManager();
11.141 - ScriptEngine js = sem.getEngineByExtension("js");
11.142 - try {
11.143 - Object res = js.eval(sb.toString());
11.144 - assertTrue(js instanceof Invocable, "It is invocable object: " + res);
11.145 - return (Invocable) js;
11.146 - } catch (ScriptException ex) {
11.147 - fail("Could not compile:\n" + sb, ex);
11.148 - return null;
11.149 - }
11.150 - }
11.151 -}
12.1 --- a/htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html Fri Nov 09 09:00:46 2012 +0100
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,30 +0,0 @@
12.4 -<?xml version="1.0" encoding="UTF-8"?>
12.5 -<!--
12.6 -
12.7 - Back 2 Browser Bytecode Translator
12.8 - Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
12.9 -
12.10 - This program is free software: you can redistribute it and/or modify
12.11 - it under the terms of the GNU General Public License as published by
12.12 - the Free Software Foundation, version 2 of the License.
12.13 -
12.14 - This program is distributed in the hope that it will be useful,
12.15 - but WITHOUT ANY WARRANTY; without even the implied warranty of
12.16 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.17 - GNU General Public License for more details.
12.18 -
12.19 - You should have received a copy of the GNU General Public License
12.20 - along with this program. Look for COPYING file in the top folder.
12.21 - If not, see http://opensource.org/licenses/GPL-2.0.
12.22 -
12.23 --->
12.24 -<!DOCTYPE html>
12.25 -<html xmlns="http://www.w3.org/1999/xhtml">
12.26 - <head>
12.27 - <title id="pg.title">Default Title</title>
12.28 - </head>
12.29 - <body>
12.30 - New title: <input id="pg.text"/>
12.31 - <button id="pg.button">Change title!</button>
12.32 - </body>
12.33 -</html>
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/javaquery/api/pom.xml Fri Nov 09 11:47:00 2012 +0100
13.3 @@ -0,0 +1,55 @@
13.4 +<?xml version="1.0"?>
13.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
13.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
13.7 + <modelVersion>4.0.0</modelVersion>
13.8 + <parent>
13.9 + <groupId>org.apidesign.bck2brwsr</groupId>
13.10 + <artifactId>javaquery</artifactId>
13.11 + <version>1.0-SNAPSHOT</version>
13.12 + </parent>
13.13 + <groupId>org.apidesign.bck2brwsr</groupId>
13.14 + <artifactId>javaquery.api</artifactId>
13.15 + <version>1.0-SNAPSHOT</version>
13.16 + <name>JavaQuery API</name>
13.17 + <url>http://maven.apache.org</url>
13.18 + <properties>
13.19 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13.20 + </properties>
13.21 + <dependencies>
13.22 + <dependency>
13.23 + <groupId>org.testng</groupId>
13.24 + <artifactId>testng</artifactId>
13.25 + <scope>test</scope>
13.26 + <exclusions>
13.27 + <exclusion>
13.28 + <artifactId>junit</artifactId>
13.29 + <groupId>junit</groupId>
13.30 + </exclusion>
13.31 + </exclusions>
13.32 + </dependency>
13.33 + <dependency>
13.34 + <groupId>org.netbeans.api</groupId>
13.35 + <artifactId>org-openide-util-lookup</artifactId>
13.36 + </dependency>
13.37 + <dependency>
13.38 + <groupId>org.apidesign.bck2brwsr</groupId>
13.39 + <artifactId>core</artifactId>
13.40 + <version>1.0-SNAPSHOT</version>
13.41 + <type>jar</type>
13.42 + </dependency>
13.43 + <dependency>
13.44 + <groupId>org.apidesign.bck2brwsr</groupId>
13.45 + <artifactId>emul</artifactId>
13.46 + <version>1.0-SNAPSHOT</version>
13.47 + <type>jar</type>
13.48 + <scope>runtime</scope>
13.49 + </dependency>
13.50 + <dependency>
13.51 + <groupId>org.apidesign.bck2brwsr</groupId>
13.52 + <artifactId>vm4brwsr</artifactId>
13.53 + <version>0.1-SNAPSHOT</version>
13.54 + <type>jar</type>
13.55 + <scope>test</scope>
13.56 + </dependency>
13.57 + </dependencies>
13.58 +</project>
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Fri Nov 09 11:47:00 2012 +0100
14.3 @@ -0,0 +1,233 @@
14.4 +/**
14.5 + * Back 2 Browser Bytecode Translator
14.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
14.7 + *
14.8 + * This program is free software: you can redistribute it and/or modify
14.9 + * it under the terms of the GNU General Public License as published by
14.10 + * the Free Software Foundation, version 2 of the License.
14.11 + *
14.12 + * This program is distributed in the hope that it will be useful,
14.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.15 + * GNU General Public License for more details.
14.16 + *
14.17 + * You should have received a copy of the GNU General Public License
14.18 + * along with this program. Look for COPYING file in the top folder.
14.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
14.20 + */
14.21 +package org.apidesign.bck2brwsr.htmlpage;
14.22 +
14.23 +import java.io.IOException;
14.24 +import java.io.InputStream;
14.25 +import java.io.OutputStreamWriter;
14.26 +import java.io.Writer;
14.27 +import java.util.ArrayList;
14.28 +import java.util.Collections;
14.29 +import java.util.List;
14.30 +import java.util.Locale;
14.31 +import java.util.Set;
14.32 +import javax.annotation.processing.AbstractProcessor;
14.33 +import javax.annotation.processing.Completion;
14.34 +import javax.annotation.processing.Completions;
14.35 +import javax.annotation.processing.Processor;
14.36 +import javax.annotation.processing.RoundEnvironment;
14.37 +import javax.annotation.processing.SupportedAnnotationTypes;
14.38 +import javax.lang.model.element.AnnotationMirror;
14.39 +import javax.lang.model.element.Element;
14.40 +import javax.lang.model.element.ElementKind;
14.41 +import javax.lang.model.element.ExecutableElement;
14.42 +import javax.lang.model.element.Modifier;
14.43 +import javax.lang.model.element.PackageElement;
14.44 +import javax.lang.model.element.TypeElement;
14.45 +import javax.lang.model.type.TypeMirror;
14.46 +import javax.tools.Diagnostic;
14.47 +import javax.tools.FileObject;
14.48 +import javax.tools.StandardLocation;
14.49 +import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
14.50 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
14.51 +import org.openide.util.lookup.ServiceProvider;
14.52 +
14.53 +/** Annotation processor to process an XHTML page and generate appropriate
14.54 + * "id" file.
14.55 + *
14.56 + * @author Jaroslav Tulach <jtulach@netbeans.org>
14.57 + */
14.58 +@ServiceProvider(service=Processor.class)
14.59 +@SupportedAnnotationTypes({
14.60 + "org.apidesign.bck2brwsr.htmlpage.api.Page",
14.61 + "org.apidesign.bck2brwsr.htmlpage.api.OnClick"
14.62 +})
14.63 +public final class PageProcessor extends AbstractProcessor {
14.64 + @Override
14.65 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
14.66 + for (Element e : roundEnv.getElementsAnnotatedWith(Page.class)) {
14.67 + Page p = e.getAnnotation(Page.class);
14.68 + PackageElement pe = (PackageElement)e.getEnclosingElement();
14.69 + String pkg = pe.getQualifiedName().toString();
14.70 +
14.71 + ProcessPage pp;
14.72 + try {
14.73 + InputStream is = openStream(pkg, p.xhtml());
14.74 + pp = ProcessPage.readPage(is);
14.75 + is.close();
14.76 + } catch (IOException iOException) {
14.77 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Can't read " + p.xhtml(), e);
14.78 + return false;
14.79 + }
14.80 + Writer w;
14.81 + String className = p.className();
14.82 + if (className.isEmpty()) {
14.83 + int indx = p.xhtml().indexOf('.');
14.84 + className = p.xhtml().substring(0, indx);
14.85 + }
14.86 + try {
14.87 + FileObject java = processingEnv.getFiler().createSourceFile(pkg + '.' + className, e);
14.88 + w = new OutputStreamWriter(java.openOutputStream());
14.89 + try {
14.90 + w.append("package " + pkg + ";\n");
14.91 + w.append("import org.apidesign.bck2brwsr.htmlpage.api.*;\n");
14.92 + w.append("class ").append(className).append(" {\n");
14.93 + for (String id : pp.ids()) {
14.94 + String tag = pp.tagNameForId(id);
14.95 + String type = type(tag);
14.96 + w.append(" ").append("public static final ").
14.97 + append(type).append(' ').append(cnstnt(id)).append(" = new ").
14.98 + append(type).append("(\"").append(id).append("\");\n");
14.99 + }
14.100 + w.append(" static {\n");
14.101 + if (!initializeOnClick(pe, w, pp)) {
14.102 + return false;
14.103 + }
14.104 + w.append(" }\n");
14.105 + w.append("}\n");
14.106 + } finally {
14.107 + w.close();
14.108 + }
14.109 + } catch (IOException ex) {
14.110 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Can't create " + className + ".java", e);
14.111 + return false;
14.112 + }
14.113 + }
14.114 + return true;
14.115 + }
14.116 +
14.117 + private InputStream openStream(String pkg, String name) throws IOException {
14.118 + try {
14.119 + FileObject fo = processingEnv.getFiler().getResource(
14.120 + StandardLocation.SOURCE_PATH, pkg, name);
14.121 + return fo.openInputStream();
14.122 + } catch (IOException ex) {
14.123 + return processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, pkg, name).openInputStream();
14.124 + }
14.125 + }
14.126 +
14.127 + private static String type(String tag) {
14.128 + if (tag.equals("title")) {
14.129 + return "Title";
14.130 + }
14.131 + if (tag.equals("button")) {
14.132 + return "Button";
14.133 + }
14.134 + if (tag.equals("input")) {
14.135 + return "Input";
14.136 + }
14.137 + return "Element";
14.138 + }
14.139 +
14.140 + private static String cnstnt(String id) {
14.141 + return id.toUpperCase(Locale.ENGLISH).replace('.', '_');
14.142 + }
14.143 +
14.144 + private boolean initializeOnClick(PackageElement pe, Writer w, ProcessPage pp) throws IOException {
14.145 + TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType();
14.146 + for (Element clazz : pe.getEnclosedElements()) {
14.147 + if (clazz.getKind() != ElementKind.CLASS) {
14.148 + continue;
14.149 + }
14.150 + TypeElement type = (TypeElement)clazz;
14.151 + for (Element method : clazz.getEnclosedElements()) {
14.152 + OnClick oc = method.getAnnotation(OnClick.class);
14.153 + if (oc != null) {
14.154 + for (String id : oc.id()) {
14.155 + if (pp.tagNameForId(id) == null) {
14.156 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
14.157 + return false;
14.158 + }
14.159 + ExecutableElement ee = (ExecutableElement)method;
14.160 + boolean hasParam;
14.161 + if (ee.getParameters().isEmpty()) {
14.162 + hasParam = false;
14.163 + } else {
14.164 + if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
14.165 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
14.166 + return false;
14.167 + }
14.168 + hasParam = true;
14.169 + }
14.170 + if (!ee.getModifiers().contains(Modifier.STATIC)) {
14.171 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
14.172 + return false;
14.173 + }
14.174 + if (ee.getModifiers().contains(Modifier.PRIVATE)) {
14.175 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
14.176 + return false;
14.177 + }
14.178 + w.append(" ").append(cnstnt(id)).
14.179 + append(".addOnClick(new Runnable() { public void run() {\n");
14.180 + w.append(" ").append(type.getSimpleName().toString()).
14.181 + append('.').append(ee.getSimpleName()).append("(");
14.182 + if (hasParam) {
14.183 + w.append("\"").append(id).append("\"");
14.184 + }
14.185 + w.append(");\n");
14.186 + w.append(" }});\n");
14.187 + }
14.188 + }
14.189 + }
14.190 + }
14.191 + return true;
14.192 + }
14.193 +
14.194 + @Override
14.195 + public Iterable<? extends Completion> getCompletions(
14.196 + Element element, AnnotationMirror annotation,
14.197 + ExecutableElement member, String userText
14.198 + ) {
14.199 + if (!userText.startsWith("\"")) {
14.200 + return Collections.emptyList();
14.201 + }
14.202 +
14.203 + Element cls = findClass(element);
14.204 + Page p = cls.getAnnotation(Page.class);
14.205 + PackageElement pe = (PackageElement) cls.getEnclosingElement();
14.206 + String pkg = pe.getQualifiedName().toString();
14.207 + ProcessPage pp;
14.208 + try {
14.209 + InputStream is = openStream(pkg, p.xhtml());
14.210 + pp = ProcessPage.readPage(is);
14.211 + is.close();
14.212 + } catch (IOException iOException) {
14.213 + return Collections.emptyList();
14.214 + }
14.215 +
14.216 + List<Completion> cc = new ArrayList<Completion>();
14.217 + userText = userText.substring(1);
14.218 + for (String id : pp.ids()) {
14.219 + if (id.startsWith(userText)) {
14.220 + cc.add(Completions.of("\"" + id + "\"", id));
14.221 + }
14.222 + }
14.223 + return cc;
14.224 + }
14.225 +
14.226 + private static Element findClass(Element e) {
14.227 + if (e == null) {
14.228 + return null;
14.229 + }
14.230 + Page p = e.getAnnotation(Page.class);
14.231 + if (p != null) {
14.232 + return e;
14.233 + }
14.234 + return e.getEnclosingElement();
14.235 + }
14.236 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/ProcessPage.java Fri Nov 09 11:47:00 2012 +0100
15.3 @@ -0,0 +1,78 @@
15.4 +/**
15.5 + * Back 2 Browser Bytecode Translator
15.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
15.7 + *
15.8 + * This program is free software: you can redistribute it and/or modify
15.9 + * it under the terms of the GNU General Public License as published by
15.10 + * the Free Software Foundation, version 2 of the License.
15.11 + *
15.12 + * This program is distributed in the hope that it will be useful,
15.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.15 + * GNU General Public License for more details.
15.16 + *
15.17 + * You should have received a copy of the GNU General Public License
15.18 + * along with this program. Look for COPYING file in the top folder.
15.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
15.20 + */
15.21 +package org.apidesign.bck2brwsr.htmlpage;
15.22 +
15.23 +import java.io.IOException;
15.24 +import java.io.InputStream;
15.25 +import java.util.Collections;
15.26 +import java.util.Map;
15.27 +import java.util.Set;
15.28 +import java.util.TreeMap;
15.29 +import javax.xml.parsers.DocumentBuilder;
15.30 +import javax.xml.parsers.DocumentBuilderFactory;
15.31 +import org.w3c.dom.Document;
15.32 +import org.w3c.dom.Element;
15.33 +import org.w3c.dom.Node;
15.34 +import org.w3c.dom.NodeList;
15.35 +
15.36 +class ProcessPage {
15.37 + private final Map<String,String> ids2Elems = new TreeMap<String, String>();
15.38 +
15.39 + public Set<String> ids() {
15.40 + return Collections.unmodifiableSet(ids2Elems.keySet());
15.41 + }
15.42 +
15.43 + public String tagNameForId(String id) {
15.44 + return ids2Elems.get(id);
15.45 + }
15.46 +
15.47 + public static ProcessPage readPage(InputStream is) throws IOException {
15.48 + DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
15.49 + f.setValidating(false);
15.50 + f.setIgnoringComments(true);
15.51 +
15.52 + Document doc = null;
15.53 + try {
15.54 + DocumentBuilder b = f.newDocumentBuilder();
15.55 + doc = b.parse(is);
15.56 + } catch (IOException ex) {
15.57 + throw ex;
15.58 + } catch (Exception e) {
15.59 + throw new IOException(e);
15.60 + }
15.61 + Element root = doc.getDocumentElement();
15.62 +
15.63 + ProcessPage pp = new ProcessPage();
15.64 + pp.seekForIds(root);
15.65 + return pp;
15.66 + }
15.67 +
15.68 + private void seekForIds(Element e) {
15.69 + String val = e.getAttribute("id");
15.70 + if (val != null && !val.isEmpty()) {
15.71 + String prev = ids2Elems.put(val, e.getTagName());
15.72 + }
15.73 + NodeList arr = e.getChildNodes();
15.74 + for (int i = 0; i < arr.getLength(); i++) {
15.75 + final Node n = arr.item(i);
15.76 + if (n instanceof Element) {
15.77 + seekForIds((Element)n);
15.78 + }
15.79 + }
15.80 + }
15.81 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Button.java Fri Nov 09 11:47:00 2012 +0100
16.3 @@ -0,0 +1,36 @@
16.4 +/**
16.5 + * Back 2 Browser Bytecode Translator
16.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
16.7 + *
16.8 + * This program is free software: you can redistribute it and/or modify
16.9 + * it under the terms of the GNU General Public License as published by
16.10 + * the Free Software Foundation, version 2 of the License.
16.11 + *
16.12 + * This program is distributed in the hope that it will be useful,
16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.15 + * GNU General Public License for more details.
16.16 + *
16.17 + * You should have received a copy of the GNU General Public License
16.18 + * along with this program. Look for COPYING file in the top folder.
16.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
16.20 + */
16.21 +package org.apidesign.bck2brwsr.htmlpage.api;
16.22 +
16.23 +/**
16.24 + *
16.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
16.26 + */
16.27 +public final class Button extends Element {
16.28 + public Button(String id) {
16.29 + super(id);
16.30 + }
16.31 +
16.32 + @Override
16.33 + void dontSubclass() {
16.34 + }
16.35 +
16.36 + public void setDisabled(boolean state) {
16.37 + setAttribute(this, "disabled", state);
16.38 + }
16.39 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java Fri Nov 09 11:47:00 2012 +0100
17.3 @@ -0,0 +1,65 @@
17.4 +/**
17.5 + * Back 2 Browser Bytecode Translator
17.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
17.7 + *
17.8 + * This program is free software: you can redistribute it and/or modify
17.9 + * it under the terms of the GNU General Public License as published by
17.10 + * the Free Software Foundation, version 2 of the License.
17.11 + *
17.12 + * This program is distributed in the hope that it will be useful,
17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17.15 + * GNU General Public License for more details.
17.16 + *
17.17 + * You should have received a copy of the GNU General Public License
17.18 + * along with this program. Look for COPYING file in the top folder.
17.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
17.20 + */
17.21 +package org.apidesign.bck2brwsr.htmlpage.api;
17.22 +
17.23 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
17.24 +
17.25 +/** Represents a generic HTML element.
17.26 + *
17.27 + * @author Jaroslav Tulach <jtulach@netbeans.org>
17.28 + */
17.29 +public abstract class Element {
17.30 + private final String id;
17.31 +
17.32 + public Element(String id) {
17.33 + this.id = id;
17.34 + }
17.35 +
17.36 + abstract void dontSubclass();
17.37 +
17.38 + @JavaScriptBody(
17.39 + args={"el", "property", "value"},
17.40 + body="var e = window.document.getElementById(el.fld_id);\n"
17.41 + + "e[property] = value;\n"
17.42 + )
17.43 + static void setAttribute(Element el, String property, Object value) {
17.44 + throw new UnsupportedOperationException("Needs JavaScript!");
17.45 + }
17.46 +
17.47 + @JavaScriptBody(
17.48 + args={"el", "property"},
17.49 + body="var e = window.document.getElementById(el.fld_id);\n"
17.50 + + "return e[property];\n"
17.51 + )
17.52 + static Object getAttribute(Element el, String property) {
17.53 + throw new UnsupportedOperationException("Needs JavaScript!");
17.54 + }
17.55 +
17.56 + /** Executes given runnable when user performs a "click" on the given
17.57 + * element.
17.58 + * @param r the runnable to execute, never null
17.59 + */
17.60 + @JavaScriptBody(
17.61 + args={"el", "r"},
17.62 + body="var e = window.document.getElementById(el.fld_id);\n"
17.63 + + "e.onclick = function() { r.runV(); };\n"
17.64 + )
17.65 + public final void addOnClick(Runnable r) {
17.66 + throw new UnsupportedOperationException("Needs JavaScript!");
17.67 + }
17.68 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java Fri Nov 09 11:47:00 2012 +0100
18.3 @@ -0,0 +1,44 @@
18.4 +/**
18.5 + * Back 2 Browser Bytecode Translator
18.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
18.7 + *
18.8 + * This program is free software: you can redistribute it and/or modify
18.9 + * it under the terms of the GNU General Public License as published by
18.10 + * the Free Software Foundation, version 2 of the License.
18.11 + *
18.12 + * This program is distributed in the hope that it will be useful,
18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.15 + * GNU General Public License for more details.
18.16 + *
18.17 + * You should have received a copy of the GNU General Public License
18.18 + * along with this program. Look for COPYING file in the top folder.
18.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
18.20 + */
18.21 +package org.apidesign.bck2brwsr.htmlpage.api;
18.22 +
18.23 +/**
18.24 + *
18.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
18.26 + */
18.27 +public final class Input extends Element {
18.28 + public Input(String id) {
18.29 + super(id);
18.30 + }
18.31 +
18.32 + @Override
18.33 + void dontSubclass() {
18.34 + }
18.35 +
18.36 + public void setAutocomplete(boolean state) {
18.37 + setAttribute(this, "autocomplete", state);
18.38 + }
18.39 +
18.40 + public final String getValue() {
18.41 + return (String)getAttribute(this, "value");
18.42 + }
18.43 +
18.44 + public final void setValue(String txt) {
18.45 + setAttribute(this, "value", txt);
18.46 + }
18.47 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Fri Nov 09 11:47:00 2012 +0100
19.3 @@ -0,0 +1,34 @@
19.4 +/**
19.5 + * Back 2 Browser Bytecode Translator
19.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
19.7 + *
19.8 + * This program is free software: you can redistribute it and/or modify
19.9 + * it under the terms of the GNU General Public License as published by
19.10 + * the Free Software Foundation, version 2 of the License.
19.11 + *
19.12 + * This program is distributed in the hope that it will be useful,
19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.15 + * GNU General Public License for more details.
19.16 + *
19.17 + * You should have received a copy of the GNU General Public License
19.18 + * along with this program. Look for COPYING file in the top folder.
19.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
19.20 + */
19.21 +package org.apidesign.bck2brwsr.htmlpage.api;
19.22 +
19.23 +import java.lang.annotation.ElementType;
19.24 +import java.lang.annotation.Retention;
19.25 +import java.lang.annotation.RetentionPolicy;
19.26 +import java.lang.annotation.Target;
19.27 +
19.28 +/** Adds an onClick handler to an element identified by given <em>id</em>.
19.29 + * Apply on a <code>public static void</code> method with no arguments.
19.30 + *
19.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
19.32 + */
19.33 +@Retention(RetentionPolicy.SOURCE)
19.34 +@Target(ElementType.METHOD)
19.35 +public @interface OnClick {
19.36 + String[] id();
19.37 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java Fri Nov 09 11:47:00 2012 +0100
20.3 @@ -0,0 +1,39 @@
20.4 +/**
20.5 + * Back 2 Browser Bytecode Translator
20.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
20.7 + *
20.8 + * This program is free software: you can redistribute it and/or modify
20.9 + * it under the terms of the GNU General Public License as published by
20.10 + * the Free Software Foundation, version 2 of the License.
20.11 + *
20.12 + * This program is distributed in the hope that it will be useful,
20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.15 + * GNU General Public License for more details.
20.16 + *
20.17 + * You should have received a copy of the GNU General Public License
20.18 + * along with this program. Look for COPYING file in the top folder.
20.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
20.20 + */
20.21 +package org.apidesign.bck2brwsr.htmlpage.api;
20.22 +
20.23 +import java.lang.annotation.ElementType;
20.24 +import java.lang.annotation.Retention;
20.25 +import java.lang.annotation.RetentionPolicy;
20.26 +import java.lang.annotation.Target;
20.27 +
20.28 +/** Converts an XHTML page into a Java class that contains
20.29 + * references to all IDs.
20.30 + *
20.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
20.32 + */
20.33 +@Retention(RetentionPolicy.SOURCE)
20.34 +@Target(ElementType.TYPE)
20.35 +public @interface Page {
20.36 + /** Path to the XHTML page to read in */
20.37 + String xhtml();
20.38 + /** Name of a Java class to generate. It will contain constants for all
20.39 + * found elements with IDs.
20.40 + */
20.41 + String className() default "";
20.42 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java Fri Nov 09 11:47:00 2012 +0100
21.3 @@ -0,0 +1,36 @@
21.4 +/**
21.5 + * Back 2 Browser Bytecode Translator
21.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
21.7 + *
21.8 + * This program is free software: you can redistribute it and/or modify
21.9 + * it under the terms of the GNU General Public License as published by
21.10 + * the Free Software Foundation, version 2 of the License.
21.11 + *
21.12 + * This program is distributed in the hope that it will be useful,
21.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.15 + * GNU General Public License for more details.
21.16 + *
21.17 + * You should have received a copy of the GNU General Public License
21.18 + * along with this program. Look for COPYING file in the top folder.
21.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
21.20 + */
21.21 +package org.apidesign.bck2brwsr.htmlpage.api;
21.22 +
21.23 +/**
21.24 + *
21.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
21.26 + */
21.27 +public class Title extends Element {
21.28 + public Title(String id) {
21.29 + super(id);
21.30 + }
21.31 +
21.32 + @Override
21.33 + void dontSubclass() {
21.34 + }
21.35 +
21.36 + public final void setText(String text) {
21.37 + setAttribute(this, "innerHTML", text);
21.38 + }
21.39 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Fri Nov 09 11:47:00 2012 +0100
22.3 @@ -0,0 +1,57 @@
22.4 +/**
22.5 + * Back 2 Browser Bytecode Translator
22.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
22.7 + *
22.8 + * This program is free software: you can redistribute it and/or modify
22.9 + * it under the terms of the GNU General Public License as published by
22.10 + * the Free Software Foundation, version 2 of the License.
22.11 + *
22.12 + * This program is distributed in the hope that it will be useful,
22.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.15 + * GNU General Public License for more details.
22.16 + *
22.17 + * You should have received a copy of the GNU General Public License
22.18 + * along with this program. Look for COPYING file in the top folder.
22.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
22.20 + */
22.21 +package org.apidesign.bck2brwsr.htmlpage;
22.22 +
22.23 +import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
22.24 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
22.25 +
22.26 +/** Trivial demo for the bck2brwsr project. First of all start
22.27 + * with <a href="TestPage.html">your XHTML page</a>. Include there
22.28 + * a script that will <em>boot Java</em> in your browser.
22.29 + * <p>
22.30 + * Then use <code>@Page</code> annotation to
22.31 + * generate a Java representation of elements with IDs in that page.
22.32 + * Depending on the type of the elements, they will have different
22.33 + * methods (e.g. <code>PG_TITLE</code> has <code>setText</code>, etc.).
22.34 + * Use <code>@OnClick</code> annotation to associate behavior
22.35 + * with existing elements. Use the generated elements
22.36 + * (<code>PG_TITLE</code>, <code>PG_TEXT</code>) to modify the page.
22.37 + * <p>
22.38 + * Everything is type-safe. As soon as somebody modifies the page and
22.39 + * removes the IDs or re-assigns them to wrong elements. Java compiler
22.40 + * will emit an error.
22.41 + * <p>
22.42 + * Welcome to the type-safe HTML5 world!
22.43 + *
22.44 + * @author Jaroslav Tulach <jtulach@netbeans.org>
22.45 + */
22.46 +@Page(xhtml="TestPage.html")
22.47 +public class PageController {
22.48 + @OnClick(id="pg.button")
22.49 + static void updateTitle() {
22.50 + TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
22.51 + }
22.52 +
22.53 + @OnClick(id={ "pg.title", "pg.text" })
22.54 + static void click(String id) {
22.55 + if (!id.equals("pg.title")) {
22.56 + throw new IllegalStateException();
22.57 + }
22.58 + TestPage.PG_TITLE.setText(id);
22.59 + }
22.60 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Fri Nov 09 11:47:00 2012 +0100
23.3 @@ -0,0 +1,148 @@
23.4 +/**
23.5 + * Back 2 Browser Bytecode Translator
23.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
23.7 + *
23.8 + * This program is free software: you can redistribute it and/or modify
23.9 + * it under the terms of the GNU General Public License as published by
23.10 + * the Free Software Foundation, version 2 of the License.
23.11 + *
23.12 + * This program is distributed in the hope that it will be useful,
23.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
23.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23.15 + * GNU General Public License for more details.
23.16 + *
23.17 + * You should have received a copy of the GNU General Public License
23.18 + * along with this program. Look for COPYING file in the top folder.
23.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
23.20 + */
23.21 +package org.apidesign.bck2brwsr.htmlpage;
23.22 +
23.23 +import java.io.IOException;
23.24 +import java.io.InputStream;
23.25 +import java.lang.reflect.Method;
23.26 +import java.util.Set;
23.27 +import javax.script.Invocable;
23.28 +import javax.script.ScriptEngine;
23.29 +import javax.script.ScriptEngineManager;
23.30 +import javax.script.ScriptException;
23.31 +import org.testng.annotations.Test;
23.32 +import static org.testng.Assert.*;
23.33 +
23.34 +public class ProcessPageTest {
23.35 +
23.36 +
23.37 + @Test public void findsThreeIds() throws IOException {
23.38 + InputStream is = ProcessPageTest.class.getResourceAsStream("TestPage.html");
23.39 + assertNotNull(is, "Sample HTML page found");
23.40 + ProcessPage res = ProcessPage.readPage(is);
23.41 + final Set<String> ids = res.ids();
23.42 + assertEquals(ids.size(), 3, "Three ids found: " + ids);
23.43 +
23.44 + assertEquals(res.tagNameForId("pg.title"), "title");
23.45 + assertEquals(res.tagNameForId("pg.button"), "button");
23.46 + assertEquals(res.tagNameForId("pg.text"), "input");
23.47 + }
23.48 +
23.49 + @Test public void testCompileAndRunPageController() throws Exception {
23.50 + StringBuilder sb = new StringBuilder();
23.51 + sb.append(
23.52 + "var window = new Object();\n"
23.53 + + "var doc = new Object();\n"
23.54 + + "doc.button = new Object();\n"
23.55 + + "doc.title = new Object();\n"
23.56 + + "doc.title.innerHTML = 'nothing';\n"
23.57 + + "doc.text = new Object();\n"
23.58 + + "doc.text.value = 'something';\n"
23.59 + + "doc.getElementById = function(id) {\n"
23.60 + + " switch(id) {\n"
23.61 + + " case 'pg.button': return doc.button;\n"
23.62 + + " case 'pg.title': return doc.title;\n"
23.63 + + " case 'pg.text': return doc.text;\n"
23.64 + + " }\n"
23.65 + + " throw id;\n"
23.66 + + " }\n"
23.67 + + "\n"
23.68 + + "function clickAndCheck() {\n"
23.69 + + " doc.button.onclick();\n"
23.70 + + " return doc.title.innerHTML.toString();\n"
23.71 + + "};\n"
23.72 + + "\n"
23.73 + + "window.document = doc;\n"
23.74 + );
23.75 + Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
23.76 +
23.77 + Object ret = null;
23.78 + try {
23.79 + ret = i.invokeFunction("clickAndCheck");
23.80 + } catch (ScriptException ex) {
23.81 + fail("Execution failed in " + sb, ex);
23.82 + } catch (NoSuchMethodException ex) {
23.83 + fail("Cannot find method in " + sb, ex);
23.84 + }
23.85 + assertEquals(ret, "You want this window to be named something", "We expect that the JavaCode performs all the wiring");
23.86 + }
23.87 +
23.88 + @Test public void clickWithArgumentCalled() throws Exception {
23.89 + StringBuilder sb = new StringBuilder();
23.90 + sb.append(
23.91 + "var window = new Object();\n"
23.92 + + "var doc = new Object();\n"
23.93 + + "doc.button = new Object();\n"
23.94 + + "doc.title = new Object();\n"
23.95 + + "doc.title.innerHTML = 'nothing';\n"
23.96 + + "doc.text = new Object();\n"
23.97 + + "doc.text.value = 'something';\n"
23.98 + + "doc.getElementById = function(id) {\n"
23.99 + + " switch(id) {\n"
23.100 + + " case 'pg.button': return doc.button;\n"
23.101 + + " case 'pg.title': return doc.title;\n"
23.102 + + " case 'pg.text': return doc.text;\n"
23.103 + + " }\n"
23.104 + + " throw id;\n"
23.105 + + " }\n"
23.106 + + "\n"
23.107 + + "function clickAndCheck() {\n"
23.108 + + " doc.title.onclick();\n"
23.109 + + " return doc.title.innerHTML.toString();\n"
23.110 + + "};\n"
23.111 + + "\n"
23.112 + + "window.document = doc;\n"
23.113 + );
23.114 + Invocable i = compileClass(sb, "org/apidesign/bck2brwsr/htmlpage/PageController");
23.115 +
23.116 + Object ret = null;
23.117 + try {
23.118 + ret = i.invokeFunction("clickAndCheck");
23.119 + } catch (ScriptException ex) {
23.120 + fail("Execution failed in " + sb, ex);
23.121 + } catch (NoSuchMethodException ex) {
23.122 + fail("Cannot find method in " + sb, ex);
23.123 + }
23.124 + assertEquals(ret, "pg.title", "Title has been passed to the method argument");
23.125 + }
23.126 +
23.127 + static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
23.128 + if (sb == null) {
23.129 + sb = new StringBuilder();
23.130 + }
23.131 + try {
23.132 + Method m;
23.133 + Class<?> genJS = Class.forName("org.apidesign.vm4brwsr.GenJS");
23.134 + m = genJS.getDeclaredMethod("compile", Appendable.class, String[].class);
23.135 + m.setAccessible(true);
23.136 + m.invoke(null, sb, names);
23.137 + } catch (Exception exception) {
23.138 + throw new IOException(exception);
23.139 + }
23.140 + ScriptEngineManager sem = new ScriptEngineManager();
23.141 + ScriptEngine js = sem.getEngineByExtension("js");
23.142 + try {
23.143 + Object res = js.eval(sb.toString());
23.144 + assertTrue(js instanceof Invocable, "It is invocable object: " + res);
23.145 + return (Invocable) js;
23.146 + } catch (ScriptException ex) {
23.147 + fail("Could not compile:\n" + sb, ex);
23.148 + return null;
23.149 + }
23.150 + }
23.151 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/javaquery/api/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html Fri Nov 09 11:47:00 2012 +0100
24.3 @@ -0,0 +1,30 @@
24.4 +<?xml version="1.0" encoding="UTF-8"?>
24.5 +<!--
24.6 +
24.7 + Back 2 Browser Bytecode Translator
24.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
24.9 +
24.10 + This program is free software: you can redistribute it and/or modify
24.11 + it under the terms of the GNU General Public License as published by
24.12 + the Free Software Foundation, version 2 of the License.
24.13 +
24.14 + This program is distributed in the hope that it will be useful,
24.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
24.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.17 + GNU General Public License for more details.
24.18 +
24.19 + You should have received a copy of the GNU General Public License
24.20 + along with this program. Look for COPYING file in the top folder.
24.21 + If not, see http://opensource.org/licenses/GPL-2.0.
24.22 +
24.23 +-->
24.24 +<!DOCTYPE html>
24.25 +<html xmlns="http://www.w3.org/1999/xhtml">
24.26 + <head>
24.27 + <title id="pg.title">Default Title</title>
24.28 + </head>
24.29 + <body>
24.30 + New title: <input id="pg.text"/>
24.31 + <button id="pg.button">Change title!</button>
24.32 + </body>
24.33 +</html>
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/javaquery/pom.xml Fri Nov 09 11:47:00 2012 +0100
25.3 @@ -0,0 +1,17 @@
25.4 +<?xml version="1.0" encoding="UTF-8"?>
25.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
25.6 + <modelVersion>4.0.0</modelVersion>
25.7 + <parent>
25.8 + <artifactId>bck2brwsr</artifactId>
25.9 + <groupId>org.apidesign</groupId>
25.10 + <version>1.0-SNAPSHOT</version>
25.11 + </parent>
25.12 + <groupId>org.apidesign.bck2brwsr</groupId>
25.13 + <artifactId>javaquery</artifactId>
25.14 + <version>1.0-SNAPSHOT</version>
25.15 + <packaging>pom</packaging>
25.16 + <name>JavaQuery API and Demo</name>
25.17 + <modules>
25.18 + <module>api</module>
25.19 + </modules>
25.20 +</project>
26.1 --- a/pom.xml Fri Nov 09 09:00:46 2012 +0100
26.2 +++ b/pom.xml Fri Nov 09 11:47:00 2012 +0100
26.3 @@ -7,11 +7,11 @@
26.4 <packaging>pom</packaging>
26.5 <name>Back 2 Browser</name>
26.6 <modules>
26.7 - <module>vm</module>
26.8 - <module>htmlpage</module>
26.9 + <module>vm</module>
26.10 <module>emul</module>
26.11 <module>core</module>
26.12 <module>mojo</module>
26.13 + <module>javaquery</module>
26.14 </modules>
26.15 <licenses>
26.16 <license>