http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/main/java/org/netbeans/html/json/tck/KOTest.java ---------------------------------------------------------------------- diff --git a/json-tck/src/main/java/org/netbeans/html/json/tck/KOTest.java b/json-tck/src/main/java/org/netbeans/html/json/tck/KOTest.java new file mode 100644 index 0000000..9caf123 --- /dev/null +++ b/json-tck/src/main/java/org/netbeans/html/json/tck/KOTest.java @@ -0,0 +1,60 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.json.tck; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Annotates method that is part of {@link KnockoutTCK test compatibility kit} + * and should be executed in appropriate environment. The method annotated by + * this annotation will be public instance method of its class + * with no arguments. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface KOTest { +}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java ---------------------------------------------------------------------- diff --git a/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java b/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java new file mode 100644 index 0000000..6bf968a --- /dev/null +++ b/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java @@ -0,0 +1,144 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.json.tck; + +import java.net.URI; +import java.util.Map; +import net.java.html.BrwsrCtx; +import net.java.html.json.tests.ConvertTypesTest; +import net.java.html.json.tests.GCKnockoutTest; +import net.java.html.json.tests.JSONTest; +import net.java.html.json.tests.KnockoutTest; +import net.java.html.json.tests.MinesTest; +import net.java.html.json.tests.OperationsTest; +import net.java.html.json.tests.Utils; +import net.java.html.json.tests.WebSocketTest; +import org.netbeans.html.context.spi.Contexts.Builder; +import org.openide.util.lookup.ServiceProvider; +import org.testng.annotations.Factory; + +/** Entry point for providers of different HTML binding technologies (like + * Knockout.js in JavaFX's WebView). Sample usage: + * +<pre> +{@link ServiceProvider @ServiceProvider}(service = KnockoutTCK.class) +public final class MyKnockoutBindingTest extends KnockoutTCK { + {@link Override @Override} + protected BrwsrCtx createContext() { + // use {@link Builder}.{@link Builder#build() build}(); + } + + {@code @}{@link Factory} public static Object[] create() { + return VMTest.newTests().withClasses({@link KnockoutTCK#testClasses}()).build(); + } +} + * </pre> + * + * @author Jaroslav Tulach + */ +public abstract class KnockoutTCK { + protected KnockoutTCK() { + Utils.registerTCK(this); + } + + /** Implement to create new context for the test. + * Use {@link Builder} to set context for your technology up. + * @return the final context for the test + */ + public abstract BrwsrCtx createContext(); + + /** Create a JSON object as seen by the technology + * @param values mapping from names to values of properties + * @return the JSON object with filled in values + */ + public abstract Object createJSON(Map<String,Object> values); + + /** Executes script in the context of current window + * + * @param script the JavaScript code to execute + * @param arguments arguments sent to the script (can be referenced as <code>arguments[0]</code>) + * @return the output of the execution + */ + public abstract Object executeScript(String script, Object[] arguments); + + /** Creates a URL which later returns content with given + * <code>mimeType</code> and <code>content</code>. The + * content may be processed by the provided <code>parameters</code>. + * + * @param content what should be available on the URL. Can contain <code>$0</code> + * <code>$1</code> to reference <code>parameters</code> by their position + * @param mimeType the type of the resource + * @param parameters names of parameters as reference by <code>content</code> + * @return URI the test can connect to to obtain the (processed) content + */ + public abstract URI prepareURL(String content, String mimeType, String[] parameters); + + /** Gives you list of classes included in the TCK. Their test methods + * are annotated by {@link KOTest} annotation. The methods are public + * instance methods that take no arguments. + * + * @return classes with methods annotated by {@link KOTest} annotation + */ + protected static Class<?>[] testClasses() { + return new Class[] { + ConvertTypesTest.class, + JSONTest.class, + KnockoutTest.class, + MinesTest.class, + OperationsTest.class, + WebSocketTest.class, + GCKnockoutTest.class + }; + } + + /** Some implementations cannot fully support web sockets and fail. + * + * @return true, if UnsupportedOperationException reported from a web + * socket open operation is acceptable reply + */ + public boolean canFailWebSocketTest() { + return false; + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/main/resources/net/java/html/js/tests/global.js ---------------------------------------------------------------------- diff --git a/json-tck/src/main/resources/net/java/html/js/tests/global.js b/json-tck/src/main/resources/net/java/html/js/tests/global.js new file mode 100644 index 0000000..d2e81a5 --- /dev/null +++ b/json-tck/src/main/resources/net/java/html/js/tests/global.js @@ -0,0 +1,44 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +var globalString = 'HTML/Java'; + http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/main/resources/net/java/html/js/tests/global2.js ---------------------------------------------------------------------- diff --git a/json-tck/src/main/resources/net/java/html/js/tests/global2.js b/json-tck/src/main/resources/net/java/html/js/tests/global2.js new file mode 100644 index 0000000..5881c76 --- /dev/null +++ b/json-tck/src/main/resources/net/java/html/js/tests/global2.js @@ -0,0 +1,44 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +var global2String = 'NetBeans'; + http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/main/resources/org/netbeans/html/json/tck/package.html ---------------------------------------------------------------------- diff --git a/json-tck/src/main/resources/org/netbeans/html/json/tck/package.html b/json-tck/src/main/resources/org/netbeans/html/json/tck/package.html new file mode 100644 index 0000000..4e1eb4a --- /dev/null +++ b/json-tck/src/main/resources/org/netbeans/html/json/tck/package.html @@ -0,0 +1,56 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + + Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://www.netbeans.org/cddl-gplv2.html + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License file at + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the GPL Version 2 section of the License file that + accompanied this code. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + Contributor(s): + + The Original Software is NetBeans. The Initial Developer of the Original + Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 2, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 2] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 2 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 2 code and therefore, elected the GPL + Version 2 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + +--> +<!DOCTYPE html> +<html> + <head> + <title></title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + </head> + <body> + <div>Entry point to the + <a href="KnockoutTCK.html">test compatibility kit</a>. + </div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json-tck/src/test/java/net/java/html/js/tests/BodiesTest.java ---------------------------------------------------------------------- diff --git a/json-tck/src/test/java/net/java/html/js/tests/BodiesTest.java b/json-tck/src/test/java/net/java/html/js/tests/BodiesTest.java new file mode 100644 index 0000000..0223e41 --- /dev/null +++ b/json-tck/src/test/java/net/java/html/js/tests/BodiesTest.java @@ -0,0 +1,83 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.js.tests; + +import java.io.InputStream; +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class BodiesTest { + + public BodiesTest() { + } + + @Test public void annotationIsStillPresent() throws Exception { + InputStream is = Bodies.class.getResourceAsStream("Bodies.class"); + assertNotNull(is, "Class Stream found"); + + byte[] arr = new byte[is.available()]; + int len = is.read(arr); + + assertEquals(len, arr.length, "Fully read"); + + String bytes = new String(arr, "UTF-8"); + + { + int idx = bytes.indexOf("Lnet/java/html/js/JavaScriptBody"); + if (idx == -1) { + fail("Expecting JavaScriptBody reference in: " + bytes); + } + } + { + int idx = bytes.indexOf("return a + b"); + if (idx == -1) { + fail("Expecting 'return a + b' in the class file: " + bytes); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/pom.xml ---------------------------------------------------------------------- diff --git a/json/pom.xml b/json/pom.xml new file mode 100644 index 0000000..77c95f4 --- /dev/null +++ b/json/pom.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2013-2016 Oracle and/or its affiliates. All rights reserved. + + Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://www.netbeans.org/cddl-gplv2.html + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License file at + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the GPL Version 2 section of the License file that + accompanied this code. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + Contributor(s): + + The Original Software is NetBeans. The Initial Developer of the Original + Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 2, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 2] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 2 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 2 code and therefore, elected the GPL + Version 2 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + +--> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.netbeans.html</groupId> + <artifactId>pom</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + <groupId>org.netbeans.html</groupId> + <artifactId>net.java.html.json</artifactId> + <version>2.0-SNAPSHOT</version> + <packaging>bundle</packaging> + <name>JSON Model in Java</name> + <url>http://maven.apache.org</url> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <publicPackages>net.java.html.json,org.netbeans.html.json.spi</publicPackages> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>2.2.1</version> + <executions> + <execution> + <id>prepare-sources</id> + <goals> + <goal>jar</goal> + </goals> + <phase>package</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <subpackages>net.java.html.json</subpackages> + <skip>false</skip> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.netbeans.api</groupId> + <artifactId>org-openide-util-lookup</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>net.java.html</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <description>API for smooth representation of JSON objects in Java. Write your +application in Java and +present it using modern HTML rendering technologies like +Knockout. +</description> +</project> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/ComputedProperty.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/ComputedProperty.java b/json/src/main/java/net/java/html/json/ComputedProperty.java new file mode 100644 index 0000000..92917db --- /dev/null +++ b/json/src/main/java/net/java/html/json/ComputedProperty.java @@ -0,0 +1,105 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Can be used in classes annotated with {@link Model} annotation to + * define a derived property. Value of derived property is based on values + * of {@link Property} as enumerated by {@link Model#properties()}. + * <p> + * The name of the derived property is the name of the method. The arguments + * of the method must match names and types of some of the properties + * from {@link Model#properties()} list. As soon as one of these properties + * changes, the method is called to recompute its new value. + * This applies to inner changes in derived properties as well - e.g. + * if the dependant property is another type generated by {@link Model @Model} annotation - + * changes in its own properties trigger recomputation of this derived + * property as well (since version 0.9). + * <p> + * Method's return type defines the type of the derived property. It may be + * any primitive type, {@link String}, {@link Enum enum type} or a + * type generated by {@link Model @Model} annotation. One may + * also return an array by returning a list of such (boxed) type + * (for example {@link java.util.List List}<{@link String}> or {@link java.util.List List}<{@link Integer}>). + * <p> + * An example testing <a target="_blank" href="http://dew.apidesign.org/dew/#7545568"> + * whether a number is a prime</a> using a {@link ComputedProperty} is available + * on-line. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface ComputedProperty { + /** Name of a method to handle changes to the computed property. + * By default the computed properties are read-only, however one can + * make them mutable by defining a static method that takes + * two parameters: + * <ol> + * <li>the model class</li> + * <li>the value - either exactly the return the method annotated + * by this property or a superclass (like {@link Object})</li> + * </ol> + * Sample code snippet using the <b>write</b> feature of {@link ComputedProperty} + * could look like this (assuming the {@link Model model class} named + * <em>DataModel</em> has <b>int</b> property <em>value</em>): + * <pre> + * {@link ComputedProperty @ComputedProperty}(write="setPowerValue") + * <b>static int</b> powerValue(<b>int</b> value) { + * <b>return</b> value * value; + * } + * <b>static void</b> setPowerValue(DataModel m, <b>int</b> value) { + * m.setValue((<b>int</b>){@link Math}.sqrt(value)); + * } + * </pre> + * + * @return the name of a method to handle changes to the computed + * property + * @since 1.2 + */ + public String write() default ""; +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/FakeModel.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/FakeModel.java b/json/src/main/java/net/java/html/json/FakeModel.java new file mode 100644 index 0000000..468a15f --- /dev/null +++ b/json/src/main/java/net/java/html/json/FakeModel.java @@ -0,0 +1,122 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +/** + * Generated for {@link Models} + */ +final class FakeModel implements Cloneable { + private static Class<Models> modelFor() { + return Models.class; + } + private static final Html4JavaType TYPE = new Html4JavaType(); + private final org.netbeans.html.json.spi.Proto proto; + + private FakeModel(net.java.html.BrwsrCtx context) { + this.proto = TYPE.createProto(this, context); + } + + private FakeModel() { + this(net.java.html.BrwsrCtx.findDefault(FakeModel.class)); + } + + public static Object create() { + return new FakeModel(); + } + + private static class Html4JavaType extends org.netbeans.html.json.spi.Proto.Type<FakeModel> { + + private Html4JavaType() { + super(FakeModel.class, Models.class, 0, 0); + } + + @Override + public void setValue(FakeModel data, int type, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public Object getValue(FakeModel data, int type) { + throw new UnsupportedOperationException(); + } + + @Override + public void call(FakeModel model, int type, Object data, Object ev) throws Exception { + switch (type) { + } + throw new UnsupportedOperationException(); + } + + @Override + public org.netbeans.html.json.spi.Proto protoFor(Object obj) { + return ((FakeModel) obj).proto; + } + + @Override + public void onChange(FakeModel model, int type) { + throw new UnsupportedOperationException(); + } + + @Override + public void onMessage(FakeModel model, int index, int type, Object data, Object[] params) { + throw new UnsupportedOperationException(); + } + + @Override + public FakeModel read(net.java.html.BrwsrCtx c, Object json) { + return new FakeModel(c, json); + } + + @Override + public FakeModel cloneTo(FakeModel o, net.java.html.BrwsrCtx c) { + return o; + } + } + + private FakeModel(net.java.html.BrwsrCtx c, Object json) { + this(c); + Object[] ret = new Object[0]; + proto.extract(json, new String[]{}, ret); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/Function.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/Function.java b/json/src/main/java/net/java/html/json/Function.java new file mode 100644 index 0000000..9babc31 --- /dev/null +++ b/json/src/main/java/net/java/html/json/Function.java @@ -0,0 +1,122 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import java.io.PrintStream; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.netbeans.html.json.spi.FunctionBinding; + +/** Methods in class annotated by {@link Model} can be + * annotated by this annotation to signal that they should be available + * as functions to users of the model classes. The method + * should be non-private, static (unless {@link Model#instance() instance mode} is on) + * and return <code>void</code>. + * It may take few arguments. The first argument can be the type of + * the associated model class, the other argument can be of any type, + * but has to be named <code>data</code> - this one represents the + * actual data the function was invoked on. Example: + * <pre> + * + * {@link Model @Model}(className="Names", properties={ + * {@link Property @Property}(name = "selectedName", type=String.class), + * {@link Property @Property}(name = "names", type=String.class, array = true) + * }) + * static class NamesModel { + * {@link Function @Function} static void <b>nameSelected</b>(Names myModel, String data) { + * myModel.setSelectedName(data); + * } + * + * static void initialize() { + * Names pageModel = new Names("---", "Jarda", "Pepa", "Honza", "Jirka", "Tomáš"); + * pageModel.applyBindings(); + * } + * } + * + * // associated <a target="_blank" href="http://knockoutjs.com/">Knockout</a> HTML page: + * + * Selected name: <span data-bind="text: selectedName"></span> + * <ul data-bind="foreach: names"> + * <li> + * <a data-bind="text: $data, click: $root.nameSelected" href="#"></a> + * </li> + * </ul> + * </pre> + * The above example would render: + * <hr> + * Selected name: <span>---</span> + * <ul> + * <li>Jarda</li> + * <li>Pepa</li> + * <li>Honza</li> + * <li>Jirka</li> + * <li>Tomáš</li> + * </ul> + * <hr> + * and after clicking on one of the names the <code>---</code> would be replaced + * by selected name. + * Try <a target="_blank" href="http://dew.apidesign.org/dew/#8848505">this sample on-line</a>! + * <p> + * There can be additional arguments in the method which can extract information + * from (typically event object) sent as a second parameter of the function + * {@link FunctionBinding#call(java.lang.Object, java.lang.Object) dispatch method}. + * Such arguments can be of primitive types (<code>int</code>, <code>double</code> + * or {@link String}). Their names are used to extract values of appropriate + * properties from the event object. The following function... + * <pre> + * {@link Function @Function} static void <b>meaningOfWorld</b>(Names myModel, String data, int answer) { + * {@link System}.out.{@link PrintStream#println(int) println}(answer); + * } + * // would print <b>42</b> if the dispatch method: + * {@link FunctionBinding#call(java.lang.Object, java.lang.Object) meaningOfWorld.call}(model, json) + * </pre> + * is called with equivalent of <code>var json = { 'answer' : 42 }</code>. + * + * @author Jaroslav Tulach + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface Function { +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/Model.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/Model.java b/json/src/main/java/net/java/html/json/Model.java new file mode 100644 index 0000000..7d467ab --- /dev/null +++ b/json/src/main/java/net/java/html/json/Model.java @@ -0,0 +1,356 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.net.URL; +import java.util.List; + +/** Defines a model class that represents a single + * <a target="_blank" href="http://en.wikipedia.org/wiki/JSON">JSON</a>-like object + * named {@link #className()}. The generated class contains + * getters and setters for properties defined via {@link #properties()} and + * getters for other, derived properties defined by annotating methods + * of this class by {@link ComputedProperty}. Each property + * can be of primitive type, an {@link Enum enum type} or (in order to create + * nested <a target="_blank" href="http://en.wikipedia.org/wiki/JSON">JSON</a> structure) + * of another {@link Model class generated by @Model} annotation. Each property + * can either represent a single value or be an array of its values. + * <p> + * The {@link #className() generated class}'s <code>toString</code> method + * converts the state of the object into + * <a target="_blank" href="http://en.wikipedia.org/wiki/JSON">JSON</a> format. One can + * use {@link Models#parse(net.java.html.BrwsrCtx, java.lang.Class, java.io.InputStream)} + * method to read the JSON text stored in a file or other stream back into the Java model. + * One can also use {@link OnReceive @OnReceive} annotation to read the model + * asynchronously from a {@link URL}. + * <p> + * An example where one defines class <code>Person</code> with four + * properties (<code>firstName</code>, <code>lastName</code>, array of <code>addresses</code> and + * <code>fullName</code>) follows: + * <pre> + * {@link Model @Model}(className="Person", properties={ + * {@link Property @Property}(name = "firstName", type=String.<b>class</b>), + * {@link Property @Property}(name = "lastName", type=String.<b>class</b>) + * {@link Property @Property}(name = "addresses", type=Address.<b>class</b>, array = <b>true</b>) + * }) + * <b>static class</b> PersonModel { + * {@link ComputedProperty @ComputedProperty} + * <b>static</b> String fullName(String firstName, String lastName) { + * <b>return</b> firstName + " " + lastName; + * } + * + * {@link ComputedProperty @ComputedProperty} + * <b>static</b> String mainAddress({@link List List<Address>} addresses) { + * <b>for</b> (Address a : addresses) { + * <b>return</b> a.getStreet() + " " + a.getTown(); + * } + * <b>return</b> "No address"; + * } + * + * {@link Model @Model}(className="Address", properties={ + * {@link Property @Property}(name = "street", type=String.<b>class</b>), + * {@link Property @Property}(name = "town", type=String.<b>class</b>) + * }) + * <b>static class</b> AddressModel { + * } + * } + * </pre> + * The generated model class has a default constructor, and also <em>quick + * instantiation</em> constructor that accepts all non-array properties + * (in the order used in the {@link #properties()} attribute) and vararg list + * for the first array property (if any). One can thus use following code + * to create an instance of the Person and Address classes: + * <pre> + * Person p = <b>new</b> Person("Jaroslav", "Tulach", + * <b>new</b> Address("MarkouÅ¡ovice", "Ãpice"), + * <b>new</b> Address("V Parku", "Praha") + * ); + * // p.toString() then returns equivalent of following <a target="_blank" href="http://en.wikipedia.org/wiki/JSON">JSON</a> object + * { + * "firstName" : "Jaroslav", + * "lastName" : "Tulach", + * "addresses" : [ + * { "street" : "MarkouÅ¡ovice", "town" : "Ãpice" }, + * { "street" : "V Parku", "town" : "Praha" }, + * ] + * } + * </pre> + * <p> + * In case you are using <a target="_blank" href="http://knockoutjs.com/">Knockout technology</a> + * for Java then you can associate such model object with surrounding HTML page by + * calling: <code>p.applyBindings();</code> (in case you specify {@link #targetId()}. + * The page can then use regular + * <a target="_blank" href="http://knockoutjs.com/">Knockout</a> bindings to reference your + * model and create dynamic connection between your model in Java and + * live DOM structure in the browser: + * </p> + * <pre> + * Name: <span data-bind="text: fullName"> + * <div data-bind="foreach: addresses"> + * Lives in <span data-bind="text: town"/> + * </div> + * </pre> + * + * <h3>Access Raw <a target="_blank" href="http://knockoutjs.com/">Knockout</a> Observables</h3> + * + * One can obtain <em>raw</em> JavaScript object representing the + * instance of {@link Model model class} (with appropriate + * <a target="_blank" href="http://knockoutjs.com/">Knockout</a> <b>observable</b> properties) + * by calling {@link Models#toRaw(java.lang.Object) Models.toRaw(p)}. For + * example here is a way to obtain the value of <code>fullName</code> property + * (inefficient as it switches between Java and JavaScript back and forth, + * but functional and instructive) via a JavaScript call: + * <pre> + * {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(args = "raw", javacall = true, body = + * "return raw.fullName();" // yes, the <a target="_blank" href="http://knockoutjs.com/">Knockout</a> property is a function + * ) + * static native String jsFullName(Object raw); + * // and later + * Person p = ...; + * String fullName = jsFullName({@link Models#toRaw(java.lang.Object) Models.toRaw(p)}); + * </pre> + * The above shows how to read a value from <a target="_blank" href="http://knockoutjs.com/">Knockout</a> + * observable. There is a way to change the value too: + * One can pass a parameter to the property-function and then + * it acts like a setter (of course not in the case of read only <code>fullName</code> property, + * but for <code>firstName</code> or <code>lastName</code> the setter is + * available). Everything mentioned in this paragraph applies only when + * <a target="_blank" href="http://knockoutjs.com/">Knockout</a> technology is active + * other technologies may behave differently. + * + * <h4>Copy to Plain JSON</h4> + * There is a way to pass a value of a Java {@link Model model class} instance + * by copy and convert + * the {@link Model the whole object} into plain + * <a target="_blank" href="http://en.wikipedia.org/wiki/JSON">JSON</a>. Just + * print it as a string and parse it in JavaScript: + * <pre> + * {@link net.java.html.js.JavaScriptBody @JavaScriptBody}(args = { "txt" }, body = + * "return JSON.parse(txt);" + * ) + * private static native Object parseJSON(String txt); + * + * public static Object toPlainJSON(Object model) { + * return parseJSON(model.toString()); + * } + * </pre> + * The newly returned instance is a one time copy of the original model and is no longer + * connected to it. The copy based behavior is independent on any + * particular technology and should work + * in <a target="_blank" href="http://knockoutjs.com/">Knockout</a> as well as other + * technology implementations. + * + * <h4>References</h4> + * + * Visit an <a target="_blank" href="http://dew.apidesign.org/dew/#7510833">on-line demo</a> + * to see a histogram driven by the {@link Model} annotation or try + * a little <a target="_blank" href="http://dew.apidesign.org/dew/#7263102">math test</a>. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Model { + /** Name of the model class. + * @return valid Java identifier to use as a name of the model class + */ + String className(); + /** List of properties in the model. + * @return array of property definitions + */ + Property[] properties(); + + /** The id of an element to bind this model too. If this + * property is specified an <code>applyBindings</code> method + * in the model class is going to be generated which later calls + * {@link Models#applyBindings(java.lang.Object, java.lang.String)} + * with appropriate <code>targetId</code>. If the <code>targetId</code> + * is specified as empty string, <code>null</code> value is passed + * to {@link Models#applyBindings(java.lang.Object, java.lang.String)} method. + * If the <code>targetId</code> is not specified at all, no public + * <code>applyBindings</code> method is generated at all (a change compared + * to previous versions of this API). + * + * @return an empty string (means apply globally), or ID of a (usually DOM) + * element to apply this model after calling its generated + * <code>applyBindings()</code> method to + * @since 1.1 + */ + String targetId() default ""; + + /** Controls whether builder-like setters shall be generated. Once this + * attribute is set, all {@link #properties()} will get a builder like + * setter (takes value of the property and returns <code>this</code> + * so invocations can be chained). When this attribute is specified, + * the non-default constructor isn't generated at all. + * <p> + * Specifying <code>builder="assign"</code> + * and having {@link #properties() properties} <code>name</code> and + * <code>age</code> will generate method: <pre> + * <b>public</b> MyModel assignName(String name) { ... } + * <b>public</b> MyModel assignAge(int age) { ... } + * </pre> + * These methods can then be chained as <pre> + * MyModel m = <b>new</b> MyModel().assignName("name").assignAge(3); + * </pre> + * The <code>builder</code> attribute can be set to empty string <code>""</code> - + * then it is possible that some property names clash with Java keywords. + * It's responsibility of the user to specify valid builder prefix, + * so the generated methods are compilable. + * + * @return the prefix to put before {@link Property property} names when + * generating their builder methods + * @since 1.3 + */ + String builder() default ""; + + /** Controls keeping of per-instance private state. Sometimes + * the class generated by the {@link Model @Model annotation} needs to + * keep non-public, or non-JSON like state. One can achieve that by + * specifying <code>instance=true</code> when using the annotation. Then + * the generated class gets a pointer to the instance of the annotated + * class (there needs to be default constructor) and all the {@link ModelOperation @ModelOperation}, + * {@link Function @Function}, {@link OnPropertyChange @OnPropertyChange} + * and {@link OnReceive @OnReceive} methods may be non-static. The + * instance of the implementation class isn't accessible directly, just + * through calls to above defined (non-static) methods. Example: + * <pre> + * {@link Model @Model}(className="Data", instance=<b>true</b>, properties={ + * {@link Property @Property}(name="message", type=String.<b>class</b>) + * }) + * <b>final class</b> DataPrivate { + * <b>private int</b> count; + * + * {@link ModelOperation @ModelOperation} <b>void</b> increment(Data model) { + * count++; + * } + * + * {@link ModelOperation @ModelOperation} <b>void</b> hello(Data model) { + * model.setMessage("Hello " + count + " times!"); + * } + * } + * Data data = <b>new</b> Data(); + * data.increment(); + * data.increment(); + * data.increment(); + * data.hello(); + * <b>assert</b> data.getMessage().equals("Hello 3 times!"); + * </pre> + * <p> + * The methods annotated by {@link ComputedProperty} need to remain static, as + * they are supposed to be <em>pure</em> functions (e.g. depend only on their parameters) + * and shouldn't use any internal state. + * </p> + * <p><b>How do I initialize private values?</b> + * The implementation class (the one annotated by {@link Model @Model} annotation) + * needs to have accessible default constructor. That constructor is used to + * create the instance. Obviously such constructor does not have + * any parameters, so no initialization is possible. + * </p> + * <p> + * Later one can, however, call any {@link ModelOperation @ModelOperation} + * method and pass in additional configuration parameters. In the above + * example it should be possible add + * </p> + * <pre> + * {@link ModelOperation @ModelOperation} <b>void</b> init(Data model, int count) { + * <b>this</b>.count = count; + * } + * </pre><p> + * and then one can initialize the model using the <code>init</code> as: + * </p> + * <pre> + * Data data = <b>new</b> Data(); + * data.init(2); + * data.increment(); + * data.hello(); + * <b>assert</b> data.getMessage().equals("Hello 3 times!"); + * </pre><p> + * Why there has to be default constructor? Because instances of + * classes generated by {@link Model @Model annotation} may be constructed + * by the system as + * {@link Models#fromRaw(net.java.html.BrwsrCtx, java.lang.Class, java.lang.Object) wrappers around existing JavaScript objects} + * - then + * there is nobody to provide additional parameters at construction time. + * </p> + * <p><b>How do I read private values?</b> + * The methods annotated by {@link ModelOperation} must return <code>void</code> + * (as they can run asynchronously) and as such they aren't suitable for + * returning values back to the caller. In case something like that is + * needed, one can use the approach of the <code>hello</code> method - e.g. + * set value of some {@link Property property} that has a getter: + * </p> + * <pre> + * data.hello(); + * <b>assert</b> data.getMessage().equals("Hello 3 times!"); + * </pre><p> + * Or one can use actor-like callbacks. Define callback interface and + * use it in a {@link ModelOperation @ModelOperation} method: + * </p> + * <pre> + * <b>public interface</b> ReadCount { + * <b>public void</b> notifyCount(int count); + * } + * {@link ModelOperation @ModelOperation} <b>void</b> readCount(Data model, ReadCount callback) { + * callback.readCount(<b>this</b>.count); + * } + * Data data = <b>new</b> Data(); + * data.init(2); + * data.increment(); + * data.readCount(count -> System.out.println("count should be 3: " + count)); + * </pre><p> + * The provided lambda-function callback may be invoked immediately + * or asynchronously as documentation for {@link ModelOperation} + * annotation describes. + * </p> + * + * @return <code>true</code> if the model class should keep pointer to + * instance of the implementation class + * @since 1.3 + */ + boolean instance() default false; +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/ModelOperation.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/ModelOperation.java b/json/src/main/java/net/java/html/json/ModelOperation.java new file mode 100644 index 0000000..5f8ea12 --- /dev/null +++ b/json/src/main/java/net/java/html/json/ModelOperation.java @@ -0,0 +1,100 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** The threading model of classes generated by {@link Model @Model} requires + * that all operations are perform from the originating thread - unless they + * are invoked as {@link ModelOperation @ModelOperation} methods. + * <p> + * A method in a class annotated by {@link Model @Model} annotation may be + * annotated by {@link ModelOperation @ModelOperation}. The method has + * to be static (unless {@link Model#instance() instance mode} is on), + * non-private and return <code>void</code>. The first parameter + * of the method must be the {@link Model#className() model class} followed + * by any number of additional arguments. + * <p> + * As a result method of the same name and the same list of additional arguments + * (e.g. without the first model class one) will be generated into the + * {@link Model#className() model class}. This method can be invoked on any + * thread, any time and it is the responsibility of model manipulating + * technology to ensure the model is available and only then call back to + * the original method annotated by {@link ModelOperation @ModelOperation}. + * The call may happen synchronously (if possible), or be delayed and invoked + * later (on appropriate dispatch thread), without blocking the caller. + * <pre> + * + * {@link Model @Model}(className="Names", properties={ + * {@link Property @Property}(name = "names", type=String.class, array = true) + * }) + * static class NamesModel { + * {@link ModelOperation @ModelOperation} static void <b>updateNames</b>(Names model, {@link java.util.List}<String;gt; arr) { + * <em>// can safely access the model</em> + * model.getNames().addAll(arr); + * } + * + * static void initialize() { + * final Names pageModel = new Names(); + * pageModel.applyBindings(); + * + * <em>// spawn to different thread</em> + * {@link java.util.concurrent.Executors}.newSingleThreadExecutor().execute({ + * List<String> arr = <em>// ... obtain the names somewhere from network</em> + * pageModel.<b>updateNames</b>(arr); + * // returns immediately, later it invokes the model operation + * }); + * + * } + * } + * </pre> + * + * @author Jaroslav Tulach + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface ModelOperation { +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/Models.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/Models.java b/json/src/main/java/net/java/html/json/Models.java new file mode 100644 index 0000000..71dbb39 --- /dev/null +++ b/json/src/main/java/net/java/html/json/Models.java @@ -0,0 +1,191 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import net.java.html.BrwsrCtx; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import org.netbeans.html.json.impl.JSON; +import org.netbeans.html.json.spi.Technology; + +/** Information about and + * operations for classes generated by the {@link Model @Model} + * annotation. + * + * @author Jaroslav Tulach + */ +public final class Models { + private Models() { + } + + /** Finds out whether given class is a model class - e.g. has been + * generated by {@link Model @Model} annotation. + * + * @param clazz the class to test + * @return true, if <code>clazz</code> was generated by {@link Model} annotation + * @since 0.2 + */ + public static boolean isModel(Class<?> clazz) { + return JSON.isModel(clazz); + } + + /** Binds given model to another context. + * + * @param <Model> class defined by {@link net.java.html.json.Model} annotation + * @param model instance of a model defined by {@link net.java.html.json.Model} annotation + * @param context context to which the model should be bound + * @return new instance of model bound to new <code>context</code> + * @throws IllegalArgumentException in case the instance is not generated by model interface + * @since 0.4 + */ + public static <Model> Model bind(Model model, BrwsrCtx context) { + return JSON.bindTo(model, context); + } + + /** Generic method to parse content of a model class from a stream. + * + * @param <M> type of the <code>model</code> class + * @param c context of the technology to use for reading + * @param model the model class generated by {@link Model} annotation + * @param is input stream with data + * @return new instance of the model class + * @throws java.io.IOException throw when reading from <code>is</code> faces problems + * @since 0.2 + */ + public static <M> M parse(BrwsrCtx c, Class<M> model, InputStream is) throws IOException { + return JSON.readStream(c, model, is, null); + } + + /** Generic method to parse stream, that can possibly contain array + * of specified objects. + * + * @param <M> the type of the individal JSON object + * @param c context of the technology to use for reading + * @param model the model class generated by {@link Model} annotation + * @param is input stream with data + * @param collectTo collection to add the individual model instances to. + * If the stream contains an object, one instance will be added, if + * it contains an array, the number of array items will be added to + * the collection + * @throws IOException thrown when an I/O problem appears + * @since 0.8.3 + */ + public static <M> void parse( + BrwsrCtx c, Class<M> model, + InputStream is, Collection<? super M> collectTo + ) throws IOException { + collectTo.getClass(); + JSON.readStream(c, model, is, collectTo); + } + + /** Converts an existing, raw, JSON object into a {@link Model model class}. + * + * @param <M> the type of the model class + * @param ctx context of the technology to use for converting + * @param model the model class + * @param jsonObject original instance of the JSON object + * @return new instance of the model class + * @since 0.7 + */ + public static <M> M fromRaw(BrwsrCtx ctx, Class<M> model, Object jsonObject) { + M value = JSON.read(ctx, model, jsonObject); + JSON.readBindings(ctx, value, jsonObject); + return value; + } + + /** Converts an existing {@link Model model} into its associated, raw + * JSON object. The object may, but does not have to, be the same instance + * as the model object. + * + * @param model the model object + * (can be <code>null</code> to initialize the associated {@link Technology}) + * @return the raw JSON object associated with the model + * (<code>null</code> if the <code>model</code> parameter was null) + * @throws IllegalArgumentException if the <code>model</code> is + * not instance of a class + * generated by {@link Model model annotation} processor. + * @since 0.7 + */ + public static Object toRaw(Object model) { + if (model == null) { + toRaw(FakeModel.create()); + return null; + } + final Class<? extends Object> type = model.getClass(); + if (!isModel(type)) { + throw new IllegalStateException("Not a model " + type); + } + return JSON.find(model); + } + + /** Apply bindings of a model class to overall page. In <em>ko4j</em> mode, + * it binds the model values to the currently active page. + * + * @param model instance of a {@link Model class} + * @throws IllegalArgumentException if the <code>model</code> is not + * instance of a class generated by {@link Model model annotation} + * processor. + * + * @since 0.7 + */ + public static void applyBindings(Object model) { + JSON.applyBindings(model, null); + } + + + /** Apply bindings of a model class. In <em>ko4j</em> mode, + * it binds the model values to an element on currently active page. + * + * @param model instance of a {@link Model class} + * @param targetId the id of the element to apply the binding to + * @throws IllegalArgumentException if the <code>model</code> is not + * instance of a class generated by {@link Model model annotation} + * processor. + * + * @since 1.1 + */ + public static void applyBindings(Object model, String targetId) { + JSON.applyBindings(model, targetId); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/json/src/main/java/net/java/html/json/OnPropertyChange.java ---------------------------------------------------------------------- diff --git a/json/src/main/java/net/java/html/json/OnPropertyChange.java b/json/src/main/java/net/java/html/json/OnPropertyChange.java new file mode 100644 index 0000000..a5eded0 --- /dev/null +++ b/json/src/main/java/net/java/html/json/OnPropertyChange.java @@ -0,0 +1,100 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.json; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks a method that is going to be notified when a + * property defined by {@link Model} has been changed. This is + * especially useful when one wants to react to changes in the + * model caused by the rendered view. In case of + * <a href="http://knockoutjs.com">knockout.js</a> technology + * one could for example react to selection of a name from a combo + * box: + * <pre> + * + * <!-- associates the selected value with property <em>name</em> --> + * + * <select data-bind="value: name"> + * <option>JiÅÃ</option> + * <option>Jarda</option> + * <option>Petr</option> + * <option>Tomáš</option> + * </select> + * + * // Java code snippet reacting to change of the <em>name</em> property: + * + * {@link OnPropertyChange @OnPropertyChange}("name") + * <b>static void</b> propertyChanged(AModel inst, {@link String} propertyName) { + * // schedule some operation + * // on the model + * } + * </pre> + * The method's first argument should be the instance of the + * associated {@link Model model class}. The method shall be non-private + * and unless {@link Model#instance() instance mode} is on also static. + * There can be an optional second {@link String} argument which will be set + * to the name of the changed property. The second argument is only useful when + * a single method reacts to changes in multiple properties. + * <p> + * An online example using this technique is + * <a target="_blank" href="http://dew.apidesign.org/dew/#7138581">available here</a> - + * it observes selection in a combo box and in case it changes + * the example sends a network + * request and {@link net.java.html.json.OnReceive asynchronously updates} + * list of code snippets. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface OnPropertyChange { + /** Name(s) of the properties. One wishes to observe. + * + * @return valid java identifier + */ + String[] value(); +}
