Moving the htmlpage API into a submodule in preparation of adding in an example of its usage
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 09 Nov 2012 11:47:00 +0100
changeset 140590958fcb7d7
parent 139 070fc5844295
child 141 63be794c1eeb
Moving the htmlpage API into a submodule in preparation of adding in an example of its usage
htmlpage/pom.xml
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/ProcessPage.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Button.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java
htmlpage/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java
htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java
htmlpage/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java
htmlpage/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html
javaquery/api/pom.xml
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/ProcessPage.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Button.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Input.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Page.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Title.java
javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java
javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java
javaquery/api/src/test/resources/org/apidesign/bck2brwsr/htmlpage/TestPage.html
javaquery/pom.xml
pom.xml
     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>