├── .gitignore
├── LICENSE.txt
├── README.md
├── README.txt
├── core
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── timepedia
│ │ └── exporter
│ │ ├── Exporter.gwt.xml
│ │ ├── client
│ │ ├── Export.java
│ │ ├── ExportAfterCreateMethod.java
│ │ ├── ExportClosure.java
│ │ ├── ExportConstructor.java
│ │ ├── ExportInstanceMethod.java
│ │ ├── ExportJsInitMethod.java
│ │ ├── ExportOverlay.java
│ │ ├── ExportPackage.java
│ │ ├── ExportStaticMethod.java
│ │ ├── Exportable.java
│ │ ├── Exporter.java
│ │ ├── ExporterBaseActual.java
│ │ ├── ExporterBaseImpl.java
│ │ ├── ExporterUtil.java
│ │ ├── Getter.java
│ │ ├── NoExport.java
│ │ ├── SOptional.java
│ │ ├── SType.java
│ │ ├── Setter.java
│ │ ├── StructuralType.java
│ │ └── test
│ │ │ └── JsTestUtil.java
│ │ ├── doclet
│ │ └── JsDoclet.java
│ │ └── rebind
│ │ ├── ClassExporter.java
│ │ ├── DispatchTable.java
│ │ ├── ExportableTypeOracle.java
│ │ ├── ExporterGenerator.java
│ │ ├── ExporterGeneratorNoExport.java
│ │ ├── JExportOverlayClassType.java
│ │ ├── JExportable.java
│ │ ├── JExportableArrayType.java
│ │ ├── JExportableClassType.java
│ │ ├── JExportableConstructor.java
│ │ ├── JExportableField.java
│ │ ├── JExportableMethod.java
│ │ ├── JExportableParameter.java
│ │ ├── JExportablePrimitiveType.java
│ │ ├── JExportableType.java
│ │ ├── JStructuralTypeField.java
│ │ └── Property.java
│ └── test
│ └── java
│ └── org
│ └── timepedia
│ └── exporter
│ ├── Test.gwt.xml
│ └── test
│ ├── CoreTestGwt.java
│ ├── ExporterGwtSuiteTest.java
│ └── issues
│ ├── Issue25aTestGwt.java
│ ├── Issue25bTestGwt.java
│ ├── Issue33TestGwt.java
│ ├── Issue34TestGwt.java
│ ├── Issue35TestGwt.java
│ ├── Issue38TestGwt.java
│ ├── Issue44TestGwt.java
│ ├── Issue45TestGwt.java
│ ├── Issue48TestGwt.java
│ ├── Issue49TestGwt.java
│ ├── Issue50TestGwt.java
│ ├── Issue51TestGwt.java
│ └── MyExportable.java
└── samples
├── export-widgets
├── README.txt
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── gquery
│ │ └── ewidget
│ │ ├── ExportWidget.gwt.xml
│ │ ├── client
│ │ └── ExportWidget.java
│ │ └── public
│ │ └── ExportWidget.html
│ └── webapp
│ ├── WEB-INF
│ └── web.xml
│ └── index.html
├── exporterdemo
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── exporterdemo
│ │ ├── ExporterDemo.gwt.xml
│ │ ├── client
│ │ ├── Employee.java
│ │ ├── ExportManager.java
│ │ ├── ExporterDemo.java
│ │ ├── Manager.java
│ │ ├── MyClickListener.java
│ │ └── Person.java
│ │ └── public
│ │ └── ExporterDemo.html
│ └── webapp
│ ├── WEB-INF
│ └── web.xml
│ └── index.html
└── testdemo
├── pom.xml
└── src
└── main
├── java
└── testdemo
│ ├── TestDemo.gwt.xml
│ ├── client
│ └── TestDemo.java
│ └── public
│ └── TestDemo.html
└── webapp
├── WEB-INF
└── web.xml
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | gwt-unitCache
3 | war
4 | *~
5 | .settings
6 | .project
7 | .classpath
8 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2007 Timepedia.org
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing,
10 | software distributed under the License is distributed on
11 | an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
12 | either express or implied. See the License for the specific
13 | language governing permissions and limitations under the License.
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What is gwt-exporter? #
2 | The project is a GWT module which contains a generator capable of taking GWT classes and exporting them as ordinary Javascript APIs callable from hand-written Javascript, without having to deal with JSNI, and suitable for use in mashups.
3 |
4 | Develop an application or library in GWT and use gwtexporter annotations to make classes and methods available from javascript.
5 |
6 | The project includes a class to generate the Api documentation of the exported javascript.
7 |
8 | # Documentation #
9 | Take a look to the [Getting Started Guide](../../wiki/GettingStarted) to learn how to use it.
10 |
11 | [Here](#articles-and-posts) you have are a set of useful links you can read as well.
12 |
13 |
14 | # gwt-exporter in action #
15 | * In your java code modify your classes to implement the `Exportable` interface, and add some extra annotations
16 | ```
17 | package com.example;
18 |
19 | @Export() /* [1] */
20 | public class Person implements /* [2] */ Exportable {
21 | private String name;
22 | public Person(String name) {
23 | this.name = name;
24 | }
25 | public String execute(String key, long[] values) {
26 | return key + " : " + values.length;
27 | }
28 | public String foo(Foo foo) {
29 | return foo.foo();
30 | }
31 | }
32 |
33 | public class Foo implements /* [3] */ Exportable {
34 | public String bar() {
35 | return "bar,";
36 | }
37 | }
38 |
39 | // [1] Export this class and all its public methods.
40 | // [2] [3] Mark classes as exportable: use the gwt-exporter generator.
41 | // [3] because this class is not annotated with @Export, it will be exported
42 | // only in the case it was used in a exported method.
43 | ```
44 |
45 | * In your `onModuleLoad` you have to say to the compiler which classes to export
46 | ```
47 | public void onModuleLoad() {
48 | GWT.exportAll(); // Export all Exportable classes, otherwise use GWT.create per class.
49 | }
50 | ```
51 | * **IMPORTANT:** The exported stuff will not be available in JS until your GWT app is fully loaded.
52 | * In compile time, gwt-exporter will decorate your classes with the necessary jsni code so as they are callable from javascript:
53 | ```
54 |
55 | var person = new com.example.Person('manolo')
56 | var foo = new com.example.Person.Foo()
57 | foo.bar();
58 | person.foo(foo)
59 | person.execute('baz', [1,2,3])
60 |
61 | ```
62 |
63 | * Additionally gwt-exporter's plenty of features to make your js api look better
64 | ```
65 |
66 | @ExportPackage("pkg") // Change the js namespace from "com.example" to "pkg"
67 | @Export("person") // Change the class name from "Person" to "person"
68 | public class Person implements Exportable {
69 | [...]
70 | @Export("baz") // Rename methods
71 | public String execute(String key, long[] values) {
72 | [...]
73 | }
74 |
75 | public String run(Order callback) { // Run js functions
76 | callback.success("ok");
77 | }
78 | }
79 |
80 | @ExportClosure // Convert js functions to java objects
81 | public interface Order implements Exportable {
82 | void success(String msg);
83 | }
84 |
85 | ```
86 | ```
87 |
88 | var person = new pkg.person('manolo')
89 | person.baz('baz', [1,2,3])
90 | person.run(function(msg){
91 | alert('msg')
92 | });
93 |
94 | ```
95 | # Articles and posts #
96 |
97 | Here you have a set of articles, tutorials and links related with GwtExporter:
98 |
99 | * The [Getting started guide](../../wiki/GettingStarted) is the official documentation of the library.
100 | * [English](../../wiki/Exporting-GWT-to-JS) and [Spanish](../../wiki/Exportando-GWT-a-JS) tutorials.
101 | * [jsQuery](http://code.google.com/p/gwtquery/wiki/JsQuery) is a clone of jquery written in gwt and exported with Gwt. You can take a look to [this presentation](http://www.slideshare.net/dodotis/gquery-a-jquery-clone-for-gwt-rivieradev-2011) to get more information.
102 | * A list of some posts about gwtexporter in Ray's blog.
103 | * [Announcemen of a doclet class able to generate js-api documentation using javadoc comments](http://timepedia.blogspot.com/2009/01/gwt-exporter-now-generates-javascript.html)
104 | * [Ray's thoughts about the future of gwt exporter in March,2003](http://timepedia.blogspot.com/2009/03/whats-next-for-gwt-exporter.html)
105 | * [New features in 2.05](http://timepedia.blogspot.com/2009/03/gwt-exporter-205-released.html)
106 | * [Bug in 2.05](http://timepedia.blogspot.com/2009/04/small-update-to-gwt-exporter.html)
107 | * [New features in 2.09](http://timepedia.blogspot.com/2009/12/gwt-exporter-209-released.html)
108 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 |
2 | This is the GWT Exporter module courtesy of Timepedia.org. This module
3 | allows you to expose GWT classes, methods, and fields as Javascript
4 | objects and takes care of marshalling GWT objects back and forth
5 | between the Javascript interface and the GWT interface.
6 |
7 | Feel free to use, modify, and redistribute this code according to the
8 | provisions of the Apache License 2.0.
9 |
10 | If you want to contribute, feel free to submit issues to the issue
11 | tracker on http://code.google.com/gwt-exporter or submit patches.
12 | You can email to the mailing list gwt-exporter@googlecode.com as well.
13 |
14 | Build files are in maven central repositories, or in the download
15 | section of the web site.
16 |
17 | There is some good wiki pages and articles in the web site and you
18 | can take a look to our test cases to learn usage.
19 |
20 | You can also read the Timepedia blog, http://timepedia.blogspot.com
21 | for a discussion of how everything works.
22 |
23 | -Ray Cromwell
24 |
25 |
--------------------------------------------------------------------------------
/core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | org.timepedia.exporter
4 | gwtexporter
5 | jar
6 | 2.6.0-SNAPSHOT
7 | GWT Javascript API Exporter
8 | http://timepedia.org
9 |
10 |
11 | org.sonatype.oss
12 | oss-parent
13 | 7
14 |
15 |
16 |
17 | UTF-8
18 | 2.5.1-rc1
19 |
20 |
21 |
22 | junit
23 | junit
24 | 3.8.1
25 | test
26 |
27 |
28 | com.google.gwt
29 | gwt-user
30 | ${gwtversion}
31 | provided
32 |
33 |
34 | com.google.gwt
35 | gwt-dev
36 | ${gwtversion}
37 | provided
38 |
39 |
40 | com.sun
41 | tools
42 | 1.6
43 | system
44 | true
45 | ${java.home}/../lib/tools.jar
46 |
47 |
48 |
49 |
50 |
51 |
52 | ${basedir}/src/main/java
53 |
54 |
55 | ${basedir}/src/main/resources
56 |
57 |
58 |
59 |
60 | org.apache.maven.plugins
61 | maven-source-plugin
62 |
63 |
64 | package
65 |
66 | jar
67 |
68 |
69 |
70 |
71 |
72 | org.apache.maven.plugins
73 | maven-compiler-plugin
74 |
75 | 1.6
76 | 1.6
77 |
78 |
79 |
80 | org.apache.maven.plugins
81 | maven-surefire-plugin
82 |
83 |
84 | ${basedir}/src/main/java
85 | ${basedir}/src/test/java
86 |
87 |
88 |
89 | false
90 |
91 | -runStyle HtmlUnit:FF3,IE6
92 |
93 |
94 |
95 |
96 | org.apache.maven.plugins
97 | maven-gpg-plugin
98 |
99 |
100 | sign-artifacts
101 | verify
102 |
103 | sign
104 |
105 |
106 |
107 |
108 |
109 | org.apache.maven.plugins
110 | maven-javadoc-plugin
111 |
112 |
113 | javadoc
114 | package
115 |
116 | jar
117 |
118 |
119 |
120 |
121 |
122 | org.apache.maven.plugins
123 | maven-release-plugin
124 | 2.3.2
125 |
126 |
127 | default
128 |
129 | perform
130 |
131 |
132 | core/pom.xml
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | maven2-repository.dev.java.net
143 | Java.net Repository for Maven
144 | http://download.java.net/maven/2/
145 |
146 |
147 | timefire
148 | http://timefire-repository.googlecode.com/svn/mavenrepo/
149 |
150 |
151 |
152 |
153 | scm:git:https://code.google.com/p/gwt-exporter/
154 | scm:git:git@github.com:manolo/gwt-exporter.git
155 | http://code.google.com/p/gwt-exporter/source/browse/
156 | gwtexporter-2.6.1
157 |
158 |
159 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/Exporter.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/Export.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marks a method, field, constructor, or class as exportable and allows
10 | * its Javascript name to be overriden.
11 | *
12 | * When a class is marked, all public methods will be exported unless them
13 | * are marked with NoExport
14 | */
15 | @Target(
16 | {ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.TYPE})
17 | @Retention(RetentionPolicy.RUNTIME)
18 | public @interface Export {
19 |
20 | String value() default "";
21 |
22 | boolean all() default false;
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportAfterCreateMethod.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Mark a static method in a class so as it will run after the class
10 | * has been created.
11 | * It is run just once and it is useful to redefine name-spaces or
12 | * whatever we needed to do after the class has been exported.
13 | */
14 | @Target({ElementType.METHOD})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface ExportAfterCreateMethod {
17 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportClosure.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Indicates that an interface allows JS functions to be automatically promoted
10 | * to its type when it appears as an argument to an exported function.
11 | * For example:
12 | *
13 | @Export
14 | @ExportPackage("jsc")
15 | @ExportClosure
16 | public interface JsClosure extends Exportable {
17 | public void execute(String par1, String par2);
18 | }
19 |
20 | @Export
21 | @ExportPackage("jsc")
22 | public class MyClass implements Exportable {
23 | public executeJsClosure(JsClosure closure){
24 | closure.execute("Hello", "Friend");
25 | }
26 | }
27 | *
28 | */
29 |
30 |
31 | @Target(ElementType.TYPE)
32 | @Retention(RetentionPolicy.RUNTIME)
33 | public @interface ExportClosure {
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportConstructor.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Mark a static method to be exported as a constructor of the exported
10 | * class.
11 | * The method should return the exported class instance.
12 | *
13 | */
14 | @Target({ElementType.METHOD})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface ExportConstructor {
17 | String value() default "";
18 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportInstanceMethod.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Mark a static method in a class annotated with ExportOverlay to
10 | * be exported as an instance method of the original class.
11 | * The first argument of the method must be the instance of the original class.
12 | */
13 | @Target({ElementType.METHOD})
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface ExportInstanceMethod {
16 | String value() default "";
17 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportJsInitMethod.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Mark an instance method in a class so as it will return the
10 | * JavascriptObject which should be used when wrapping the class.
11 | */
12 | @Target({ElementType.METHOD})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface ExportJsInitMethod {
15 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportOverlay.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | /**
4 | * Implements a decoupled Exportable interface. Type T will be exported.
5 | *
6 | * Classes implementing this interface, should be marked with Export annotation and
7 | * have to implement stub methods and constructor of the methods in the original class
8 | * to export.
9 | *
10 | * This classes could have static implementations of constructors and methods of the
11 | * original class which should be marked with ExportConstructor or ExportInstanceMethod.
12 | *
13 | */
14 | public interface ExportOverlay extends Exportable {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportPackage.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | *
10 | */
11 | @Target(ElementType.TYPE)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface ExportPackage {
14 |
15 | String value();
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExportStaticMethod.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Mark a static method in a class annotated with ExportOverlay to
10 | * be exported as an static method of the original class.
11 | */
12 | @Target({ElementType.METHOD})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface ExportStaticMethod {
15 | String value() default "";
16 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/Exportable.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | /**
4 | * Marker interface. To export a class to Javascript, perform the following
5 | * steps:
6 | *
7 | * add Exportable as an implemented interface Choose between a
8 | * whitelist or blacklist export policy If blacklist, add @gwt.export to the
9 | * JavaDoc of the class definition and use @gwt.noexport for any methods you do
10 | * not wish to be exported. By default, all public methods and static final
11 | * fields are exported. If whitelist, add @gwt.export to each method, field,
12 | * constructor you wish to export. use @gwt.exportPackage foo.bar to
13 | * override the generated Javascript package hierarchy If two methods have
14 | * the same export name, you can resolve the conflict by renaming the exported
15 | * method, e.g. "@gwt.export addDouble" will export method add(double, double)
16 | * as addDouble(double,double)
17 | *
18 | * Finally, somewhere in your entry point class, perform the following:
19 | *
Exporter exporter = (Exporter)GWT.create(MyClass.class);
20 | * exporter.export();
21 | *
22 | * @author Ray Cromwell <ray@timepedia.org>
23 | */
24 | public interface Exportable {
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/Exporter.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import com.google.gwt.core.client.JavaScriptObject;
4 |
5 | /**
6 | * Exportable classes passed to GWT.create() will return an implementation of
7 | * Exporter. Invoke the export() method to export the JavaScript bridge classes
8 | * and methods.
9 | *
10 | * @author Ray Cromwell <ray@timepedia.org>
11 | */
12 | public interface Exporter {
13 |
14 | @Deprecated
15 | /**
16 | * Invoking GWT.create() on an exportable class is sufficient to export it.
17 | */
18 | void export();
19 |
20 | /**
21 | * Invoked to synchronize Java object with underlying structural type JS
22 | * object after return from a Java method.
23 | */
24 | // void sync();
25 |
26 | boolean isAssignable(Object o);
27 |
28 | JavaScriptObject getJsConstructor();
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExporterBaseImpl.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.util.Date;
4 |
5 | import com.google.gwt.core.client.JavaScriptObject;
6 | import com.google.gwt.core.client.JsArray;
7 | import com.google.gwt.core.client.JsArrayNumber;
8 | import com.google.gwt.core.client.JsArrayString;
9 |
10 | /**
11 | * No-op implementation when export is disabled.
12 | */
13 | public class ExporterBaseImpl {
14 |
15 | public void setWrapper(Object instance, JavaScriptObject wrapper) {
16 | }
17 |
18 | public JavaScriptObject typeConstructor(Exportable type) {
19 | return null;
20 | }
21 |
22 | public JavaScriptObject typeConstructor(String type) {
23 | return null;
24 | }
25 |
26 | public JavaScriptObject wrap(Object type) {
27 | return null;
28 | }
29 |
30 | public JavaScriptObject wrap(Object[] type) {
31 | return null;
32 | }
33 |
34 | public JavaScriptObject wrap(JavaScriptObject[] type) {
35 | return null;
36 | }
37 |
38 | public JavaScriptObject wrap(double[] type) {
39 | return null;
40 | }
41 |
42 | public JavaScriptObject wrap(float[] type) {
43 | return null;
44 | }
45 |
46 | public JavaScriptObject wrap(int[] type) {
47 | return null;
48 | }
49 |
50 | public JavaScriptObject wrap(char[] type) {
51 | return null;
52 | }
53 |
54 | public JavaScriptObject wrap(byte[] type) {
55 | return null;
56 | }
57 |
58 | public JavaScriptObject wrap(long[] type) {
59 | return null;
60 | }
61 |
62 | public JavaScriptObject wrap(short[] type) {
63 | return null;
64 | }
65 |
66 | public JavaScriptObject declarePackage(String qualifiedExportName) {
67 | return null;
68 | }
69 |
70 | public JavaScriptObject runDispatch(Object instance, Class clazz, int meth,
71 | JsArray arguments, boolean isStatic, boolean isVarArgs) {
72 | return null;
73 | }
74 |
75 | public void registerDispatchMap(Class clazz, JavaScriptObject dispMap, boolean isStatic) {
76 | }
77 |
78 | public JavaScriptObject wrap(String[] type) {
79 | return null;
80 | }
81 |
82 | public JavaScriptObject wrap(Date[] type) {
83 | return null;
84 | }
85 |
86 | public String[] toArrString(JsArrayString type) {
87 | return null;
88 | }
89 |
90 | public double[] toArrDouble(JsArrayNumber type) {
91 | return null;
92 | }
93 |
94 | public float[] toArrFloat(JsArrayNumber type) {
95 | return null;
96 | }
97 |
98 | public int[] toArrInt(JsArrayNumber type) {
99 | return null;
100 | }
101 |
102 | public byte[] toArrByte(JsArrayNumber type) {
103 | return null;
104 | }
105 |
106 | public char[] toArrChar(JsArrayNumber type) {
107 | return null;
108 | }
109 |
110 | public long[] toArrLong(JsArrayNumber type) {
111 | return null;
112 | }
113 |
114 | public T[] toArrObject(JavaScriptObject type, T[] ret) {
115 | return null;
116 | }
117 |
118 | public Exportable[] toArrExport(JavaScriptObject p) {
119 | return null;
120 | }
121 |
122 | public Date[] toArrDate(JavaScriptObject j) {
123 | return null;
124 | }
125 |
126 | public Object[] toArrJsObject(JavaScriptObject type) {
127 | return null;
128 | }
129 |
130 | public JavaScriptObject unshift(Object o, JavaScriptObject arr){
131 | return null;
132 | }
133 |
134 | public JavaScriptObject dateToJsDate(Date d) {
135 | return null;
136 | }
137 |
138 | public Date jsDateToDate(JavaScriptObject jd) {
139 | return null;
140 | }
141 |
142 | public Object gwtInstance(Object o) {
143 | return null;
144 | }
145 |
146 | public void addExporter(Class>c, T o) {
147 | }
148 |
149 | }
150 |
151 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/ExporterUtil.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.util.Date;
4 |
5 | import org.timepedia.exporter.client.ExporterBaseActual.JsArrayObject;
6 |
7 | import com.google.gwt.core.client.GWT;
8 | import com.google.gwt.core.client.JavaScriptObject;
9 | import com.google.gwt.core.client.JsArray;
10 | import com.google.gwt.core.client.JsArrayNumber;
11 | import com.google.gwt.core.client.JsArrayString;
12 |
13 | /**
14 | * Holds utility methods and wrapper state
15 | *
16 | * @author Ray Cromwell
17 | */
18 | public class ExporterUtil {
19 |
20 | public static abstract class ExportAll implements Exportable, Exporter {
21 | public void export() {
22 | export(false);
23 | }
24 | public abstract void export(boolean all);
25 | }
26 |
27 | private static ExporterBaseImpl impl = GWT.create(ExporterBaseImpl.class);
28 | static {
29 | }
30 |
31 | public static JavaScriptObject declarePackage(String qualifiedExportName) {
32 | return impl.declarePackage(qualifiedExportName);
33 | }
34 |
35 | /**
36 | * Automatically export all instantiable and public classes marked with the Exportable
37 | * interface.
38 | *
39 | * @param all, when this parameter is true it will export additionally all non-instantiable
40 | * classes marked with Exportable
41 | */
42 | public static void export(boolean all) {
43 | ExportAll export = GWT.create(ExportAll.class);
44 | export.export(all);
45 | }
46 |
47 | /**
48 | * Export all classes marked with the Exportable interface, including those which are not default
49 | * instantiable (interfaces, abstracts, without constructor, etc).
50 | *
51 | * Use ExporterUtil.export(false) to export just the set of instantiable classes and save some
52 | * js size, gwt-exporter will take care of exporting dependent classes when used.
53 | *
54 | */
55 | public static void exportAll() {
56 | export(true);
57 | }
58 |
59 | // public static void exportAllAsync() {
60 | // GWT.runAsync(new RunAsyncCallback() {
61 | // public void onFailure(Throwable reason) {
62 | // throw new RuntimeException(reason);
63 | // }
64 | //
65 | // public void onSuccess() {
66 | // GWT.create(ExportAll.class);
67 | // onexport();
68 | // }
69 | //
70 | // private native void onexport() /*-{
71 | // $wnd.onexport();
72 | // }-*/;
73 | // });
74 | // }
75 |
76 | public static JavaScriptObject runDispatch(Object instance, Class clazz, int meth,
77 | JsArray arguments, boolean isStatic, boolean isVarArgs) {
78 | return impl.runDispatch(instance, clazz, meth, arguments, isStatic, isVarArgs);
79 | }
80 |
81 | public static native byte getStructuralFieldbyte(JavaScriptObject jso,
82 | String field) /*-{
83 | return jso[field];
84 | }-*/;
85 |
86 | public static native char getStructuralFieldchar(JavaScriptObject jso,
87 | String field) /*-{
88 | return jso[field];
89 | }-*/;
90 |
91 | public static native double getStructuralFielddouble(JavaScriptObject jso,
92 | String field) /*-{
93 | return jso[field];
94 | }-*/;
95 |
96 | public static native float getStructuralFieldfloat(JavaScriptObject jso,
97 | String field) /*-{
98 | return jso[field];
99 | }-*/;
100 |
101 | public static native int getStructuralFieldint(JavaScriptObject jso,
102 | String field) /*-{
103 | return jso[field];
104 | }-*/;
105 |
106 | public static long getStructuralFieldlong(JavaScriptObject jso,
107 | String field) {
108 | return (long) getStructuralFielddouble(jso, field);
109 | }
110 |
111 | public static native T getStructuralFieldObject(JavaScriptObject jso,
112 | String field) /*-{
113 | return jso[field];
114 | }-*/;
115 |
116 | public static native short getStructuralFieldshort(JavaScriptObject jso,
117 | String field) /*-{
118 | return jso[field];
119 | }-*/;
120 |
121 | public static void registerDispatchMap(Class clazz, JavaScriptObject dispMap,
122 | boolean isStatic) {
123 | impl.registerDispatchMap(clazz, dispMap, isStatic);
124 | }
125 |
126 | public static native void setStructuralField(JavaScriptObject jso,
127 | String field, Object val) /*-{
128 | jso[field]=type;
129 | }-*/;
130 |
131 | public static void setWrapper(Object instance, JavaScriptObject wrapper) {
132 | impl.setWrapper(instance, wrapper);
133 | }
134 |
135 | public static JavaScriptObject typeConstructor(Exportable type) {
136 | return impl.typeConstructor(type);
137 | }
138 |
139 | public static JavaScriptObject typeConstructor(String type) {
140 | return impl.typeConstructor(type);
141 | }
142 |
143 | public static JavaScriptObject wrap(Object type) {
144 | return impl.wrap(type);
145 | }
146 |
147 | public static JavaScriptObject wrap(JavaScriptObject[] type) {
148 | return impl.wrap(type);
149 | }
150 |
151 | public static JavaScriptObject wrap(Object[] type) {
152 | return impl.wrap(type);
153 | }
154 |
155 | public static JavaScriptObject wrap(Exportable[] type) {
156 | return wrap((Object[])type);
157 | }
158 |
159 | public static JavaScriptObject wrap(String[] type) {
160 | return impl.wrap(type);
161 | }
162 |
163 | public static JavaScriptObject wrap(double[] type) {
164 | return impl.wrap(type);
165 | }
166 |
167 | public static JavaScriptObject wrap(float[] type) {
168 | return impl.wrap(type);
169 | }
170 |
171 | public static JavaScriptObject wrap(int[] type) {
172 | return impl.wrap(type);
173 | }
174 |
175 | public static JavaScriptObject wrap(char[] type) {
176 | return impl.wrap(type);
177 | }
178 |
179 | public static JavaScriptObject wrap(byte[] type) {
180 | return impl.wrap(type);
181 | }
182 |
183 | public static JavaScriptObject wrap(long[] type) {
184 | return impl.wrap(type);
185 | }
186 |
187 | public static JavaScriptObject wrap(short[] type) {
188 | return impl.wrap(type);
189 | }
190 |
191 | public static JavaScriptObject wrap(Date[] type) {
192 | return impl.wrap(type);
193 | }
194 |
195 | public static String[] toArrString(JavaScriptObject type) {
196 | return impl.toArrString(type.cast());
197 | }
198 |
199 | public static double[] toArrDouble(JavaScriptObject type) {
200 | return impl.toArrDouble(type.cast());
201 | }
202 |
203 | public static float[] toArrFloat(JavaScriptObject type) {
204 | return impl.toArrFloat(type.cast());
205 | }
206 |
207 | public static int[] toArrInt(JavaScriptObject type) {
208 | return impl.toArrInt(type.cast());
209 | }
210 |
211 | public static byte[] toArrByte(JavaScriptObject type) {
212 | return impl.toArrByte(type.cast());
213 | }
214 |
215 | public static char[] toArrChar(JavaScriptObject type) {
216 | return impl.toArrChar(type.cast());
217 | }
218 |
219 | public static long[] toArrLong(JavaScriptObject type) {
220 | return impl.toArrLong(type.cast());
221 | }
222 |
223 | public static T[] toArrObject(JavaScriptObject type, T[] ret) {
224 | return impl.toArrObject(type, ret);
225 | }
226 |
227 | public static Object[] toArrJsObject(JavaScriptObject type) {
228 | return impl.toArrJsObject(type);
229 | }
230 |
231 | public static Date[] toArrDate(JavaScriptObject type) {
232 | return impl.toArrDate(type);
233 | }
234 |
235 | // Although in Compiled mode we could cast an Exportable[] to any other T[] array
236 | // In hosted mode it is not possible, so we only support Exportable[] parameter
237 | public static Exportable[] toArrExport(JavaScriptObject type) {
238 | return impl.toArrExport(type);
239 | }
240 |
241 | public static JavaScriptObject unshift(Object o, JavaScriptObject arr) {
242 | return impl.unshift(o, arr);
243 | }
244 |
245 | public static JavaScriptObject dateToJsDate(Date d) {
246 | return impl.dateToJsDate(d);
247 | }
248 |
249 | public static Date jsDateToDate(JavaScriptObject jd) {
250 | return impl.jsDateToDate(jd);
251 | }
252 |
253 | public static int length(JavaScriptObject o) {
254 | return o.cast().length();
255 | }
256 |
257 | public static Object gwtInstance(Object o) {
258 | return impl.gwtInstance(o);
259 | }
260 |
261 | public static void addExporter(Class>c, T o) {
262 | impl.addExporter(c, o);
263 | }
264 |
265 | }
266 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/Getter.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marks a method as a getter for a readable property
10 | * its Javascript name to be overriden else the default java convention will be used (get/set/is removed and lowercase)
11 | *
12 | * @see Setter for also generating the set method for a writeable property
13 | */
14 | @Target({ElementType.METHOD})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Getter {
17 |
18 | String value() default "";
19 |
20 | boolean all() default false;
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/NoExport.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * If a class is marked for export, used this method to selectively disable
10 | * certain methods or fields from being exported.
11 | */
12 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface NoExport {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/SOptional.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Indicates a structural type field which may be optional.
10 | */
11 | @Target(
12 | {ElementType.METHOD, ElementType.FIELD})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface SOptional {
15 |
16 | public abstract boolean value() default false;
17 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/SType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Structural type field. Used to tell the @StructuralType annotation which
10 | * fields are important for matching, and what their names are. By default,
11 | * all Javabean properties must be matched. @SType can be used to expand the
12 | * fields which must be matched, or rename them.
13 | */
14 | @Target(
15 | {ElementType.METHOD, ElementType.FIELD})
16 | @Retention(RetentionPolicy.RUNTIME)
17 | public @interface SType {
18 |
19 | public abstract String value() default "";
20 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/Setter.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Marks a method as a setter for a writable property
10 | * its Javascript name to be overriden else the default java convention will be used (get/set/is removed and lowercase)
11 | *
12 | * @see Getter for also generating the get method for a read/write property
13 | */
14 | @Target({ElementType.METHOD})
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Setter {
17 |
18 | String value() default "";
19 |
20 | boolean all() default false;
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/StructuralType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Indicates that a class or interface may have Javascript objects automatically
10 | * promoted it its type when such objects are passed as arguments in situations
11 | * where the class type is expected. In the class of a class, the JS object must
12 | * contain properties whose names match java bean or @SType properties of the
13 | * class. Any classes that allow structural types must possess a no-arg
14 | * constructor and be non-final. JavaBean property setters must be non-final.
15 | *
16 | * In the case of interface types, each method in the interface must have
17 | * a corresponding property in the JS object whose value is a JS function. The
18 | * JS object will be automatically promoted to a Java implementation of the
19 | * interface which delegates the method implementations to the bound JS
20 | * functions on the JS object.
21 | */
22 | @Target(ElementType.TYPE)
23 | @Retention(RetentionPolicy.RUNTIME)
24 | public @interface StructuralType {
25 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/client/test/JsTestUtil.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.client.test;
2 |
3 | /**
4 | * Class used to run assert-equals in Jsni tests.
5 | *
6 | * This class is packet with gwt-exporter so as we can use it either
7 | * in tests and samples modules.
8 | *
9 | * @author manolo
10 | */
11 | public class JsTestUtil {
12 |
13 | public final String name;
14 |
15 | public JsTestUtil(Class> clz) {
16 | this.name = clz.getName().replaceAll("^.+\\.", "");
17 | }
18 |
19 | private String failed = "";
20 |
21 | public boolean isFailed() {
22 | return !failed.isEmpty();
23 | }
24 |
25 | public String getFailed() {
26 | return failed;
27 | }
28 |
29 | private native void print(T s) /*-{
30 | if ($wnd.console && $wnd.console.log) {
31 | $wnd.console.log(s);
32 | } else {
33 | $wnd.alert(s);
34 | }
35 | }-*/;
36 |
37 | private native String arrToStr(T o) /*-{
38 | var ret = '';
39 | for ( var i = 0; i < o.length; i++)
40 | ret += (i > 0 ? "," : "") + String(o[i]);
41 | return ret;
42 | }-*/;
43 |
44 | /**
45 | * Checks that both parameters have the same string representation.
46 | *
47 | * In case of arrays, it converts them to a comma separated string.
48 | * In case of numbers, it removes .0 part.
49 | * In case of classNames it compares just the unqualified name of the class.
50 | */
51 | public void assertEquals(Object a, Object b) {
52 | String sb = (b != null && b.toString().matches(".*(Array|\\[).*"))
53 | ? arrToStr(b) : b == null ? "null" : b.toString();
54 | String ss = "";
55 | while (!ss.equals(sb)) {
56 | ss = sb;
57 | sb = sb.replaceAll("(^|,)[^,]+[\\$\\.]([A-Z][\\w]+)\\$*(,|$)", "$1$2$3");
58 | }
59 | sb = sb.replaceAll("\\.0+([^\\d])", "$1");
60 | if (a == null && b == null || a != null
61 | && a.toString().equals(sb.toString())) {
62 | print("OK -> " + sb);
63 | } else {
64 | String btype = (b != null ? b.getClass().getName() : String.valueOf(b));
65 | String amsg = a == null ? "" : ("[" + a.getClass().getName() + "] " + a + " <=> [" + btype + "] ");
66 | String msg = "ERROR -> " + amsg + sb;
67 | print(msg);
68 | failed += (failed.isEmpty() ? "" : "\n") + msg;
69 | }
70 | }
71 |
72 | public void assertEqualsNumber(double a, double b) {
73 | if (a == b) {
74 | print("OK -> " + a);
75 | } else {
76 | String msg = "ERROR -> " + a + " <=> " + b;
77 | failed += (failed.isEmpty() ? "" : "\n") + msg;
78 | }
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/doclet/JsDoclet.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.doclet;
2 |
3 | import java.io.File;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.StringTokenizer;
10 |
11 | import com.sun.javadoc.AnnotationDesc;
12 | import com.sun.javadoc.ClassDoc;
13 | import com.sun.javadoc.ConstructorDoc;
14 | import com.sun.javadoc.ExecutableMemberDoc;
15 | import com.sun.javadoc.MethodDoc;
16 | import com.sun.javadoc.PackageDoc;
17 | import com.sun.javadoc.ParamTag;
18 | import com.sun.javadoc.Parameter;
19 | import com.sun.javadoc.RootDoc;
20 | import com.sun.javadoc.Tag;
21 | import com.sun.javadoc.Type;
22 | import com.sun.tools.doclets.formats.html.ConfigurationImpl;
23 | import com.sun.tools.doclets.formats.html.HtmlDoclet;
24 | import com.sun.tools.doclets.formats.html.HtmlDocletWriter;
25 | import com.sun.tools.doclets.internal.toolkit.util.ClassTree;
26 | import com.sun.tools.doclets.internal.toolkit.util.DocletConstants;
27 | import com.sun.tools.doclets.internal.toolkit.util.PackageListWriter;
28 | import com.sun.tools.doclets.internal.toolkit.util.Util;
29 |
30 | /**
31 | * Generates Js and Gss docs.
32 | */
33 | public class JsDoclet extends HtmlDoclet {
34 |
35 | public static boolean start(RootDoc rootDoc) {
36 | JsDoclet jsDoclet = new JsDoclet();
37 | try {
38 | return jsDoclet.startGeneration3(rootDoc);
39 | } catch (Exception e) {
40 | e.printStackTrace();
41 | }
42 | return false;
43 | }
44 |
45 | private boolean startGeneration3(RootDoc root) throws Exception {
46 | configuration = ConfigurationImpl.getInstance();
47 | configuration.root = root;
48 |
49 | if (root.classes().length == 0) {
50 | configuration.message.
51 | error("doclet.No_Public_Classes_To_Document");
52 | return false;
53 | }
54 | configuration.setOptions();
55 | //configuration.getDocletSpecificMsg().notice("doclet.build_version",
56 | //configuration.getDocletSpecificBuildDate());
57 | ClassTree classtree = new ClassTree(configuration,
58 | configuration.nodeprecated);
59 |
60 | generateClassFiles(root, classtree);
61 | if (configuration.sourcepath != null
62 | && configuration.sourcepath.length() > 0) {
63 | StringTokenizer pathTokens = new StringTokenizer(configuration.sourcepath,
64 | String.valueOf(File.pathSeparatorChar));
65 | boolean first = true;
66 | while (pathTokens.hasMoreTokens()) {
67 | Util.copyDocFiles(configuration,
68 | pathTokens.nextToken() + File.separator,
69 | DocletConstants.DOC_FILES_DIR_NAME, first);
70 | first = false;
71 | }
72 | }
73 |
74 | PackageListWriter.generate(configuration);
75 | generatePackageFiles(classtree);
76 |
77 | generateOtherFiles(root, classtree);
78 | configuration.tagletManager.printReport();
79 | return true;
80 | }
81 |
82 | // FIXME: exportOverlay is not implemented yet
83 | Map classTypeMap = new HashMap();
84 |
85 | @Override
86 | protected void generateOtherFiles(RootDoc rootDoc, ClassTree classTree)
87 | throws Exception {
88 | super.generateOtherFiles(rootDoc, classTree);
89 | HtmlDocletWriter writer = new HtmlDocletWriter(configuration, "jsdoc.html");
90 |
91 | writer.html();
92 | writer.head();
93 | writer.println(" ");
94 | writer.println(getCSS());
95 | writer.headEnd();
96 | writer.body("white", true);
97 |
98 | ClassDoc[] classes = rootDoc.classes();
99 | Arrays.sort(classes);
100 |
101 | // Document static methods
102 | List smethods = new ArrayList();
103 | for (ClassDoc clz : classes) {
104 | if (isExportable(clz)) {
105 |
106 | // FIXME: implement exportoverlay somehow.
107 | classTypeMap.put(clz.simpleTypeName(), getExportedName(clz, false, true));
108 |
109 | if (hasStaticMethods(clz)) {
110 | for (MethodDoc md : clz.methods()) {
111 | if (md.isStatic() && isExportable(md)) {
112 | smethods.add(md);
113 | }
114 | }
115 | }
116 | }
117 | }
118 | if (smethods.size() > 0) {
119 | writer.h1("Exported JavaScript-API: Index of static functions");
120 | writer.table(1, "100%", 0, 0);
121 | java.util.Collections.sort(smethods);
122 | for (MethodDoc md: smethods) {
123 | writeMethod(writer, false, true, md);
124 | }
125 | writer.tableEnd();
126 | }
127 |
128 | List eclasses = new ArrayList();
129 | for (ClassDoc clz : classes) {
130 | if (isExportable(clz) && hasClassMethods(clz) && !isExportedClosure(clz)) {
131 | eclasses.add(clz);
132 | }
133 | }
134 |
135 | if (eclasses.size() > 0) {
136 | // Write an index of classes
137 | writer.h1("Exported JavaScript-API: Index of Classes");
138 | writer.ul();
139 | for (ClassDoc clz : eclasses) {
140 | writer.li();
141 | writer.println(getExportedName(clz, true, true));
142 | }
143 | writer.ulEnd();
144 |
145 | // Write each class
146 | for (ClassDoc clz : eclasses) {
147 | String className = getExportedName(clz, false, true);
148 | writer.h2(""+ className + "
");
149 | String comments = clz.commentText().trim();
150 | if (!comments.isEmpty()) {
151 | writer.println("" + filter(clz.commentText()) + "
");
152 | }
153 |
154 | writer.table(1, "100%", 0, 0);
155 | writeConstructors(writer, clz);
156 | writeMethods(writer, clz, true, isExportedAll(clz), new ArrayList());
157 | writer.tableEnd();
158 | }
159 | }
160 |
161 | writer.bodyEnd();
162 | writer.htmlEnd();
163 | writer.flush();
164 | writer.close();
165 | }
166 |
167 | private void writeConstructors(HtmlDocletWriter writer, ClassDoc clz) {
168 | String cName = getExportedName(clz, false, true);
169 | boolean firstcon = true;
170 | for (ConstructorDoc cd : clz.constructors()) {
171 | if (isExportable(cd)) {
172 | if (firstcon) {
173 | writer.tr();
174 | writer.tdColspanBgcolorStyle(2, "", "jsdocHeader");
175 | writer.print("Constructors");
176 | firstcon = false;
177 | writer.tdEnd();
178 | writer.trEnd();
179 | }
180 | writer.tr();
181 | writer.tdVAlignClass("top", "jsdocRetType");
182 | writer.print(" ");
183 | writer.tdEnd();
184 | writer.tdVAlignClass("top", "jsdocMethod");
185 | writer.print("" + cName + " (");
186 | writeParameters(writer, cd.parameters());
187 | writer.print(")");
188 | writer.br();
189 |
190 | String comment = filter(cd.commentText());
191 | comment += getCommentTags(cd);
192 | writer.print("");
193 |
194 | writer.tdEnd();
195 | writer.trEnd();
196 | }
197 | }
198 | }
199 |
200 | private void writeMethods(HtmlDocletWriter writer, ClassDoc clz, boolean firstcon, boolean all, List visited) {
201 | if (clz == null) {
202 | return;
203 | }
204 | for (MethodDoc md : clz.methods()) {
205 | if (!md.isStatic() && md.isPublic() && !md.isAbstract()) {
206 | String sig = getSignatureMethod(md);
207 | if (!visited.contains(sig)) {
208 | if (all || isExportable(md)) {
209 | writeMethod(writer, firstcon, false, md);
210 | firstcon = false;
211 | }
212 | visited.add(sig);
213 | }
214 | }
215 | }
216 | writeMethods(writer, clz.superclass(), firstcon, all, visited);
217 | }
218 |
219 | private MethodDoc getMethodInInterface(MethodDoc md) {
220 | if (!md.containingClass().isInterface()) {
221 | String sig = getSignatureMethod(md);
222 | for (ClassDoc cd: md.containingClass().interfaces()) {
223 | for (MethodDoc m: cd.methods()) {
224 | if (sig.equals(getSignatureMethod(m)) && isExportable(m)) {
225 | return m;
226 | }
227 | }
228 | }
229 | }
230 | return null;
231 | }
232 |
233 | private MethodDoc getMethodInSuperclass(ClassDoc superc, MethodDoc md) {
234 | if (superc != null) {
235 | String sig = getSignatureMethod(md);
236 | for (MethodDoc m : superc.methods()) {
237 | if (sig.equals(getSignatureMethod(m))) {
238 | return m;
239 | }
240 | }
241 | return getMethodInSuperclass(superc.superclass(), md);
242 | }
243 | return null;
244 | }
245 |
246 | private String getSignatureMethod (MethodDoc md) {
247 | return md.returnType() + " " + md.name() + md.signature();
248 | }
249 |
250 | private void writeMethod(HtmlDocletWriter writer, boolean firstcon, boolean writePakage,
251 | MethodDoc md) {
252 | ClassDoc cd = md.containingClass();
253 | String pkg = writePakage ? getExportedName(cd, false, true) : "";
254 | String name = getExportedName(md);
255 | if (name.startsWith("$wnd")) {
256 | pkg = "";
257 | name = name.replaceFirst("^\\$wnd\\.", "");
258 | }
259 | if (!pkg.isEmpty()) {
260 | pkg += ".";
261 | }
262 |
263 | if (firstcon) {
264 | writer.tr();
265 | writer.tdColspanBgcolorStyle(2, "", "jsdocHeader");
266 | writer.print("Methods");
267 | firstcon = false;
268 | writer.tdEnd();
269 | writer.trEnd();
270 | }
271 | writer.tr();
272 | writer.tdVAlignClass("top", "jsdocRetType");
273 | writer.print(getExportedName(md.returnType(), true));
274 |
275 | writer.tdEnd();
276 | writer.tdVAlignClass("top", "jsdocMethod");
277 | writer.print(
278 | "" + pkg + name + " "
279 | + "(");
280 | writeParameters(writer, md.parameters());
281 | writer.print(")");
282 | writer.br();
283 |
284 | String comments = md.commentText();
285 | if (!md.isStatic() && comments.isEmpty()) {
286 | MethodDoc id = getMethodInInterface(md);
287 | if (id != null) {
288 | comments = id.commentText();
289 | }
290 | if (comments.isEmpty()) {
291 | id = getMethodInSuperclass(cd.superclass(), md);
292 | } else {
293 | md = id;
294 | }
295 | if (id != null) {
296 | comments = id.commentText();
297 | md = id;
298 | }
299 | }
300 | comments += getCommentTags(md);
301 | if (!comments.isEmpty()) {
302 | writer.print("");
303 | }
304 | writer.tdEnd();
305 | writer.trEnd();
306 | }
307 |
308 | private String getCommentTags(ExecutableMemberDoc doc) {
309 | String ret = "";
310 | if (doc != null) {
311 | ret += "";
312 | for (ParamTag t : doc.paramTags() ){
313 | ret +="" + t.parameterName() + " " + t.parameterComment();
314 | }
315 | for (Tag t : doc.tags("return") ){
316 | ret += "return " + t.text();
317 | }
318 | ret += " ";
319 | }
320 | return ret;
321 | }
322 |
323 | private boolean hasClassMethods(ClassDoc clz) {
324 | if (clz != null && !clz.isInterface() && !clz.isAbstract()) {
325 | for (ConstructorDoc cd : clz.constructors()) {
326 | if (isExportable(cd)) {
327 | return true;
328 | }
329 | }
330 | for (MethodDoc md : clz.methods()) {
331 | if (!md.isStatic()) {
332 | boolean exportable = isExportable(md);
333 | if (!exportable && (md = getMethodInInterface(md)) != null) {
334 | exportable = isExportable(md);
335 | }
336 | if (exportable) {
337 | return true;
338 | }
339 | }
340 | }
341 | return hasClassMethods(clz.superclass());
342 | }
343 | return false;
344 | }
345 |
346 | private boolean hasStaticMethods(ClassDoc clz) {
347 | int countExportedMethods = 0;
348 | for (MethodDoc md : clz.methods()) {
349 | if (isExportable(md) && md.isStatic()) {
350 | countExportedMethods++;
351 | }
352 | }
353 | return countExportedMethods > 0;
354 | }
355 |
356 | private String getExportedName(MethodDoc cd) {
357 | String ename = cd.name();
358 | for (AnnotationDesc a : cd.annotations()) {
359 | if (a.annotationType().name().equals("Export")) {
360 | for (AnnotationDesc.ElementValuePair p : a.elementValues()) {
361 | ename = p.value().toString().trim();
362 | break;
363 | }
364 | }
365 | }
366 | return ename.replaceAll("\"", "");
367 | }
368 |
369 | protected String filter(String s) {
370 | if (s.startsWith("Created")) {
371 | return "";
372 | }
373 | s = s.replaceAll("(?s)\\{@link\\s[^\\}]*?#(.+)\\}", "$1");
374 | s = s.replaceAll("(?s)\\{@link\\s[^\\}]*?([^\\.\\}]+)\\}", "$1 ");
375 | return s;
376 | }
377 |
378 | private String getExportedName(Type clz, boolean link) {
379 | return (clz.isPrimitive() ? "void".equals(clz.typeName()) ? " "
380 | : clz.typeName() : getExportedName(clz.asClassDoc(), link, false)) + clz.dimension();
381 | }
382 |
383 | private void writeParameters(HtmlDocletWriter writer, Parameter[] ps) {
384 | writer.print(getParameterString(ps));
385 | }
386 |
387 | private boolean isExportable(ConstructorDoc cd) {
388 | boolean export = isExported(cd.containingClass());
389 | for (AnnotationDesc a : cd.annotations()) {
390 | if (a.annotationType().name().equals("Export")) {
391 | export = true;
392 | }
393 | if (a.annotationType().name().equals("NoExport")) {
394 | export = false;
395 | }
396 | }
397 | return export;
398 | }
399 |
400 | private boolean isExportable(MethodDoc md) {
401 | if (md == null) {
402 | return false;
403 | }
404 | boolean export = isExported(md.containingClass());
405 | for (AnnotationDesc a : md.annotations()) {
406 | if (a.annotationType().name().equals("Export")) {
407 | return true;
408 | }
409 | if (a.annotationType().name().equals("NoExport")) {
410 | return false;
411 | }
412 | }
413 | if (!export) {
414 | export = isExportable(getMethodInInterface(md));
415 | }
416 | return export;
417 | }
418 |
419 |
420 | private boolean isExportedClosure(ClassDoc clz) {
421 | for (AnnotationDesc a : clz.annotations()) {
422 | String aname = a.annotationType().name();
423 | if (aname.equals("ExportClosure")) {
424 | return true;
425 | }
426 | }
427 | return false;
428 | }
429 |
430 | private boolean isExportedAll(ClassDoc clz) {
431 | for (AnnotationDesc a : clz.annotations()) {
432 | String aname = a.annotationType().name();
433 | if (aname.equals("Export") || aname.equals("ExportClosure")) {
434 | for (AnnotationDesc.ElementValuePair p : a.elementValues()) {
435 | if ("all".equals(p.element().name())) {
436 | return "true".equals(p.value().toString());
437 | }
438 | }
439 | }
440 | }
441 | return false;
442 | }
443 |
444 | private boolean isExported(ClassDoc clz) {
445 | for (AnnotationDesc a : clz.annotations()) {
446 | String aname = a.annotationType().name();
447 | if (aname.equals("Export") || aname.equals("ExportClosure")) {
448 | return true;
449 | }
450 | }
451 | return false;
452 | }
453 |
454 | private String getExportedPackage(ClassDoc clz) {
455 | if (clz == null) {
456 | return "";
457 | }
458 |
459 | PackageDoc cpkg = clz.containingPackage();
460 | String pkg = cpkg == null ? "" : (cpkg.name().trim());
461 |
462 | for (AnnotationDesc a : clz.annotations()) {
463 | if (a.annotationType().name().equals("ExportPackage")) {
464 | for (AnnotationDesc.ElementValuePair p : a.elementValues()) {
465 | pkg = p.value().toString().replaceAll("\"", "");
466 | if (!pkg.isEmpty()) {
467 | pkg += ".";
468 | }
469 | break;
470 | }
471 | }
472 | }
473 | return pkg;
474 | }
475 |
476 | private String getExportedName(ClassDoc clz, boolean withLink, boolean withPkg) {
477 | if (clz == null) {
478 | return "";
479 | }
480 |
481 | PackageDoc cpkg = clz.containingPackage();
482 | String pkg = cpkg == null ? "" : cpkg.name();
483 | String name = clz.name();
484 |
485 | boolean isClosure = false;
486 | boolean isEnclosed = clz.containingClass() != null;
487 | boolean isExportEnclosed = isEnclosed && isExportable(clz.containingClass());
488 | boolean removeEnclosedPart = false;
489 |
490 | if (isExportEnclosed) {
491 | pkg = getExportedName(clz.containingClass(), false, true);
492 | removeEnclosedPart = true;
493 | }
494 |
495 | for (AnnotationDesc a : clz.annotations()) {
496 | if (a.annotationType().name().equals("ExportPackage")) {
497 | for (AnnotationDesc.ElementValuePair p : a.elementValues()) {
498 | pkg = p.value().toString().trim();
499 | removeEnclosedPart = true;
500 | break;
501 | }
502 | }
503 | if (a.annotationType().name().equals("Export")) {
504 | for (AnnotationDesc.ElementValuePair p : a.elementValues()) {
505 | if ("value".equals(p.element().name())) {
506 | name = p.value().toString().trim().replaceAll("\"", "");
507 | if (!name.isEmpty()) {
508 | removeEnclosedPart = false;
509 | break;
510 | }
511 | }
512 | }
513 | }
514 | if (a.annotationType().name().equals("ExportClosure")) {
515 | isClosure = true;
516 | name = "function (";
517 | name += getParameterString(clz.methods()[0].parameters());
518 | name += ")";
519 | pkg = "";
520 | }
521 | }
522 | if (removeEnclosedPart) {
523 | name = name.replaceFirst("^.+\\.", "");
524 | }
525 |
526 | pkg = pkg.replaceAll("\"", "").replaceFirst("\\.+$", "");
527 | if (!pkg.isEmpty()) {
528 | pkg += ".";
529 | }
530 |
531 | if (withLink && !isClosure &&
532 | !name.matches("String|JavaScriptObject|Object|Exportable|Class|Date")) {
533 | if (withPkg) {
534 | name = pkg + "" + name + " ";
535 | } else {
536 | name = "" + name + " ";
537 | }
538 | } else if (withPkg) {
539 | name = pkg + name;
540 | }
541 | return name;
542 | }
543 |
544 | private String getParameterString(Parameter[] ps) {
545 | String result = "";
546 | for (int i = 0; i < ps.length; i++) {
547 | Type type = ps[i].type();
548 | String ename = getExportedName(type, true);
549 | String pname = ename.contains("function") ? "{}" : ps[i].name();
550 | result += "" + ename
551 | + " " + pname
552 | + " ";
553 | if (i < ps.length - 1) {
554 | result += ", ";
555 | }
556 | }
557 | return result;
558 | }
559 |
560 |
561 |
562 | private static boolean isExportable(ClassDoc clz) {
563 | if (clz == null) {
564 | return false;
565 | }
566 | for (ClassDoc i : clz.interfaces()) {
567 | if (i.name().contains("Exportable")) {
568 | return true;
569 | }
570 | for (ClassDoc j : i.interfaces()) {
571 | if (j.name().contains("Exportable")) {
572 | return true;
573 | }
574 | }
575 | }
576 | for (MethodDoc m : clz.methods()) {
577 | if (!m.isStatic()) {
578 | for (AnnotationDesc a : m.annotations()) {
579 | if (a.annotationType().name().equals("Export")) {
580 | return true;
581 | }
582 | }
583 | }
584 | }
585 | return isExportable(clz.superclass());
586 | }
587 |
588 | public String getCSS() {
589 | return "";
645 | }
646 |
647 | }
648 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/DispatchTable.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collections;
5 | import java.util.HashMap;
6 | import java.util.HashSet;
7 | import java.util.Map;
8 | import java.util.Set;
9 |
10 | import com.google.gwt.core.ext.typeinfo.JArrayType;
11 | import com.google.gwt.core.ext.typeinfo.JType;
12 |
13 | /**
14 | * Information to assist quick overloaded type resolution at runtime.
15 | */
16 | public class DispatchTable {
17 |
18 | public DispatchTable(ExportableTypeOracle x) {
19 | xTypeOracle = x;
20 | }
21 |
22 | private boolean isOverloaded;
23 | private static ExportableTypeOracle xTypeOracle;
24 |
25 | /**
26 | * Add a signature to the dispatch table. Returns false if the same signature
27 | * occurs more than once.
28 | */
29 | public boolean addSignature(JExportableMethod method) {
30 |
31 | JExportableParameter[] exportableParameters = method.getExportableParameters();
32 |
33 | isOverloaded |= method.isVarArgs();
34 |
35 | Set sigs = sigMap.get(exportableParameters.length);
36 | if (sigs == null) {
37 | sigs = new HashSet();
38 | sigMap.put(exportableParameters.length, sigs);
39 | }
40 | isOverloaded |= sigMap.size() > 1;
41 |
42 | // When one argument is Object we have to handle the method via dispatcher,
43 | // which is able to cast primitive arguments to Object
44 | if (!isOverloaded) {
45 | for (JExportableParameter p : exportableParameters) {
46 | isOverloaded |= "java.lang.Object".equals(p.getTypeName());
47 | }
48 | }
49 |
50 | Signature sig = new Signature(method, exportableParameters);
51 | if (sigs.contains(sig)) {
52 | return false;
53 | } else {
54 | sigs.add(sig);
55 | }
56 | isOverloaded |= sigs.size() > 1;
57 | return true;
58 | }
59 |
60 | public int maxArity() {
61 | return Collections.max(sigMap.keySet()).intValue();
62 | }
63 |
64 | public boolean isOverloaded() {
65 | return isOverloaded;
66 | }
67 |
68 | public static String toJSON(HashMap dispatchMap) {
69 | StringBuilder sb = new StringBuilder();
70 | sb.append("{\n");
71 | int i = 0;
72 | for (Map.Entry e : dispatchMap.entrySet()) {
73 | if (e.getValue().isOverloaded()) {
74 | // We use a number instead of the method name, so as the generated
75 | // js is small.
76 | sb.append(" " + i++ + ":" + e.getValue().toJSON() + ",\n");
77 | }
78 | }
79 | sb.append("}");
80 | return sb.toString();
81 | }
82 |
83 | public static class Signature {
84 |
85 | private JExportableMethod method;
86 |
87 | private JExportableParameter[] exportableParameters;
88 |
89 | public Signature(JExportableMethod method,
90 | JExportableParameter[] exportableParameters) {
91 | this.method = method;
92 | this.exportableParameters = exportableParameters;
93 | }
94 |
95 | @Override
96 | public boolean equals(Object o) {
97 | if (this == o) {
98 | return true;
99 | }
100 | if (o == null || getClass() != o.getClass()) {
101 | return false;
102 | }
103 |
104 | Signature signature = (Signature) o;
105 |
106 | if (!Arrays
107 | .equals(exportableParameters, signature.exportableParameters)) {
108 | return false;
109 | }
110 |
111 | return true;
112 | }
113 |
114 | @Override
115 | public int hashCode() {
116 | return exportableParameters != null ? Arrays
117 | .hashCode(exportableParameters) : 0;
118 | }
119 |
120 | public String toJSON() {
121 | StringBuilder sb = new StringBuilder();
122 | sb.append("[");
123 | String functionRef = "@" + method.getJSNIReference();
124 | if (method.isStatic() || method.needsWrapper()) {
125 | sb.append(functionRef);
126 | } else {
127 | sb.append("function() { return this." + functionRef+".apply(this, arguments); }");
128 | }
129 | sb.append(",");
130 |
131 | String wrap = method.getExportableReturnType(false) == null ? null : method.getExportableReturnType(false).getWrapperFunc();
132 | sb.append(wrap + "," + generateWrapArgumentsFunction(method) + ",");
133 | for (JExportableParameter param : exportableParameters) {
134 | String jsType = param.getJsTypeOf();
135 | if (jsType.equals("number") || jsType.equals("object") ||
136 | jsType.equals("string") || jsType.equals("boolean") ||
137 | jsType.equals("array") ) {
138 | jsType = "\""+jsType+"\"";
139 | }
140 | sb.append(jsType + ",");
141 | }
142 | sb.append("]");
143 | return sb.toString();
144 | }
145 | }
146 |
147 | public String toJSON() {
148 | StringBuilder json = new StringBuilder();
149 | json.append("{\n");
150 | for (Integer arity : sigMap.keySet()) {
151 | json.append(" " + arity + ":" + toJSON(sigMap.get(arity)) + ",\n");
152 | }
153 | json.append(" }");
154 | return json.toString();
155 | }
156 |
157 | static boolean isAnyOverridden(HashMap dispatchMap) {
158 | for (Map.Entry e : dispatchMap.entrySet()) {
159 | if (e.getValue().isOverloaded()) {
160 | return true;
161 | }
162 | }
163 | return false;
164 | }
165 | private String toJSON(Set signatures) {
166 | StringBuilder sb = new StringBuilder();
167 | sb.append("[");
168 | for (Signature s : signatures) {
169 | sb.append(s.toJSON() + ",");
170 | }
171 | sb.append("]");
172 | return sb.toString();
173 | }
174 |
175 | private Map> sigMap
176 | = new HashMap>();
177 |
178 | private static String generateWrapArgumentsFunction(JExportableMethod method) {
179 | String args = "[";
180 | JExportableParameter params[] = method.getExportableParameters();
181 | boolean hasClosures = false;
182 | for (int i = 0; i < params.length; i++) {
183 | args += (i > 0 ? "," : "");
184 | String argName = "args[" + i + "]";
185 | JType t = params[i].getParam().getType();
186 | JArrayType a = t.isArray();
187 | if (a != null) {
188 | JExportableClassType requestedType = xTypeOracle.findExportableClassType(a.getComponentType().getQualifiedSourceName());
189 | if (xTypeOracle.isClosure(requestedType)) {
190 | hasClosures = true;
191 | args += argName
192 | + " == null ? null :function(a) {for (var i = 0; i < a.length ; i++) {a[i] = a[i].constructor == $wnd."
193 | + requestedType.getJSQualifiedExportName()
194 | + " ? a[i]." + ClassExporter.GWT_INSTANCE + " : @"
195 | + requestedType.getQualifiedExporterImplementationName()
196 | + "::makeClosure(Lcom/google/gwt/core/client/JavaScriptObject;)(a[i]);}return a;}("
197 | + argName + ")";
198 | } else {
199 | args += argName;
200 | }
201 | } else {
202 | JExportableClassType requestedType = xTypeOracle.findExportableClassType(t.getQualifiedSourceName());
203 | if (xTypeOracle.isClosure(requestedType)) {
204 | hasClosures = true;
205 | args += argName
206 | + " == null ? null : function(a) { a = a.constructor == $wnd."
207 | + requestedType.getJSQualifiedExportName()
208 | + " ? a." + ClassExporter.GWT_INSTANCE + " : @"
209 | + requestedType.getQualifiedExporterImplementationName()
210 | + "::makeClosure(Lcom/google/gwt/core/client/JavaScriptObject;)(a); return a;}("
211 | + argName + ")";
212 | } else {
213 | args += argName;
214 | }
215 | }
216 | }
217 | args += "]";
218 | String unshift = "@org.timepedia.exporter.client.ExporterUtil::unshift(Ljava/lang/Object;Lcom/google/gwt/core/client/JavaScriptObject;)";
219 | boolean needsUnshift = !method.isStatic() && method.needsWrapper();
220 | if (hasClosures) {
221 | String ret = "function(instance, args){return ";
222 | if (needsUnshift) {
223 | return ret + unshift + "(instance, " + args + ")}";
224 | } else {
225 | return ret + args + "}";
226 | }
227 | } else {
228 | return needsUnshift ? unshift : "";
229 | }
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/ExportableTypeOracle.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import org.timepedia.exporter.client.Export;
9 | import org.timepedia.exporter.client.ExportClosure;
10 | import org.timepedia.exporter.client.ExportConstructor;
11 | import org.timepedia.exporter.client.Getter;
12 | import org.timepedia.exporter.client.NoExport;
13 | import org.timepedia.exporter.client.Setter;
14 | import org.timepedia.exporter.client.StructuralType;
15 |
16 | import com.google.gwt.core.ext.TreeLogger;
17 | import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
18 | import com.google.gwt.core.ext.typeinfo.JClassType;
19 | import com.google.gwt.core.ext.typeinfo.JConstructor;
20 | import com.google.gwt.core.ext.typeinfo.JField;
21 | import com.google.gwt.core.ext.typeinfo.JMethod;
22 | import com.google.gwt.core.ext.typeinfo.JType;
23 | import com.google.gwt.core.ext.typeinfo.TypeOracle;
24 | import com.google.gwt.core.ext.typeinfo.TypeOracleException;
25 |
26 | /**
27 | *
28 | */
29 | public class ExportableTypeOracle {
30 |
31 | public static final String JSO_CLASS
32 | = "com.google.gwt.core.client.JavaScriptObject";
33 |
34 | static final String EXPORTER_CLASS = "org.timepedia.exporter.client.Exporter";
35 |
36 | static final String EXPORTABLE_CLASS
37 | = "org.timepedia.exporter.client.Exportable";
38 |
39 | static final String EXPORTALL_CLASS = "org.timepedia.exporter.client.ExporterUtil.ExportAll";
40 |
41 | static final String EXPORT_OVERLAY_CLASS
42 | = "org.timepedia.exporter.client.ExportOverlay";
43 |
44 | private static final String STRING_CLASS = "java.lang.String";
45 | private static final String DATE_CLASS = "java.util.Date";
46 |
47 | private JClassType exportAllType;
48 |
49 | public boolean isConstructor(JAbstractMethod method, JExportableClassType type) {
50 | return method.isConstructor() != null || method.getAnnotation(ExportConstructor.class) !=null;
51 | }
52 |
53 | public boolean isExportable(JField field) {
54 | return field.isStatic() && field.isPublic() && field.isFinal() && (
55 | isExportable(field.getAnnotation(Export.class)) || (
56 | isExportable(field.getEnclosingType()) && !isNotExportable(
57 | field.getAnnotation(NoExport.class))));
58 | }
59 |
60 | public boolean isExportable(JClassType type) {
61 | return isExportable(type.getAnnotation(Export.class)) ||
62 | (type.isInterface() != null &&
63 | isExportable(type.getAnnotation(ExportClosure.class)));
64 | }
65 |
66 | public boolean isExportable(JExportableClassType type) {
67 | return isExportable(type.getRequestedType());
68 | }
69 |
70 | public static boolean isExportable(Export annotation) {
71 | return annotation != null;
72 | }
73 |
74 | public static boolean isExportable(Getter annotation) {
75 | return annotation != null;
76 | }
77 |
78 | public static boolean isExportable(Setter annotation) {
79 | return annotation != null;
80 | }
81 |
82 | public boolean isExportable(JAbstractMethod method, JExportableClassType type) {
83 | boolean export = false;
84 | // Only public methods are exported
85 | if (method.isPublic()) {
86 | Export e;
87 | if (method instanceof JConstructor && isInstantiable(method.getEnclosingType()) && method.getParameters().length == 0) {
88 | // zero-arg constructors always exportable
89 | export = true;
90 | } else if (isNotExportable(method.getAnnotation(NoExport.class))) {
91 | // Do not export methods annotated as NoExport, although the
92 | // method is marked as export in an interface or the entire class
93 | // is annotated as Export
94 | export = false;
95 | } else if (isExportable(method.getAnnotation(Export.class)) || isExportable(method.getAnnotation(Setter.class)) || isExportable(method.getAnnotation(Getter.class))) {
96 | // Export this method if has the Export annotation
97 | export = true;
98 | } else if (isExportable(method.getEnclosingType())) {
99 | // Export all method in a class annotated as Export
100 | export = true;
101 | } else if (type != null && (e = type.getType().getAnnotation(Export.class)) != null && e.all()) {
102 | // Export this method if the class has the Export.all attribute set
103 | // Filter some generic methods present in Object
104 | export = !method.getName().matches("getClass|hashCode|equals|notify|notifyAll|wait");
105 | } else {
106 | // Export methods which are annotated in implemented interfaces
107 | for (JClassType c : method.getEnclosingType().getImplementedInterfaces()) {
108 | for (JMethod m : c.getMethods()) {
109 | if (!isNotExportable(m.getAnnotation(NoExport.class))
110 | && (isExportable(c) || isExportable(m.getAnnotation(Export.class)) || isExportable(method.getAnnotation(Setter.class)) || isExportable(method.getAnnotation(Getter.class)))
111 | && m.getName().equals(method.getName())) {
112 | if (m.getReadableDeclaration(true, true, false, true, true).equals(
113 | ((JMethod) method).getReadableDeclaration(true, true, false,
114 | true, true))) {
115 | export = true;
116 | break;
117 | }
118 | }
119 | }
120 | }
121 | }
122 | }
123 | return export;
124 | }
125 |
126 | private static boolean isExportable(ExportClosure annotation) {
127 | return annotation != null;
128 | }
129 |
130 | private static boolean isNotExportable(NoExport annotation) {
131 | return annotation != null;
132 | }
133 |
134 | private static boolean isExportable(ExportConstructor annotation) {
135 | return annotation != null;
136 | }
137 |
138 | public boolean isExportableFactoryMethod(JMethod method, JType retClass) {
139 | if (isExportable(method, null) && isExportable(method.getAnnotation(ExportConstructor.class))) {
140 | if (method.isStatic() && retClass.equals(method.getReturnType())) {
141 | return true;
142 | }
143 | throw new RuntimeException("Method " + method.getEnclosingType() + " " + method
144 | + " ExportConstructor but it is not static or it does not return a " + retClass);
145 | }
146 | return false;
147 | }
148 |
149 | private TypeOracle typeOracle;
150 |
151 | private TreeLogger log;
152 |
153 | private JClassType exportableType = null;
154 |
155 | private JClassType jsoType = null;
156 |
157 | private JClassType stringType = null;
158 | private JClassType dateType = null;
159 |
160 | private JClassType exportOverlayType;
161 |
162 | private Map overlayTypes
163 | = new HashMap();
164 |
165 | public ExportableTypeOracle(TypeOracle typeOracle, TreeLogger log) {
166 | this.typeOracle = typeOracle;
167 | this.log = log;
168 | exportableType = typeOracle.findType(EXPORTABLE_CLASS);
169 | exportOverlayType = typeOracle.findType(EXPORT_OVERLAY_CLASS);
170 | exportAllType = typeOracle.findType(EXPORTALL_CLASS);
171 |
172 | jsoType = typeOracle.findType(JSO_CLASS);
173 | stringType = typeOracle.findType(STRING_CLASS);
174 | dateType = typeOracle.findType(DATE_CLASS);
175 | assert exportableType != null;
176 | assert exportOverlayType != null;
177 | assert jsoType != null;
178 | assert stringType != null;
179 |
180 | for (JClassType t : typeOracle.getTypes()) {
181 | if (t.isAssignableTo(exportOverlayType) && !t.equals(exportOverlayType)) {
182 | JClassType targetType = getExportOverlayType(t);
183 | overlayTypes.put(targetType.getQualifiedSourceName(),
184 | new JExportOverlayClassType(this, t));
185 | }
186 | }
187 | }
188 |
189 | public JExportableClassType findExportableClassType(String requestedClass) {
190 | JClassType requestedType = typeOracle.findType(requestedClass);
191 | if (requestedType != null) {
192 | if (requestedType.isAssignableTo(exportOverlayType)) {
193 | return new JExportOverlayClassType(this, requestedType);
194 | } else if (requestedType.isAssignableTo(exportableType)) {
195 | return new JExportableClassType(this, requestedType);
196 | }
197 | JExportOverlayClassType exportOverlay = overlayTypes.get(requestedClass);
198 | return exportOverlay;
199 | }
200 | return null;
201 | }
202 |
203 | public JExportableType findExportableType(String paramTypeName) {
204 | try {
205 | JType type = typeOracle.parse(paramTypeName);
206 | JClassType cType = type != null ? type.isClassOrInterface() : null;
207 | if (type.isPrimitive() != null) {
208 | return new JExportablePrimitiveType(this, type.isPrimitive());
209 | } else if (type.isArray() != null) {
210 | return new JExportableArrayType(this, type.isArray());
211 | } else if (overlayTypes.containsKey(paramTypeName)) {
212 | return overlayTypes.get(paramTypeName);
213 | } else if (cType.isAssignableTo(exportOverlayType)) {
214 | return new JExportOverlayClassType(this, type.isClassOrInterface());
215 | } else if (cType != null && (cType.isAssignableTo(exportableType)
216 | || cType.isAssignableTo(stringType)
217 | || cType.isAssignableTo(dateType)
218 | || cType.isAssignableTo(jsoType))) {
219 | return new JExportableClassType(this, type.isClassOrInterface());
220 | } else {
221 | return null;
222 | }
223 | } catch (TypeOracleException e) {
224 | return null;
225 | }
226 | }
227 |
228 | public JClassType getExportOverlayType(JClassType requestedType) {
229 | JClassType[] inf = requestedType.getImplementedInterfaces();
230 | for (JClassType i : inf) {
231 | if (isExportOverlay(i)) {
232 | return i.isParameterized().getTypeArgs()[0];
233 | }
234 | }
235 | return null;
236 | }
237 |
238 | public boolean isArray(JExportableClassType jExportableClassType) {
239 | return jExportableClassType.getType().isArray() != null;
240 | }
241 |
242 | // We maintain a cache with overlay classes exported via export closure
243 | static HashMap closuresCache = new HashMap();
244 |
245 | public boolean isClosure(JExportableClassType jExportableClassType) {
246 | if (jExportableClassType == null) {
247 | return false;
248 | }
249 |
250 | String cType = jExportableClassType.getType().getQualifiedSourceName();
251 | if (closuresCache.containsKey(cType)) {
252 | return true;
253 | }
254 |
255 | JClassType rType = jExportableClassType.getRequestedType();
256 | if (rType != null && rType.isAssignableTo(exportableType)) {
257 | ExportClosure ann = rType.getAnnotation(ExportClosure.class);
258 | if (ann != null && rType.isInterface() != null) {
259 | if (rType.getMethods().length > 0) {
260 | closuresCache.put(rType.getQualifiedSourceName(), jExportableClassType);
261 | closuresCache.put(cType, jExportableClassType);
262 | return true;
263 | }
264 | }
265 | }
266 | return false;
267 | }
268 |
269 | public boolean isExportOverlay(JClassType i) {
270 | return i.isAssignableTo(exportOverlayType);
271 | }
272 |
273 | public boolean isInstantiable(JClassType i) {
274 | return !i.isAbstract() && i.isInterface() == null;
275 | }
276 |
277 | public boolean isJavaScriptObject(JExportableClassType type) {
278 | return type.getType().isAssignableTo(jsoType);
279 | }
280 |
281 | public boolean isString(JExportableClassType type) {
282 | return type.getType().isAssignableTo(stringType);
283 | }
284 |
285 | public boolean isDate(JExportableClassType type) {
286 | return type.getType().isAssignableTo(dateType);
287 | }
288 |
289 | public boolean isString(JType type) {
290 | return type.isClass() != null && type.isClass().isAssignableTo(stringType);
291 | }
292 |
293 | public boolean isJavaScriptObject(JType type) {
294 | return type.isClass() != null && type.isClass().isAssignableTo(jsoType);
295 | }
296 |
297 | public boolean isExportAll(String requestedClass) {
298 | return typeOracle.findType(requestedClass).isAssignableTo(exportAllType);
299 | }
300 |
301 | public boolean hasExportableMethods(JClassType type) {
302 | return new JExportableClassType(this, type).getExportableMethods().length > 0;
303 | }
304 |
305 | public List findAllExportableTypes() {
306 | ArrayList types = new ArrayList();
307 | // Closures should be exported the first
308 | for (JClassType t : typeOracle.getTypes()) {
309 | if (t.isAssignableTo(exportableType) && isClosure(t)) {
310 | types.add(t);
311 | }
312 | }
313 | // ExportOverlays should be exported before other classes
314 | for (JClassType t : typeOracle.getTypes()) {
315 | if (types.contains(t) || t.equals(exportAllType)
316 | || t.equals(exportableType) || t.equals(exportOverlayType)) {
317 | continue;
318 | }
319 | if (t.isAssignableTo(exportOverlayType)) {
320 | types.add(t);
321 | }
322 | }
323 | // Finally all exportable classes
324 | for (JClassType t : typeOracle.getTypes()) {
325 | if (types.contains(t) || t.equals(exportAllType)
326 | || t.equals(exportableType) || t.equals(exportOverlayType)) {
327 | continue;
328 | }
329 | // Apart from implementing the Exportable interface, exportable
330 | // classes must have the @Export annotation in either the class
331 | // declaration or in one or more methods.
332 | if (t.isAssignableTo(exportableType)) {
333 | if (isExportable(t) || hasExportableMethods(t)) {
334 | types.add(t);
335 | }
336 | }
337 | }
338 | return types;
339 | }
340 |
341 | public boolean isClosure(JClassType type) {
342 | return type.getAnnotation(ExportClosure.class) != null;
343 | }
344 |
345 | public boolean isStructuralType(JClassType type) {
346 | // always false for now until enabled
347 | return false && type.getAnnotation(StructuralType.class) != null;
348 | }
349 |
350 | public String getJsTypeOf(JClassType type) {
351 | if (type.isAssignableTo(stringType)) {
352 | return "string";
353 | } else if (type.isAssignableTo(jsoType)) {
354 | return "object";
355 | }
356 | return "@" + type.getQualifiedSourceName() + "::class";
357 | }
358 |
359 | public JClassType getExportableType() {
360 | return exportableType;
361 | }
362 | }
363 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/ExporterGenerator.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.Generator;
4 | import com.google.gwt.core.ext.GeneratorContext;
5 | import com.google.gwt.core.ext.TreeLogger;
6 | import com.google.gwt.core.ext.UnableToCompleteException;
7 |
8 | public class ExporterGenerator extends Generator {
9 |
10 | public String generate(TreeLogger logger, GeneratorContext ctx,
11 | String requestedClass) throws UnableToCompleteException {
12 | ClassExporter classExporter = new ClassExporter(logger, ctx);
13 | String generatedClass = classExporter.exportClass(requestedClass, true);
14 | return generatedClass;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/ExporterGeneratorNoExport.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.Generator;
4 | import com.google.gwt.core.ext.GeneratorContext;
5 | import com.google.gwt.core.ext.TreeLogger;
6 | import com.google.gwt.core.ext.UnableToCompleteException;
7 |
8 | public class ExporterGeneratorNoExport extends Generator {
9 |
10 | public String generate(TreeLogger logger, GeneratorContext ctx,
11 | String requestedClass) throws UnableToCompleteException {
12 | ClassExporter classExporter = new ClassExporter(logger, ctx);
13 | String generatedClass = classExporter.exportClass(requestedClass, false);
14 | return generatedClass;
15 | }
16 | }
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportOverlayClassType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JClassType;
4 |
5 | /**
6 | *
7 | */
8 | public class JExportOverlayClassType extends JExportableClassType {
9 |
10 | private JClassType exportType;
11 |
12 | public JExportOverlayClassType(ExportableTypeOracle exportableTypeOracle,
13 | JClassType requestedType) {
14 | super(exportableTypeOracle, requestedType);
15 | exportType = exportableTypeOracle.getExportOverlayType(requestedType);
16 | }
17 |
18 | @Override
19 | public JClassType getType() {
20 | return exportType;
21 | }
22 |
23 | public JClassType getOverlayType() {
24 | return super.getType();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportable.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | /**
4 | * Interface for all exportable elements. Maps Java package, field, and method
5 | * names into JS equivalents
6 | *
7 | * @author Ray Cromwell
8 | */
9 | public interface JExportable {
10 |
11 | public String getJSQualifiedExportName();
12 |
13 | public String getJSNIReference();
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableArrayType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JArrayType;
4 | import com.google.gwt.core.ext.typeinfo.JType;
5 |
6 | import org.timepedia.exporter.client.ExporterUtil;
7 |
8 | /**
9 | *
10 | */
11 | public class JExportableArrayType extends JExportableClassType
12 | implements JExportableType {
13 |
14 | public JExportableArrayType(ExportableTypeOracle exportableTypeOracle,
15 | JArrayType array) {
16 | super(exportableTypeOracle, array);
17 | this.exportableTypeOracle = exportableTypeOracle;
18 | this.array = array;
19 | }
20 |
21 | private ExportableTypeOracle exportableTypeOracle;
22 |
23 | private JArrayType array;
24 |
25 | public boolean needsExport() {
26 | return true;
27 | }
28 |
29 | public String getQualifiedSourceName() {
30 | return array.getQualifiedSourceName();
31 | }
32 |
33 | @Override
34 | public String getWrapperFunc() {
35 | JType type = array.getComponentType();
36 | return "@" + ExporterUtil.class.getName() + "::wrap(["
37 | + type.getJNISignature() + ")";
38 | }
39 |
40 | public JExportableType getComponentType() {
41 | return exportableTypeOracle
42 | .findExportableType(array.getComponentType().getQualifiedSourceName());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableClassType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.Comparator;
7 | import java.util.HashMap;
8 | import java.util.HashSet;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | import org.timepedia.exporter.client.Export;
13 | import org.timepedia.exporter.client.ExportPackage;
14 | import org.timepedia.exporter.client.ExporterUtil;
15 | import org.timepedia.exporter.client.Getter;
16 | import org.timepedia.exporter.client.SType;
17 | import org.timepedia.exporter.client.Setter;
18 |
19 | import com.google.gwt.core.ext.typeinfo.JClassType;
20 | import com.google.gwt.core.ext.typeinfo.JConstructor;
21 | import com.google.gwt.core.ext.typeinfo.JField;
22 | import com.google.gwt.core.ext.typeinfo.JMethod;
23 | import com.google.gwt.core.ext.typeinfo.JType;
24 |
25 | /**
26 | *
27 | */
28 | public class JExportableClassType implements JExportable, JExportableType {
29 |
30 | private static final String IMPL_EXTENSION = "_ExporterImpl";
31 |
32 | private ExportableTypeOracle exportableTypeOracle;
33 |
34 | private JClassType type;
35 |
36 | public JExportableClassType(ExportableTypeOracle exportableTypeOracle,
37 | JClassType type) {
38 | this.exportableTypeOracle = exportableTypeOracle;
39 |
40 | this.type = type;
41 | }
42 |
43 | public boolean equals(Object o) {
44 | if (this == o) {
45 | return true;
46 | }
47 | if (o == null || getClass() != o.getClass()) {
48 | return false;
49 | }
50 |
51 | JExportableClassType that = (JExportableClassType) o;
52 |
53 | return getQualifiedSourceName().equals(that.getQualifiedSourceName());
54 | }
55 |
56 | public String[] getEnclosingClasses() {
57 | String[] enc = type.getName().split("\\.");
58 | String[] enclosingTypes = new String[enc.length - 1];
59 | if (enc.length > 1) {
60 | System.arraycopy(enc, 0, enclosingTypes, 0, enclosingTypes.length);
61 | }
62 | return enclosingTypes;
63 | }
64 |
65 | public JExportableConstructor[] getExportableConstructors() {
66 | ArrayList exportableCons = new ArrayList();
67 | for (JConstructor method : type.getConstructors()) {
68 | if (exportableTypeOracle.isExportable(method, this)) {
69 | exportableCons.add(new JExportableConstructor(this, method));
70 | }
71 | }
72 | return exportableCons.toArray(new JExportableConstructor[0]);
73 | }
74 |
75 | public JExportableMethod[] getExportableFactoryMethods() {
76 | ArrayList exportableMethods = new ArrayList();
77 | JType retClass = getTypeToExport();
78 | for (JMethod method : type.getMethods()) {
79 | if (exportableTypeOracle.isExportableFactoryMethod(method, retClass)) {
80 | exportableMethods.add(new JExportableMethod(this, method));
81 | }
82 | }
83 | return exportableMethods.toArray(new JExportableMethod[0]);
84 | }
85 |
86 | public JExportableField[] getExportableFields() {
87 | ArrayList exportableFields
88 | = new ArrayList();
89 |
90 | for (JField field : type.getFields()) {
91 | if (exportableTypeOracle.isExportable(field)) {
92 | exportableFields.add(new JExportableField(this, field));
93 | }
94 | }
95 | return exportableFields.toArray(new JExportableField[0]);
96 | }
97 |
98 | private JExportableMethod[] exportableMethods;
99 |
100 | private JExportableMethod jsInitMethod;
101 | private JExportableMethod afterCreateMethod;
102 |
103 | public JExportableMethod[] getExportableMethods() {
104 | if (exportableMethods == null) {
105 | ArrayList ret = new ArrayList();
106 |
107 | // Create a set with all methods in this class
108 | HashSet classMethods = new HashSet();
109 | classMethods.addAll(Arrays.asList(type.getMethods()));
110 | classMethods.addAll(Arrays.asList(type.getInheritableMethods()));
111 | List sortedList = new ArrayList(classMethods);
112 |
113 | // We sort methods so as the user can modify the order they are exported via
114 | // the export annotation. It is useful when we want export methods whose namespace
115 | // depends on previous methods, ie:
116 | // @Export("$wnd.$") method1()
117 | // @Export("$wnd.$.method") method2()
118 | Collections.sort(sortedList, new Comparator() {
119 | String exportableMethodname(JMethod m) {
120 | String ret = m.getName();
121 | Export e = m.getAnnotation(Export.class);
122 | if (e != null && e.value() != null && !e.value().isEmpty()) {
123 | ret = e.value();
124 | }
125 | return ret;
126 | }
127 | public int compare(JMethod o1, JMethod o2) {
128 | return exportableMethodname(o1).compareTo(exportableMethodname(o2));
129 | }
130 | });
131 |
132 | for (JMethod method : sortedList) {
133 | if (exportableTypeOracle.isConstructor(method, this)) {
134 | continue;
135 | }
136 |
137 | if (exportableTypeOracle.isExportable(method, this)) {
138 | JExportableMethod m = new JExportableMethod(this, method);
139 | if (m.isExportJsInitMethod()
140 | && exportableTypeOracle.isJavaScriptObject(method.getReturnType())
141 | ) {
142 | jsInitMethod = m;
143 | }
144 | if (m.isExportAfterCreateMethod()) {
145 | afterCreateMethod = m;
146 | } else {
147 | ret.add(m);
148 | }
149 | }
150 | }
151 | exportableMethods = ret.toArray(new JExportableMethod[0]);
152 | }
153 | return exportableMethods;
154 | }
155 |
156 | public Property[] getExportableProperties() {
157 | Map properties = new HashMap();
158 | JExportableMethod[] methods = getExportableMethods();
159 | for (JExportableMethod method : methods) {
160 | Getter getter = method.getMethod().getAnnotation(Getter.class);
161 | if (getter != null) {
162 | Property property = getProperty(properties, method, getter.value());
163 | if (property != null) {
164 | property.setGetter(method);
165 | }
166 | }
167 | Setter setter = method.getMethod().getAnnotation(Setter.class);
168 | if (setter != null) {
169 | Property property = getProperty(properties, method, setter.value());
170 | if (property != null) {
171 | property.setSetter(method);
172 | }
173 | }
174 |
175 | }
176 | return properties.values().toArray(new Property[properties.size()]);
177 | }
178 |
179 | /**
180 | * @param properties
181 | * @param method
182 | * @param name
183 | */
184 | private Property getProperty(Map properties,
185 | JExportableMethod method, String name) {
186 | Property property = null;
187 | if ("".equals(name)) {
188 | String methodName = method.getName();
189 | if (methodName.startsWith("get")) {
190 | methodName = methodName.substring(3);
191 | }
192 | else if (methodName.startsWith("is")) {
193 | methodName = methodName.substring(2);
194 | }
195 | else if (methodName.startsWith("set")) {
196 | methodName = methodName.substring(3);
197 | }
198 | methodName = Character.toLowerCase(methodName.charAt(0)) + methodName.substring(1);
199 | name = methodName;
200 | }
201 | property = properties.get(name);
202 | if (property == null) {
203 | property = new Property(name);
204 | properties.put(name, property);
205 | }
206 | return property;
207 | }
208 |
209 | public JExportableMethod getJsInitMethod() {
210 | return jsInitMethod;
211 | }
212 |
213 | public JExportableMethod getAfterCreateMethod() {
214 | return afterCreateMethod;
215 | }
216 |
217 | public ExportableTypeOracle getExportableTypeOracle() {
218 | return exportableTypeOracle;
219 | }
220 |
221 | public String getExporterImplementationName() {
222 | return type.getName().replace(".", "_") + IMPL_EXTENSION;
223 | }
224 |
225 | public String getHostedModeJsTypeCast() {
226 | return null;
227 | }
228 |
229 | public String getJsTypeOf() {
230 | return exportableTypeOracle.getJsTypeOf(getType());
231 | }
232 |
233 | public String getJSConstructor() {
234 | String pkg = getJSExportPackage().trim();
235 | if (!pkg.isEmpty()) {
236 | pkg += ".";
237 | }
238 | return pkg + getJSExportName();
239 | }
240 |
241 | String exportName;
242 | public String getJSExportName () {
243 | if (exportName == null) {
244 | // By default we use the name of the class.
245 | exportName = getTypeToExport().getName();
246 |
247 | Export expAnnotation = type.getAnnotation(Export.class);
248 | if (expAnnotation != null && !expAnnotation.value().trim().isEmpty()) {
249 | // use the annotation value
250 | exportName = expAnnotation.value().trim();
251 | } else if (type.getEnclosingType() != null) {
252 | // Check if the class is defined inside another exported type
253 | JExportableClassType encType = exportableTypeOracle
254 | .findExportableClassType(
255 | type.getEnclosingType().getQualifiedSourceName());
256 |
257 | // Check if the class has a pkgAnnotation
258 | ExportPackage pkgAnnotation = type.getAnnotation(ExportPackage.class);
259 |
260 | // Remove the enclosing part from the class name
261 | if (encType != null || pkgAnnotation != null) {
262 | exportName = exportName.replaceFirst("^.+\\.", "");
263 | }
264 |
265 |
266 | }
267 | }
268 | return exportName;
269 | }
270 |
271 | String exportPackage;
272 | public String getJSExportPackage() {
273 | if (exportPackage == null) {
274 | // By default we use the java namespace, but removing the 'client' part
275 | exportPackage = getPrefix();
276 | // Check for the @ExportPackage annotation
277 | ExportPackage ann = type.getAnnotation(ExportPackage.class);
278 | JClassType type = getTypeToExport();
279 | if (ann != null) {
280 | exportPackage = ann.value().trim();
281 | } else if (type.getEnclosingType() != null) {
282 | // Check if the class is defined inside another exported type to use it's name as base
283 | JExportableClassType encType = exportableTypeOracle
284 | .findExportableClassType(
285 | type.getEnclosingType().getQualifiedSourceName());
286 | if (encType != null) {
287 | exportPackage = encType.getJSQualifiedExportName();
288 | }
289 | }
290 | }
291 | return exportPackage;
292 | }
293 |
294 | public String getJSNIReference() {
295 | return type.getJNISignature();
296 | }
297 |
298 | public String getJSQualifiedExportName() {
299 | return getJSConstructor();
300 | }
301 |
302 | public String getPackageName() {
303 | return type.getPackage().getName();
304 | }
305 |
306 | public String getPrefix() {
307 | String prefix = "";
308 | boolean firstClientPackage = true;
309 | for (String pkg : type.getPackage().getName().split("\\.")) {
310 | if (firstClientPackage && pkg.equals("client")) {
311 | firstClientPackage = false;
312 | continue;
313 | }
314 | prefix += pkg;
315 | prefix += '.';
316 | }
317 | // remove trailing .
318 | return prefix.substring(0, prefix.length() - 1);
319 | }
320 |
321 | public String getQualifiedExporterImplementationName() {
322 | return getPackageName() + "." + getExporterImplementationName();
323 | }
324 |
325 | public String getQualifiedSourceName() {
326 | return getType().getQualifiedSourceName();
327 | }
328 |
329 | public JStructuralTypeField[] getStructuralTypeFields() {
330 | if (!isStructuralType()) {
331 | return new JStructuralTypeField[0];
332 | } else {
333 | ArrayList fields
334 | = new ArrayList();
335 | for (JMethod method : type.getMethods()) {
336 | if (method.getName().startsWith("set")
337 | && Character.isUpperCase(method.getName().charAt(3))
338 | && method.getParameters().length == 1
339 | || method.getAnnotation(SType.class) != null) {
340 | fields.add(new JStructuralTypeField(this, method));
341 | }
342 | }
343 | return fields.toArray(new JStructuralTypeField[0]);
344 | }
345 | }
346 |
347 | public JClassType getType() {
348 | return type;
349 | }
350 |
351 | public JClassType getRequestedType() {
352 | return type;
353 | }
354 |
355 | public JClassType getTypeToExport() {
356 | return exportableTypeOracle.isExportOverlay(type)
357 | ? exportableTypeOracle.getExportOverlayType(type) : type;
358 | }
359 |
360 | public String getWrapperFunc() {
361 | if (!needsExport()) {
362 | return null;
363 | }
364 | return "@" + ExporterUtil.class.getName()
365 | + "::wrap(Ljava/lang/Object;)";
366 | }
367 |
368 | public int hashCode() {
369 | return getQualifiedSourceName().hashCode();
370 | }
371 |
372 | public boolean isPrimitive() {
373 | return type.isPrimitive() != null;
374 | }
375 |
376 | public boolean isStructuralType() {
377 | return exportableTypeOracle.isStructuralType(this.getType());
378 | }
379 |
380 | public boolean isTransparentType() {
381 | return exportableTypeOracle.isJavaScriptObject(this)
382 | || exportableTypeOracle.isString(this)
383 | || exportableTypeOracle.isDate(this)
384 | || exportableTypeOracle.isArray(this);
385 | }
386 |
387 | public String getJsniSigForArrays() {
388 | if (exportableTypeOracle.isJavaScriptObject(this)) {
389 | return "[Lcom/google/gwt/core/client/JavaScriptObject;";
390 | } else if (isTransparentType()){
391 | return "[" + type.getJNISignature();
392 | } else if (exportableTypeOracle.isExportOverlay(type)) {
393 | // Fixes issue #35
394 | return "[Ljava/lang/Object;";
395 | } else {
396 | return "[Lorg/timepedia/exporter/client/Exportable;";
397 | }
398 | }
399 |
400 | public boolean needsExport() {
401 | return !isPrimitive() && !isTransparentType();
402 | }
403 |
404 | public boolean isInstantiable() {
405 | return exportableTypeOracle.isInstantiable(type);
406 | }
407 |
408 | }
409 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableConstructor.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
4 | import com.google.gwt.core.ext.typeinfo.JParameter;
5 | import com.google.gwt.core.ext.typeinfo.JType;
6 |
7 | /**
8 | * Wrapper utility class for dealing with exportable constructors
9 | *
10 | * @author Ray Cromwell (ray@timepedia.org)
11 | */
12 | public class JExportableConstructor extends JExportableMethod {
13 |
14 | private static final String STATIC_FACTORY_NAME = "___create";
15 |
16 | public JExportableConstructor(JExportableClassType exportableEnclosingType,
17 | JAbstractMethod method) {
18 | super(exportableEnclosingType, method);
19 | }
20 |
21 | private void assertExportable(JType param) {
22 |
23 | }
24 |
25 | public String getJSNIReference() {
26 | String reference = exportableEnclosingType.getQualifiedSourceName() + "::"
27 | + getStaticFactoryMethodName() + "(";
28 | JParameter[] params = method.getParameters();
29 | for (int i = 0; i < params.length; i++) {
30 | reference += params[i].getType().getJNISignature();
31 | }
32 | reference += ")";
33 | return reference;
34 | }
35 |
36 | public String getStaticFactoryMethodName() {
37 | return STATIC_FACTORY_NAME;
38 | }
39 |
40 | public JExportableType getExportableReturnType() {
41 | return exportableEnclosingType;
42 | }
43 |
44 | public String getStaticFactoryJSNIReference() {
45 | String reference =
46 | exportableEnclosingType.getQualifiedExporterImplementationName() + "::"
47 | + getStaticFactoryMethodName() + "(";
48 | JParameter[] params = method.getParameters();
49 | for (int i = 0; i < params.length; i++) {
50 | reference += params[i].getType().getJNISignature();
51 | }
52 | reference += ")";
53 | return reference;
54 | }
55 |
56 | public String getJSQualifiedExportName() {
57 | return exportableEnclosingType.getJSQualifiedExportName();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableField.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JField;
4 |
5 | import org.timepedia.exporter.client.Export;
6 |
7 | /**
8 | *
9 | */
10 | public class JExportableField {
11 |
12 | private JExportableClassType enclosingExportType;
13 |
14 | private JField field;
15 |
16 | private String exportName;
17 |
18 | public JExportableField(JExportableClassType enclosingExportType,
19 | JField field) {
20 | this.enclosingExportType = enclosingExportType;
21 | this.field = field;
22 | Export ann = field.getAnnotation(Export.class);
23 |
24 | if (ann != null && ann.value().length() > 0) {
25 | exportName = ann.value();
26 | } else {
27 | exportName = field.getName();
28 | }
29 | }
30 |
31 | public String getJSExportName() {
32 | return exportName;
33 | }
34 |
35 | public String getJSQualifiedExportName() {
36 | return enclosingExportType.getJSQualifiedExportName() + "."
37 | + getJSExportName();
38 | }
39 |
40 | public String getJSNIReference() {
41 | return field.getEnclosingType().getQualifiedSourceName() + "::" + field
42 | .getName();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableMethod.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportAfterCreateMethod;
5 | import org.timepedia.exporter.client.ExportConstructor;
6 | import org.timepedia.exporter.client.ExportInstanceMethod;
7 | import org.timepedia.exporter.client.ExportJsInitMethod;
8 | import org.timepedia.exporter.client.ExportStaticMethod;
9 |
10 | import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
11 | import com.google.gwt.core.ext.typeinfo.JArrayType;
12 | import com.google.gwt.core.ext.typeinfo.JConstructor;
13 | import com.google.gwt.core.ext.typeinfo.JMethod;
14 | import com.google.gwt.core.ext.typeinfo.JParameter;
15 | import com.google.gwt.core.ext.typeinfo.JType;
16 |
17 | /**
18 | *
19 | */
20 | public class JExportableMethod implements JExportable {
21 |
22 | public static final String WRAPPER_PREFIX = "__static_wrapper_";
23 |
24 | protected JExportableClassType exportableEnclosingType;
25 |
26 | protected JAbstractMethod method;
27 |
28 | private String exportName;
29 |
30 | private String qualifiedExportName;
31 |
32 | JExportableParameter[] exportableParameters;
33 |
34 | public JExportableMethod(JExportableClassType exportableEnclosingType,
35 | JAbstractMethod method) {
36 | this.exportableEnclosingType = exportableEnclosingType;
37 | this.method = method;
38 |
39 | String anValue = "";
40 | if (isExportInstanceMethod()) {
41 | anValue = method.getAnnotation(ExportInstanceMethod.class).value();
42 | } else if (isExportStaticMethod()) {
43 | anValue = method.getAnnotation(ExportStaticMethod.class).value();
44 | } else {
45 | Export ann = method.getAnnotation(Export.class);
46 | anValue = ann != null ? ann.value().trim() : "";
47 | }
48 |
49 | if (!anValue.isEmpty()) {
50 | exportName = anValue;
51 |
52 | // Static methods can be assigned to any name-space if it starts with $wnd
53 | if (isStatic() && anValue.startsWith("$wnd.")) {
54 | qualifiedExportName = anValue.replaceFirst("\\$wnd\\.", "");
55 | }
56 | } else {
57 | exportName = method.getName();
58 | }
59 |
60 | if (qualifiedExportName == null) {
61 | qualifiedExportName = getEnclosingExportType().getJSQualifiedExportName()
62 | + "." + getUnqualifiedExportName();
63 | }
64 |
65 | JParameter[] params = method.getParameters();
66 | exportableParameters = new JExportableParameter[params.length];
67 | for (int i = 0; i < params.length; i++) {
68 | exportableParameters[i] = new JExportableParameter(this, params[i]);
69 | }
70 | }
71 |
72 | public JAbstractMethod getMethod() {
73 | return method;
74 | }
75 |
76 | public String getUnqualifiedExportName() {
77 | return exportName;
78 | }
79 |
80 | public String getJSQualifiedExportName() {
81 | return qualifiedExportName;
82 | }
83 |
84 | public JExportableType getExportable(JType type, boolean searchComponent) {
85 | ExportableTypeOracle xTypeOracle = getExportableTypeOracle();
86 | JArrayType a = type.isArray();
87 | if (searchComponent && a != null) {
88 | return xTypeOracle.findExportableType(a.getComponentType().getQualifiedSourceName());
89 | } else {
90 | return xTypeOracle.findExportableType(type.getQualifiedSourceName());
91 | }
92 | }
93 |
94 | public JExportableType getExportableReturnType(boolean b) {
95 | return method instanceof JMethod ? getExportable(((JMethod)method).getReturnType(), b) : null;
96 | }
97 |
98 | public JExportableParameter[] getExportableParameters() {
99 | return exportableParameters;
100 | }
101 |
102 | public JExportableClassType getEnclosingExportType() {
103 | return exportableEnclosingType;
104 | }
105 |
106 | public String getEnclosingTypeQualifiedSourceName() {
107 | if (isExportOverlay()) {
108 | return ((JExportOverlayClassType)exportableEnclosingType).getOverlayType().getQualifiedSourceName();
109 | } else {
110 | return exportableEnclosingType.getQualifiedSourceName();
111 | }
112 | }
113 |
114 | public String getJSNIReference() {
115 | String reference = "";
116 | // we export the original method or the static wrapper
117 | if (!needsWrapper()) {
118 | // Use static ExportConstructor and ExportMethod methods in the overlay class
119 | if (isExportConstructor() || isExportInstanceMethod() || isExportStaticMethod() || isExportAfterCreateMethod()) {
120 | reference = getEnclosingTypeQualifiedSourceName();
121 | } else {
122 | reference = exportableEnclosingType.getQualifiedSourceName();
123 | }
124 | reference += "::" + method.getName() + "(";
125 | } else {
126 | reference = exportableEnclosingType.getQualifiedExporterImplementationName() + "::" + WRAPPER_PREFIX + method.getName() + "(";
127 | // Wrappers are static, so we pass the instance in the first argument.
128 | if (!isStatic()) {
129 | reference += exportableEnclosingType.getTypeToExport().getJNISignature();
130 | }
131 | }
132 |
133 | int len = exportableParameters.length;
134 | for (int i = 0; i < len; i++) {
135 | String signature = exportableParameters[i].getJNISignature();
136 | // Here we replace
137 | // - long by double signature
138 | // - arrays and date by javascriptobject
139 | if ("J".equals(signature)) {
140 | signature = "D";
141 | } else if (
142 | signature.startsWith("[")
143 | || signature.equals("Ljava/util/Date;")) {
144 | signature = "Lcom/google/gwt/core/client/JavaScriptObject;";
145 | }
146 | reference += signature;
147 | }
148 |
149 | reference += ")";
150 | return reference;
151 | }
152 |
153 | private Boolean wrap = null;
154 |
155 | // return true if this method needs a static wrapper.
156 | // - methods which have a 'long' parameter or return 'long'
157 | // - methods which have array parameters
158 | // - methods with variable arguments
159 | public boolean needsWrapper() {
160 | if (wrap == null) {
161 | wrap = false;
162 | if (method.isVarArgs()) {
163 | wrap = true;
164 | } else if (isExportInstanceMethod()) {
165 | wrap = true;
166 | } else if (getExportableReturnType(false) != null &&
167 | "long".equals(getExportableReturnType(false).getQualifiedSourceName())) {
168 | wrap = true;
169 | } else for (JExportableParameter p : getExportableParameters()) {
170 | if (p.getTypeName().matches("(long|.*\\[\\])$|java.util.Date")) {
171 | wrap = true;
172 | break;
173 | }
174 | }
175 | }
176 | return wrap;
177 | }
178 |
179 | public boolean isInStaticMap() {
180 | return isStatic() && !isExportInstanceMethod();
181 | }
182 |
183 | public boolean isStatic() {
184 | if (method instanceof JConstructor) {
185 | return false;
186 | } else {
187 | return ((JMethod) method).isStatic();
188 | }
189 | }
190 |
191 | public boolean isExportOverlay() {
192 | return exportableEnclosingType instanceof JExportOverlayClassType;
193 | }
194 |
195 | public boolean isExportInstanceMethod() {
196 | return isStatic()
197 | && isExportOverlay()
198 | && method.getAnnotation(ExportInstanceMethod.class) != null;
199 | }
200 |
201 | public boolean isExportStaticMethod() {
202 | return isStatic()
203 | && isExportOverlay()
204 | && method.getAnnotation(ExportStaticMethod.class) != null;
205 | }
206 |
207 | public boolean isExportConstructor() {
208 | return isStatic()
209 | && isExportOverlay()
210 | && method.getAnnotation(ExportConstructor.class) != null;
211 | }
212 |
213 | public boolean isExportJsInitMethod() {
214 | return isStatic() == false
215 | && method.getParameters().length == 0
216 | && method.getAnnotation(ExportJsInitMethod.class) != null;
217 | }
218 |
219 | public boolean isExportAfterCreateMethod() {
220 | return isStatic()
221 | && method.getParameters().length == 0
222 | && method.getAnnotation(ExportAfterCreateMethod.class) != null;
223 | }
224 |
225 | public ExportableTypeOracle getExportableTypeOracle() {
226 | return getEnclosingExportType().getExportableTypeOracle();
227 | }
228 |
229 | public String toString() {
230 | String str = exportableEnclosingType.getQualifiedSourceName() + "."
231 | + method.getName() + "(";
232 | JExportableParameter[] params = getExportableParameters();
233 | for (int i = 0; i < params.length; i++) {
234 | str += params[i];
235 | if (i < params.length - 1) {
236 | str += ", ";
237 | }
238 | }
239 | return str + ")";
240 | }
241 |
242 | public String getName() {
243 | return method.getName();
244 | }
245 |
246 | public boolean isVarArgs() {
247 | return method.isVarArgs();
248 | }
249 |
250 | }
251 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableParameter.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JParameter;
4 | import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
5 |
6 | /**
7 | *
8 | */
9 | public class JExportableParameter {
10 |
11 | private JParameter param;
12 | private JExportableMethod method;
13 | private ExportableTypeOracle xTypeOracle;
14 |
15 | public JParameter getParam() {
16 | return param;
17 | }
18 |
19 |
20 | public JExportableClassType getExportableEnclosingType() {
21 | return method.getEnclosingExportType();
22 | }
23 |
24 | public JExportableParameter(JExportableMethod exportableMethod,
25 | JParameter param) {
26 | this.param = param;
27 | this.method = exportableMethod;
28 | xTypeOracle = getExportableEnclosingType().getExportableTypeOracle();
29 | }
30 |
31 | public String getTypeName() {
32 | return param.getType().getQualifiedSourceName();
33 | }
34 |
35 | public String getJNISignature() {
36 | return param.getType().getJNISignature();
37 | }
38 |
39 | public String getExportParameterValue(String argName) {
40 |
41 | String paramTypeName = param.getType().getQualifiedSourceName();
42 | JExportableType type = xTypeOracle.findExportableType(paramTypeName);
43 |
44 | if (type != null && type.needsExport()) {
45 | JExportableClassType cType = (JExportableClassType) type;
46 | if (xTypeOracle.isClosure((JExportableClassType) type)) {
47 | return argName + " == null ? null : (" + argName + ".constructor == $wnd."
48 | + cType.getJSQualifiedExportName() + " ? " + argName
49 | + "." + ClassExporter.GWT_INSTANCE + " : "
50 | + "@" + cType.getQualifiedExporterImplementationName() + "::"
51 | + "makeClosure(Lcom/google/gwt/core/client/JavaScriptObject;)("
52 | + argName
53 | + "))";
54 | } else if (xTypeOracle.isExportable((JExportableClassType) type)) {
55 | return "(" + argName + " == null ? null : " + argName + "." + ClassExporter.GWT_INSTANCE + ")";
56 | }
57 | }
58 |
59 | if (param.getType().isClass() != null
60 | && !xTypeOracle.isJavaScriptObject(param.getType())
61 | && !xTypeOracle.isString(param.getType())) {
62 | return "@org.timepedia.exporter.client.ExporterUtil::gwtInstance(Ljava/lang/Object;)("
63 | + argName + ")";
64 | }
65 |
66 | return argName;
67 | }
68 |
69 | @Override
70 | public boolean equals(Object o) {
71 | if (this == o) {
72 | return true;
73 | }
74 | if (o == null || getClass() != o.getClass()) {
75 | return false;
76 | }
77 |
78 | JExportableParameter that = (JExportableParameter) o;
79 | return getJsTypeOf().equals(that.getJsTypeOf());
80 | }
81 |
82 | public String getJsTypeOf() {
83 |
84 | if (param == null) {
85 | return "null";
86 | } else if (param.getType().isArray() != null) {
87 | return "array";
88 | } else if (param.getType().isPrimitive() != null) {
89 | JPrimitiveType prim = param.getType().isPrimitive();
90 | return prim == JPrimitiveType.BOOLEAN ? "boolean" : "number";
91 | } else if (xTypeOracle.isString(param.getType())) {
92 | return "string";
93 | } else if (xTypeOracle.isJavaScriptObject(param.getType())) {
94 | return "object";
95 | } else {
96 | String paramTypeName = param.getType().getQualifiedSourceName();
97 | JExportableType type = xTypeOracle.findExportableType(paramTypeName);
98 | if (type != null && type instanceof JExportableClassType
99 | && xTypeOracle.isClosure((JExportableClassType) type)) {
100 | return "'function'";
101 | }
102 | return "@" + param.getType().getQualifiedSourceName() + "::class";
103 | }
104 | }
105 |
106 | public boolean isExportable() {
107 | String js = getJsTypeOf();
108 | return !js.contains("@") || getExportableType(false) != null;
109 | }
110 |
111 | @Override
112 | public int hashCode() {
113 | return param != null ? getJsTypeOf().hashCode() : 0;
114 | }
115 |
116 | public String toString() {
117 | return param.getType().getSimpleSourceName();
118 | }
119 |
120 | public JExportableType getExportableType(boolean b) {
121 | return method.getExportable(param.getType(), b);
122 | }
123 |
124 | public String getToArrayFunc(String qsn, String argName) {
125 | String ret = "ExporterUtil.";
126 | String after = ")";
127 | if (qsn.equals("java.lang.String[]")) {
128 | ret += "toArrString" ;
129 | } else if (qsn.equals("java.util.Date[]")) {
130 | ret += "toArrDate" ;
131 | } else if (qsn.equals("double[]")) {
132 | ret += "toArrDouble" ;
133 | } else if (qsn.equals("float[]")) {
134 | ret += "toArrFloat" ;
135 | } else if (qsn.equals("long[]")) {
136 | ret += "toArrLong" ;
137 | } else if (qsn.equals("int[]")) {
138 | ret += "toArrInt" ;
139 | } else if (qsn.equals("byte[]")) {
140 | ret += "toArrByte" ;
141 | } else if (qsn.equals("char[]")) {
142 | ret += "toArrChar" ;
143 | } else {
144 | ret += "toArrObject";
145 | after = ", new " + qsn.replace("]", "ExporterUtil.length(" + argName + ")]") + after;
146 | }
147 | return ret + "(" + argName + after;
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportablePrimitiveType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
4 |
5 | /**
6 | *
7 | */
8 | public class JExportablePrimitiveType implements JExportableType {
9 |
10 | private ExportableTypeOracle exportableTypeOracle;
11 |
12 | private JPrimitiveType primitive;
13 |
14 | public JExportablePrimitiveType(ExportableTypeOracle exportableTypeOracle,
15 | JPrimitiveType primitive) {
16 | this.exportableTypeOracle = exportableTypeOracle;
17 | this.primitive = primitive;
18 | }
19 |
20 | public boolean needsExport() {
21 | return false;
22 | }
23 |
24 | public String getQualifiedSourceName() {
25 | return primitive.getQualifiedSourceName();
26 | }
27 |
28 | public String getHostedModeJsTypeCast() {
29 | return primitive.getSimpleSourceName().equals("Boolean") ? "Boolean"
30 | : "Number";
31 | }
32 |
33 | public String getWrapperFunc() {
34 | return null;
35 | }
36 |
37 | public String getJsTypeOf() {
38 | JPrimitiveType prim = primitive.isPrimitive();
39 | return prim == JPrimitiveType.BOOLEAN ? "boolean" : "number";
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JExportableType.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | /**
4 | * Represents types that might be exported.
5 | */
6 | public interface JExportableType {
7 |
8 | /**
9 | * True if this type needs export to work in Javascript.
10 | */
11 | boolean needsExport();
12 | /*
13 | * The Java qualified name of this type.
14 | */
15 | String getQualifiedSourceName();
16 |
17 | /**
18 | * The name of a JS type cast operation that may be required to debox
19 | * Java values for Javascript in hosted mode.
20 | */
21 | String getHostedModeJsTypeCast();
22 |
23 | String getJsTypeOf();
24 |
25 | String getWrapperFunc();
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/JStructuralTypeField.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | import com.google.gwt.core.ext.typeinfo.JMethod;
4 | import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
5 |
6 | import org.timepedia.exporter.client.SType;
7 |
8 | /**
9 | * Represents a bean property or method which is a structural type field.
10 | */
11 | public class JStructuralTypeField {
12 |
13 | private JExportableClassType exportableClassType;
14 |
15 | private JMethod setterMethod;
16 |
17 | public JStructuralTypeField(JExportableClassType exportableClassType,
18 | JMethod setterMethod) {
19 |
20 | this.exportableClassType = exportableClassType;
21 | this.setterMethod = setterMethod;
22 | }
23 |
24 | public String JavaDeclaration() {
25 | return setterMethod.getReturnType().getQualifiedSourceName() + " "
26 | + setterMethod.getName() + "("
27 | + setterMethod.getParameters()[0].getType().getQualifiedSourceName()
28 | + " arg)";
29 | }
30 |
31 | public boolean isVoidReturn() {
32 | return setterMethod.getReturnType().equals(JPrimitiveType.VOID);
33 | }
34 |
35 | public String getMethodName() {
36 | return setterMethod.getName();
37 | }
38 |
39 | public String getReturnType() {
40 | return setterMethod.getReturnType().getQualifiedSourceName();
41 | }
42 |
43 | public String getFieldValueCast() {
44 | return setterMethod.getParameters()[0].getType().isPrimitive() != null ?
45 | "(double)": "(Object)";
46 | }
47 | public String getFieldJSNIType() {
48 | return setterMethod.getParameters()[0].getType().isPrimitive() != null ?
49 | "D" : "Ljava/lang/Object;";
50 | }
51 |
52 | public String getName() {
53 | SType st = setterMethod.getAnnotation(SType.class);
54 | if(st != null) {
55 | return st.value();
56 | }
57 | return beanize(setterMethod.getName());
58 | }
59 |
60 | private String beanize(String name) {
61 | String prop = name.startsWith("set") ? name.substring(3) : name;
62 | return Character.toLowerCase(prop.charAt(0))+prop.substring(1);
63 | }
64 |
65 | public String getFieldLowestType() {
66 | JPrimitiveType type = setterMethod.getParameters()[0].getType()
67 | .isPrimitive();
68 | return type != null ? type.getQualifiedSourceName() : "Object";
69 | }
70 |
71 | public String getFieldType() {
72 | return setterMethod.getParameters()[0].getType().getQualifiedSourceName();
73 | }
74 |
75 | public JExportableType getExportableType() {
76 | return exportableClassType.getExportableTypeOracle().findExportableType(getFieldType());
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/core/src/main/java/org/timepedia/exporter/rebind/Property.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.rebind;
2 |
3 | public class Property {
4 |
5 | private String name;
6 | private JExportableMethod getter;
7 | private JExportableMethod setter;
8 |
9 | public Property(String name) {
10 | this.name = name;
11 | }
12 |
13 | public void setGetter(JExportableMethod getter) {
14 | this.getter = getter;
15 | }
16 |
17 | public void setSetter(JExportableMethod setter) {
18 | this.setter = setter;
19 | }
20 |
21 | public String getName() {
22 | return name;
23 | }
24 |
25 | public JExportableMethod getGetter() {
26 | return getter;
27 | }
28 |
29 | public JExportableMethod getSetter() {
30 | return setter;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/Test.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/ExporterGwtSuiteTest.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test;
2 |
3 | import junit.framework.Test;
4 |
5 | import org.timepedia.exporter.test.issues.*;
6 |
7 | import com.google.gwt.junit.tools.GWTTestSuite;
8 | public class ExporterGwtSuiteTest extends GWTTestSuite
9 | {
10 | public static Test suite()
11 | {
12 | GWTTestSuite suite = new GWTTestSuite( "Exporter Suite" );
13 | suite.addTestSuite(CoreTestGwt.class );
14 | suite.addTestSuite(Issue25aTestGwt.class);
15 | suite.addTestSuite(Issue25bTestGwt.class);
16 | suite.addTestSuite(Issue33TestGwt.class);
17 | suite.addTestSuite(Issue34TestGwt.class);
18 | suite.addTestSuite(Issue35TestGwt.class);
19 | suite.addTestSuite(Issue38TestGwt.class);
20 | suite.addTestSuite(Issue44TestGwt.class);
21 | suite.addTestSuite(Issue48TestGwt.class);
22 | suite.addTestSuite(Issue49TestGwt.class);
23 | suite.addTestSuite(Issue50TestGwt.class);
24 | suite.addTestSuite(Issue51TestGwt.class);
25 | return suite;
26 | }
27 | }
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue25aTestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import com.google.gwt.core.client.GWT;
4 | import com.google.gwt.junit.client.GWTTestCase;
5 |
6 | public class Issue25aTestGwt extends GWTTestCase{
7 |
8 | @Override
9 | public String getModuleName() {
10 | return "org.timepedia.exporter.Test";
11 | }
12 |
13 | @Override
14 | protected void gwtSetUp() throws Exception {
15 | GWT.create(MyExportable.class);
16 | }
17 |
18 | public native String evalJsTest(String jsCode) /*-{
19 | try {
20 | return eval(jsCode);
21 | } catch(e) {
22 | return String(e);
23 | }
24 | }-*/;
25 |
26 | public void test1() {
27 | String jsCode = "var v1 = new $wnd.gwt.MyExportable(); String(v1.getId());";
28 | assertEquals("no-id", evalJsTest(jsCode));
29 | }
30 |
31 | public void test2() {
32 | String jsCode = "var v1 = new $wnd.gwt.MyExportable('mid'); String(v1.getId());";
33 | assertEquals("mid", evalJsTest(jsCode));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue25bTestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import com.google.gwt.core.client.GWT;
4 | import com.google.gwt.junit.client.GWTTestCase;
5 |
6 | public class Issue25bTestGwt extends GWTTestCase{
7 |
8 | @Override
9 | public String getModuleName() {
10 | return "org.timepedia.exporter.Test";
11 | }
12 |
13 | @Override
14 | protected void gwtSetUp() throws Exception {
15 | GWT.create(MyExportable.class);
16 | }
17 |
18 | public native String evalJsTest(String jsCode) /*-{
19 | try {
20 | return eval(jsCode);
21 | } catch(e) {
22 | return String(e);
23 | }
24 | }-*/;
25 |
26 | public void test1() {
27 | String jsCode = "var v1 = new $wnd.gwt.MyExportable(); String(v1.getId());";
28 | assertEquals("no-id", evalJsTest(jsCode));
29 | }
30 |
31 | public void test2() {
32 | String jsCode = "var v1 = new $wnd.gwt.MyExportable('mid'); String(v1.getId());";
33 | assertEquals("mid", evalJsTest(jsCode));
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue33TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 |
7 | import com.google.gwt.core.client.GWT;
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue33TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | @Override
18 | protected void gwtSetUp() throws Exception {
19 | GWT.create(EvenMoreSpecificType.class);
20 | GWT.create(FurtherSubClass.class);
21 | }
22 |
23 | @ExportPackage("tst")
24 | @Export
25 | public static class Test implements Exportable {
26 | public int[] method(int i) {
27 | return new int[]{1};
28 | }
29 |
30 | public int[] method(String s) {
31 | return new int[]{1};
32 | }
33 | }
34 |
35 | public static class SomeType {
36 | public String getType() {
37 | return "type";
38 | }
39 | }
40 |
41 | public static class SomeMoreSpecificType extends SomeType {
42 | }
43 |
44 | @ExportPackage("tst")
45 | @Export(value="EvenMoreSpecificType", all = true)
46 | public static class EvenMoreSpecificType extends SomeMoreSpecificType
47 | implements Exportable {
48 | }
49 |
50 | public static abstract class SuperClass {
51 | public String doSomething(T t) {
52 | return t.getType();
53 | }
54 | }
55 |
56 | public static abstract class SubClass extends
57 | SuperClass {
58 | @Override
59 | public String doSomething(SomeMoreSpecificType t) {
60 | return super.doSomething(t);
61 | }
62 | }
63 |
64 | @ExportPackage("tst")
65 | @Export(value="FurtherSubClass", all = true)
66 | public static class FurtherSubClass extends SubClass
67 | implements Exportable {
68 | @Override
69 | public String doSomething(SomeMoreSpecificType t) {
70 | return super.doSomething(t);
71 | }
72 | }
73 |
74 | public static native String runJs() /*-{
75 | var e = new $wnd.tst.EvenMoreSpecificType();
76 | var v = new $wnd.tst.FurtherSubClass();
77 | return v.doSomething(e);
78 | }-*/;
79 |
80 | public void testIssue() {
81 | assertEquals("type", runJs());
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue34TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 |
7 | import com.google.gwt.core.client.GWT;
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue34TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | @Override
18 | protected void gwtSetUp() throws Exception {
19 | GWT.create(Test.class);
20 | }
21 |
22 | @ExportPackage("tst")
23 | @Export("Test34")
24 | public static class Test implements Exportable {
25 | public int[] method(int i) { return new int[]{1}; }
26 | public int[] method(String s) { return new int[]{2}; }
27 | }
28 |
29 | public static native String runJs() /*-{
30 | var ret = ""
31 | ret += (new $wnd.tst.Test34()).method(1)[0];
32 | ret += '-';
33 | ret += (new $wnd.tst.Test34()).method('')[0];
34 | return ret;
35 | }-*/;
36 |
37 | public void testIssue() {
38 | assertEquals("1-2", runJs());
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue35TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportConstructor;
5 | import org.timepedia.exporter.client.ExportOverlay;
6 | import org.timepedia.exporter.client.ExportPackage;
7 |
8 | import com.google.gwt.core.client.GWT;
9 | import com.google.gwt.junit.client.GWTTestCase;
10 |
11 | public class Issue35TestGwt extends GWTTestCase {
12 |
13 | @Override
14 | public String getModuleName() {
15 | return "org.timepedia.exporter.Test";
16 | }
17 |
18 | @Override
19 | protected void gwtSetUp() throws Exception {
20 | GWT.create(CoordinateOverlay.class);
21 | GWT.create(GeometryOverlay.class);
22 | }
23 |
24 | public static class Coordinate {
25 | int x, y;
26 | public Coordinate() {
27 | }
28 | public Coordinate(int x, int y) {
29 | this.x = x;
30 | this.y = y;
31 | }
32 | public String toString() {
33 | return x + "x" + y;
34 | }
35 | }
36 |
37 | public static class Geometry {
38 | public Geometry() {
39 | }
40 | public Geometry(String geometryType, int srid, int precision) {
41 | }
42 | Coordinate[] coordinates;
43 | public Coordinate[] getCoordinates() {
44 | return coordinates;
45 | }
46 | public void setCoordinates(Coordinate[] coordinates) {
47 | this.coordinates = coordinates;
48 | }
49 | }
50 |
51 | @Export("Coordinate")
52 | @ExportPackage("sp")
53 | public static class CoordinateOverlay implements ExportOverlay {
54 | @ExportConstructor
55 | public static Coordinate constructor(int x, int y) {
56 | return new Coordinate(x, y);
57 | }
58 | public String toString() {
59 | return "";
60 | }
61 | }
62 |
63 | @Export("Geometry")
64 | @ExportPackage("sp")
65 | public static class GeometryOverlay implements ExportOverlay {
66 | @ExportConstructor
67 | public static Geometry constructor(String geometryType, int srid, int precision) {
68 | return new Geometry(geometryType, srid, precision);
69 | }
70 | public Coordinate[] getCoordinates() {
71 | return null;
72 | }
73 | public void setCoordinates(Coordinate[] coordinates) {
74 | }
75 | }
76 |
77 | public static native String runJs() /*-{
78 | var geometry = new $wnd.sp.Geometry("Point", 0, 0);
79 | geometry.setCoordinates([ new $wnd.sp.Coordinate(10, 10), new $wnd.sp.Coordinate(20, 20) ]);
80 | return "" + geometry.getCoordinates();
81 | }-*/;
82 |
83 | public void testIssue() {
84 | assertEquals("10x10,20x20", runJs());
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue38TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.ExporterUtil;
7 |
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue38TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | // Should be exported as pkg.Person1
18 | @ExportPackage("pkg")
19 | @Export(all = true, value = "Person1")
20 | public static class Person implements Exportable {
21 |
22 | // Should be exported as pkg.Person1.Foo
23 | @Export
24 | public static class Foo implements Exportable {
25 | public String bar() {
26 | return "foo-bar,";
27 | }
28 | }
29 |
30 | private String name;
31 | public Person(String name) {
32 | this.name = name;
33 | }
34 | public String method() {
35 | return "Hello: " + name + ",";
36 | }
37 |
38 | /**
39 | * Just an empty method used to test JsDoclet
40 | * @param theName Any string should work
41 | * @return always null.
42 | */
43 | public String method(String theName) {
44 | return null;
45 | }
46 | }
47 |
48 | // Should be exported as pkg.Person2
49 | @ExportPackage("pkg")
50 | @Export(all = true)
51 | public static class Person2 extends Person {
52 | /**
53 | * This comment is here to test JsDoclet
54 | *
55 | * @param name the name of the person
56 | */
57 | public Person2(String name) {
58 | super(name);
59 | }
60 | }
61 |
62 | // Should be exported as org.timepedia.exporter.test.issues.Issue38TestGwt.Person3
63 | @Export(all = true)
64 | public static class Person3 extends Person {
65 | public Person3(String name) {
66 | super(name);
67 | }
68 | }
69 |
70 | public static native String runJs() /*-{
71 | try {
72 | ret = "";
73 | if ($wnd.pkg && $wnd.pkg.Person2) {
74 | ret += new $wnd.pkg.Person1("A").method();
75 | ret += new $wnd.pkg.Person1.Foo().bar();
76 | ret += new $wnd.pkg.Person2("B").method();
77 | ret += new $wnd.org.timepedia.exporter.test.issues.Issue38TestGwt.Person3("C").method();
78 | }
79 | return ret;
80 | } catch(e) {
81 | return("Js Exception : " + e);
82 | }
83 | }-*/;
84 |
85 | public void testIssue() {
86 | // export(false) export classes which are default-instantiable (excluding interfaces, abstract, no-zero-constructor)
87 | ExporterUtil.export(false);
88 | assertEquals("", runJs());
89 |
90 | // exportAll exports all Exportable classes marked with @Export
91 | ExporterUtil.exportAll();
92 | assertEquals("Hello: A,foo-bar,Hello: B,Hello: C,", runJs());
93 | }
94 | }
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue44TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 |
7 | import com.google.gwt.core.client.GWT;
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue44TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | @Override
18 | protected void gwtSetUp() throws Exception {
19 | GWT.create(Impl.class);
20 | GWT.create(ServiceImpl.class);
21 | }
22 |
23 | @ExportPackage("tst")
24 | @Export("Interface")
25 | public interface Interface extends Exportable {
26 | public String method();
27 | }
28 |
29 | @ExportPackage("tst")
30 | @Export("Impl")
31 | public static class Impl implements Interface, Exportable {
32 |
33 | @Override
34 | public String method() {
35 | return "method";
36 | }
37 |
38 | }
39 |
40 | @ExportPackage("tst")
41 | @Export("Service")
42 | public interface Service extends Exportable {
43 |
44 | public String accept(Interface itf);
45 | }
46 |
47 | @ExportPackage("tst")
48 | @Export("ServiceImpl")
49 | public static class ServiceImpl implements Service, Exportable {
50 |
51 | @Override
52 | public String accept(Interface itf) {
53 | return itf.method();
54 | }
55 |
56 | }
57 |
58 | public static native String runJs() /*-{
59 | var service = new $wnd.tst.ServiceImpl();
60 | var ret = "";
61 | ret += service.accept(new $wnd.tst.Impl());
62 | return ret;
63 | }-*/;
64 |
65 | public void testIssue() {
66 | assertEquals("method", runJs());
67 | }
68 | }
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue45TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.ExporterUtil;
7 |
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue45TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | public void test() {
18 | ExporterUtil.exportAll();
19 | publish();
20 | assertEquals("bar,java.lang.ClassCastException,bar,foo", runJs());
21 | }
22 |
23 | @ExportPackage("module")
24 | @Export(value="Chart")
25 | public static class Chart implements Exportable {
26 | String name;
27 | public void setName(String name) {
28 | this.name = name;
29 | }
30 | public String getName() {
31 | return name;
32 | }
33 |
34 | public static Chart create() {
35 | return new Chart();
36 | }
37 | }
38 |
39 | public static class ChartManager implements Exportable {
40 | public static void addChart(Chart chart) {
41 | chart.setName("foo");
42 | }
43 | }
44 |
45 | private static native void publish() /*-{
46 | // Export some Jsni objects without using gwt-exporter
47 | $wnd.ChartManager = {
48 | addChart : function(chrt) { $entry( @org.timepedia.exporter.test.issues.Issue45TestGwt.ChartManager::addChart(*)(chrt)); }
49 | ,newChart : function(){ return @org.timepedia.exporter.test.issues.Issue45TestGwt.Chart::create(); }
50 | ,addChartFailure: function(msg) {$wnd.alert('no implementation err: ' + msg); }
51 | ,addChartSuccess: function(chart) {$wnd.alert('addChartSuccess not implemented'); }
52 | };
53 | }-*/;
54 |
55 | private static native String runJs() /*-{
56 | var ret = "";
57 |
58 | // Create a new Chart exported by gwt-exporter
59 | // actually it is not a gwt object but a js object with
60 | // wraps a reference to the real gwt instance.
61 | var cht = new $wnd.module.Chart();
62 | cht.setName('bar');
63 | ret += cht.getName(); // bar
64 |
65 | // If we pass this gwt-exporter object to a jsni method it should raise
66 | // a cast exception
67 | ret += ","
68 | try {
69 | $wnd.ChartManager.addChart(cht);
70 | } catch(e) {
71 | ret += e; //java.lang.ClassCastException
72 | }
73 | ret += ","
74 | ret += cht.getName(); // bar
75 |
76 | // We have to pass the appropriate gwt instance of the Chart object
77 | // The gwt instance is stored in the .g property of the js exported object.
78 | $wnd.ChartManager.addChart(cht.g);
79 | ret += ","
80 | ret += cht.getName(); // foo
81 |
82 | return ret;
83 | }-*/;
84 | }
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue48TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportClosure;
5 | import org.timepedia.exporter.client.ExportOverlay;
6 | import org.timepedia.exporter.client.ExportPackage;
7 | import org.timepedia.exporter.client.Exportable;
8 | import org.timepedia.exporter.client.ExporterUtil;
9 | import org.timepedia.exporter.client.test.JsTestUtil;
10 |
11 | import com.google.gwt.core.client.JavaScriptObject;
12 | import com.google.gwt.event.shared.EventHandler;
13 | import com.google.gwt.event.shared.SimpleEventBus;
14 | import com.google.gwt.junit.client.GWTTestCase;
15 | import com.google.web.bindery.event.shared.Event;
16 | import com.google.web.bindery.event.shared.EventBus;
17 | import com.google.web.bindery.event.shared.HandlerRegistration;
18 |
19 | public class Issue48TestGwt extends GWTTestCase {
20 |
21 | JsTestUtil jsTest = new JsTestUtil(Issue48TestGwt.class);
22 |
23 | @Override
24 | public String getModuleName() {
25 | return "org.timepedia.exporter.Test";
26 | }
27 |
28 | public void test() {
29 | ExporterUtil.exportAll();
30 | runJsTests(jsTest);
31 | if (jsTest.isFailed()) fail(jsTest.getFailed());
32 | }
33 |
34 | public native JavaScriptObject runJsTests(JsTestUtil jsTest) /*-{
35 | // Utility function to assert equals numbers
36 | var assertEq = function(a, b) {jsTest.@org.timepedia.exporter.client.test.JsTestUtil::assertEqualsNumber(*)(a, b);}
37 |
38 | // We increase this ver each time the handler is called
39 | var i = 0;
40 | var login_handler = function() {i++};
41 |
42 | // Register the handler
43 | var reg_handler = $wnd.My.Handlers.addLoginEventHandler(login_handler);
44 | assertEq(0, i);
45 |
46 | // each call to fireLogin should increment the counter
47 | $wnd.My.Handlers.fireLoginEvent();
48 | assertEq(1, i);
49 |
50 | $wnd.My.Handlers.fireLoginEvent();
51 | assertEq(2, i);
52 |
53 | // We remove the handler from the eventBus, so the counter should not be incremented
54 | reg_handler.removeHandler();
55 |
56 | // The counter should remain the same
57 | $wnd.My.Handlers.fireLoginEvent();
58 | assertEq(2, i);
59 | }-*/;
60 |
61 | @Export
62 | @ExportClosure
63 | @ExportPackage("_internal")
64 | public static interface JsFunction extends Exportable {
65 | public void execute();
66 | }
67 |
68 | @ExportPackage("My")
69 | @Export("Handlers")
70 | public static class HandlersExporter implements Exportable {
71 | private static EventBus eventBus = new SimpleEventBus();
72 |
73 | public static HandlerRegistration addLoginEventHandler(final JsFunction function) {
74 | return eventBus.addHandler(LoginEvent.TYPE, new LogInEventHandler() {
75 | public void onLogIn(LoginEvent event) {
76 | function.execute();
77 | }
78 | });
79 | }
80 |
81 | public static void fireLoginEvent() {
82 | eventBus.fireEvent(new LoginEvent());
83 | }
84 | }
85 |
86 | @Export
87 | @ExportPackage("_internal")
88 | public interface JsHandlerRegistration extends ExportOverlay {
89 | void removeHandler();
90 | }
91 |
92 | public interface LogInEventHandler extends EventHandler {
93 | void onLogIn(LoginEvent event);
94 | }
95 |
96 | public static class LoginEvent extends Event {
97 | public static final Type TYPE = new Type();
98 |
99 | public Type getAssociatedType() {
100 | return TYPE;
101 | }
102 |
103 | protected void dispatch(LogInEventHandler handler) {
104 | handler.onLogIn(null);
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue49TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.ExporterUtil;
7 |
8 | import com.google.gwt.junit.client.GWTTestCase;
9 |
10 | public class Issue49TestGwt extends GWTTestCase {
11 |
12 | @Override
13 | public String getModuleName() {
14 | return "org.timepedia.exporter.Test";
15 | }
16 |
17 | @Override
18 | protected void gwtSetUp() throws Exception {
19 | ExporterUtil.exportAll();
20 | }
21 |
22 | @Export
23 | public interface ObjectInterface extends Exportable {
24 | public String method();
25 | }
26 |
27 | @ExportPackage("tst")
28 | @Export("ObjectFactory")
29 | public static class ObjectFactory implements Exportable {
30 | public ObjectInterface create() {
31 | return new ObjectImpl();
32 | }
33 | }
34 |
35 | @ExportPackage("tst")
36 | @Export("ObjectUser")
37 | public static class ObjectUser implements Exportable {
38 | public String executeMethod(ObjectInterface object) {
39 | return object.method();
40 | }
41 | }
42 |
43 | public static class ObjectImpl implements ObjectInterface, Exportable {
44 | @Override
45 | public String method() {
46 | return "object";
47 | }
48 | }
49 |
50 | public static native String runJs() /*-{
51 | var factory = new $wnd.tst.ObjectFactory();
52 | var ret = "";
53 | var object = factory.create();
54 | var objectUser = new $wnd.tst.ObjectUser();
55 | ret += objectUser.executeMethod(object);
56 | return ret;
57 | }-*/;
58 |
59 | public void testIssue() {
60 | assertEquals("object", runJs());
61 | }
62 | }
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue50TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.Getter;
7 | import org.timepedia.exporter.client.Setter;
8 |
9 | import com.google.gwt.core.client.GWT;
10 | import com.google.gwt.junit.client.GWTTestCase;
11 |
12 | public class Issue50TestGwt extends GWTTestCase {
13 |
14 | @Override public String getModuleName() {
15 | return "org.timepedia.exporter.Test";
16 | }
17 |
18 | @Override protected void gwtSetUp() throws Exception {
19 | GWT.create(Test.class);
20 | }
21 |
22 | @ExportPackage("tst")
23 | @Export("Test50")
24 | public static class Test implements Exportable {
25 | private String name = "";
26 |
27 | @Getter public String getName() {
28 | return name;
29 | }
30 | @Setter public void setName(String s) {
31 | this.name = s + "-exporter";
32 | }
33 | }
34 |
35 | public static native String runJs() /*-{
36 | var obj = new $wnd.tst.Test50();
37 | obj.name = "gwt";
38 | return obj.name;
39 | }-*/;
40 |
41 | public void testIssue() {
42 | assertEquals("gwt-exporter", runJs());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/Issue51TestGwt.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.Getter;
7 | import org.timepedia.exporter.client.Setter;
8 |
9 | import com.google.gwt.core.client.GWT;
10 | import com.google.gwt.junit.client.GWTTestCase;
11 |
12 | public class Issue51TestGwt extends GWTTestCase {
13 |
14 | @Override public String getModuleName() {
15 | return "org.timepedia.exporter.Test";
16 | }
17 |
18 | @Override protected void gwtSetUp() throws Exception {
19 | GWT.create(Test.class);
20 | }
21 |
22 | /**
23 | * An external interface that can't be Exportable by itself
24 | */
25 | public static interface ExternalInterface {
26 | public static final String MY_CONSTANT = "MY_CONSTANT";
27 |
28 | public String getName();
29 | public void setName(String s);
30 | }
31 |
32 | /**
33 | * A marker interface that extends the external interface an implements the Exportable to let the
34 | * system know that it does need to export all fields of this interface and the ones it extend.
35 | */
36 | public static interface MyInternalInterface extends ExternalInterface, Exportable {
37 |
38 | }
39 |
40 | @ExportPackage("tst")
41 | @Export("Test51")
42 | public static class Test implements MyInternalInterface {
43 | private String name = "";
44 | public String getName() {
45 | return name;
46 | }
47 | public void setName(String s) {
48 | this.name = s + "-exporter";
49 | }
50 | }
51 |
52 | public static native String runJs() /*-{
53 | var obj = new $wnd.tst.Test51();
54 | obj.setName($wnd.tst.Test51.MY_CONSTANT);
55 | return obj.getName();
56 | }-*/;
57 |
58 | public void testIssue() {
59 | assertEquals("MY_CONSTANT-exporter", runJs());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/core/src/test/java/org/timepedia/exporter/test/issues/MyExportable.java:
--------------------------------------------------------------------------------
1 | package org.timepedia.exporter.test.issues;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 |
7 | @ExportPackage("gwt")
8 | @Export
9 | public class MyExportable implements Exportable {
10 |
11 | String n = "no-id";
12 |
13 | public MyExportable() {
14 | }
15 |
16 | public MyExportable(String id) {
17 | n = id;
18 | }
19 |
20 | public String getId() {
21 | return n;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/samples/export-widgets/README.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | This is the project ExportWidget which uses GwtQuery and GwtExporter libraries.
4 |
5 | It tries to show how to look for widgets from js and how to use methods in
6 | those found widgets.
7 |
8 | - Assuming you have installed maven, compile and install it just running:
9 | $ mvn clean install
10 |
11 | - Run it in development mode:
12 | $ mvn gwt:run
13 |
14 | - Import and run in Eclipse:
15 |
16 | The archetype generates a project ready to be used in eclipse,
17 | but before importing it you have to install the following plugins:
18 |
19 | * Google plugin for eclipse (update-site: http://dl.google.com/eclipse/plugin/3.7 or 3.6 or 3.5)
20 | * Sonatype Maven plugin (update-site: http://m2eclipse.sonatype.org/site/m2e)
21 |
22 | Then you can import the project in your eclipse workspace:
23 |
24 | * File -> Import -> Existing Projects into Workspace
25 |
26 | Finally you should be able to run the project in development mode and to run the gwt test unit.
27 |
28 | * Right click on the project -> Run as -> Web Application
29 | * Right click on the test class -> Run as -> GWT JUnit Test
30 |
31 | - Although the project has the files .classpath and .project, you could generate them running any
32 | of the following commands:
33 |
34 | $ mvn eclipse:m2eclipse (if you like to use m2eclipse)
35 | $ mvn eclipse:eclipse (to use the project without m2eclipse)
36 |
--------------------------------------------------------------------------------
/samples/export-widgets/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | ExportWidget gwtquery project
6 | org.gquery
7 | ewidget
8 | war
9 | 1.0-SNAPSHOT
10 |
11 |
12 | UTF-8
13 | 1.6
14 | 1.6
15 | 1.3.1
16 | 2.5.0-SNAPSHOT
17 | 2.5.1-rc1
18 | 2.5.1-rc1
19 |
20 |
21 |
22 |
23 | central
24 | http://repo1.maven.org/maven2
25 |
26 |
27 | gwtquery-plugins
28 | http://gwtquery-plugins.googlecode.com/svn/mavenrepo
29 |
30 |
31 | sonatype
32 | http://oss.sonatype.org/content/repositories/snapshots
33 | true
34 | false
35 |
36 |
37 | m.g.o
38 | http://maven.glassfish.org/content/groups/public/
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | junit
51 | junit
52 | 3.8.1
53 | test
54 |
55 |
56 | com.google.gwt
57 | gwt-user
58 | ${gwtversion}
59 | provided
60 |
61 |
62 | com.google.gwt
63 | gwt-dev
64 | ${gwtversion}
65 | provided
66 |
67 |
68 | com.google.gwt
69 | gwt-servlet
70 | ${gwtversion}
71 | runtime
72 |
73 |
74 | com.googlecode.gwtquery
75 | gwtquery
76 | ${gQueryVersion}
77 | provided
78 |
79 |
80 | org.timepedia.exporter
81 | gwtexporter
82 | ${gExporterVersion}
83 | provided
84 |
85 |
86 |
87 | javax.validation
88 | validation-api
89 | 1.0.0.GA
90 |
91 |
92 | javax.validation
93 | validation-api
94 | 1.0.0.GA
95 | sources
96 |
97 |
98 |
99 |
100 |
101 | org.apache.maven.plugins
102 | maven-compiler-plugin
103 | 2.1
104 |
105 | 1.6
106 | 1.6
107 |
108 |
109 |
110 | org.codehaus.mojo
111 | gwt-maven-plugin
112 | ${gwtmaven}
113 |
114 | ${gwt.loglevel}
115 |
116 | ${gwtversion}
117 | true
118 | ExportWidget/ExportWidget.html
119 | ${project.build.directory}/${project.build.finalName}
120 |
121 |
122 |
123 | prepare-package
124 |
125 | compile
126 |
127 |
128 |
129 |
130 |
131 | maven-surefire-plugin
132 | 2.8.1
133 |
134 |
135 | \${project.build.sourceDirectory}
136 | \${project.build.testSourceDirectory}
137 |
138 | false
139 | always
140 |
141 |
142 | gwt.args
143 | -out target/gwt-tests
144 |
145 |
146 |
147 | gwt.persistentunitcache
148 | false
149 |
150 |
151 |
152 |
153 |
154 | org.apache.maven.plugins
155 | maven-eclipse-plugin
156 | 2.7
157 |
158 | true
159 | false
160 |
161 | com.google.gwt.eclipse.core.gwtProjectValidator
162 | org.eclipse.wst.common.modulecore.ComponentStructuralBuilder
163 | org.eclipse.jdt.core.javabuilder
164 | org.eclipse.wst.common.modulecore.ComponentStructuralBuilderDependencyResolver
165 |
166 |
167 | com.google.gwt.eclipse.core.gwtNature
168 | org.eclipse.jdt.core.javanature
169 | org.eclipse.wst.common.modulecore.ModuleCoreNature
170 |
171 |
172 | com.google.gwt.eclipse.core.GWT_CONTAINER
173 | org.eclipse.jdt.launching.JRE_CONTAINER
174 | org.eclipse.jdt.junit.JUNIT_CONTAINER/3
175 |
176 |
177 |
178 |
179 |
180 | maven-resources-plugin
181 | 2.5
182 |
183 |
184 | copy-resources
185 | generate-sources
186 |
187 | copy-resources
188 |
189 |
190 | ${project.build.directory}/${project.build.finalName}
191 |
192 |
193 | src/main/webapp
194 | true
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
203 |
204 |
205 |
--------------------------------------------------------------------------------
/samples/export-widgets/src/main/java/org/gquery/ewidget/ExportWidget.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/samples/export-widgets/src/main/java/org/gquery/ewidget/client/ExportWidget.java:
--------------------------------------------------------------------------------
1 | package org.gquery.ewidget.client;
2 | import static com.google.gwt.query.client.GQuery.$;
3 |
4 | import org.timepedia.exporter.client.Export;
5 | import org.timepedia.exporter.client.ExportOverlay;
6 | import org.timepedia.exporter.client.ExportPackage;
7 | import org.timepedia.exporter.client.Exportable;
8 | import org.timepedia.exporter.client.ExporterUtil;
9 |
10 | import com.google.gwt.core.client.EntryPoint;
11 | import com.google.gwt.event.dom.client.ClickEvent;
12 | import com.google.gwt.event.dom.client.ClickHandler;
13 | import com.google.gwt.user.client.ui.Button;
14 | import com.google.gwt.user.client.ui.Label;
15 | import com.google.gwt.user.client.ui.RootPanel;
16 | import com.google.gwt.user.client.ui.Widget;
17 |
18 | /**
19 | * App example to show how to mix gquery and gwtexporter
20 | *
21 | * After compiling this app and loading in your html document,
22 | * you can call exported methods from javascript:
23 |
24 | label = js.getLabel(".gwt-Label");
25 | label.setText("Hi");
26 |
27 | widget = js.getWidget(".gwt-Label");
28 | label = new js.Label(widget);
29 | label.setText("Bye");
30 |
31 | button = js.getButtons("*")[0];
32 | button.click();
33 |
34 | widget = js.getWidget(".gwt-Button");
35 | button = new js.Button(widget);
36 | button.click();
37 |
38 | */
39 | public class ExportWidget implements EntryPoint {
40 |
41 | public void onModuleLoad() {
42 | ExporterUtil.exportAll();
43 |
44 | final Label label = new Label("Hello world");
45 | final Button button = new Button("Click me", new ClickHandler() {
46 | public void onClick(ClickEvent event) {
47 | $(label)
48 | .animate("fontSize: '+=10px', color:'blue'")
49 | .delay(1000)
50 | .animate("fontSize: '-=10px', color: 'black'");
51 | }
52 | });
53 |
54 | RootPanel.get().add(label);
55 | RootPanel.get().add(button);
56 | }
57 |
58 | /**
59 | * We use a class to expose some static methods which
60 | * will return the widgets we want calling to gquery.
61 | */
62 | @ExportPackage("")
63 | @Export("js")
64 | public static class Exposer implements Exportable {
65 | public static Label getLabel(String selector) {
66 | return $(selector).widgets(Label.class).get(0);
67 | }
68 |
69 | public static Button[] getButtons(String selector) {
70 | return $(selector).widgets(Button.class).toArray(new Button[0]);
71 | }
72 |
73 | public static Widget getWidget(String selector) {
74 | return $(selector).widget();
75 | }
76 |
77 | public static Widget[] getWidgets(String selector) {
78 | return $(selector).widgets().toArray(new Widget[0]);
79 | }
80 | }
81 |
82 | /**
83 | * We export the widgets we want to use so as we can
84 | * access their instance methods.
85 | *
86 | * We can use either interfaces or abstract classes.
87 | */
88 | @ExportPackage("js")
89 | @Export
90 | public static abstract class LabelOverLay implements ExportOverlay {
91 | public abstract String getText();
92 | public abstract void setText(String s);
93 | }
94 |
95 | @ExportPackage("js")
96 | @Export
97 | public static interface ButtonOverLay extends ExportOverlay {
98 | void setText(String s);
99 | void click();
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/samples/export-widgets/src/main/java/org/gquery/ewidget/public/ExportWidget.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | GwtQuery: ExportWidget plugin example
6 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/samples/export-widgets/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ExportWidget/ExportWidget.html
4 |
5 |
6 |
--------------------------------------------------------------------------------
/samples/export-widgets/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 | Loading the demo of the ExportWidget gwtquery application
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/samples/exporterdemo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | org.timepedia.exporter
5 | gwtexporter-exporterdemo
6 | war
7 | 2.5.0-SNAPSHOT
8 |
9 |
10 | ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
11 |
12 |
13 | org.codehaus.mojo
14 | gwt-maven-plugin
15 | ${gwtmaven}
16 |
17 | ${gwt.loglevel}
18 |
19 | ${gwt.target}
20 | ${project.build.directory}/www
21 | ${gwt.draft}
22 | ${gwt.xdisable}
23 | ${gwt.xdisable}
24 | ${gwt.soyc}
25 | ${gwt.workers}
26 | -Xmx256m
27 | ${gwt.inplace}
28 |
29 | exporterdemo.ExporterDemo
30 |
31 |
32 |
33 |
34 | prepare-package
35 |
36 | compile
37 |
38 |
39 |
40 |
41 |
42 | org.apache.maven.plugins
43 | maven-compiler-plugin
44 |
45 | 1.6
46 | 1.6
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-eclipse-plugin
52 |
53 | true
54 | false
55 |
56 |
57 | com.google.gwt.eclipse.core.gwtProjectValidator
58 |
59 |
60 |
61 | com.google.gwt.eclipse.core.gwtNature
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | repo1
71 | http://repo1.maven.org/maven2/
72 |
73 |
74 | maven2-repository.dev.java.net
75 | Repository for wagon svn
76 | http://download.java.net/maven/2/
77 |
78 |
79 | sonatype-snapshot
80 | http://oss.sonatype.org/content/repositories/snapshots
81 | true
82 | false
83 |
84 |
85 | timepedia
86 | http://gwt-chronoscope.googlecode.com/svn/mavenrepo/
87 |
88 |
89 | timefire
90 | http://timefire-repository.googlecode.com/svn/mavenrepo/
91 |
92 |
93 |
94 |
95 | UTF-8
96 | 2.5.1-rc1
97 | 2.5.1-rc1
98 | INFO
99 | PRETTY
100 |
101 | false
102 | false
103 | true
104 | true
105 | false
106 |
107 | index.html
108 |
109 |
110 |
111 |
112 |
113 |
114 | bind
115 |
116 | INFO' -bindAddress '0.0.0.0
117 |
118 |
119 |
120 | pretty
121 |
122 | PRETTY
123 |
124 |
125 |
126 |
127 |
128 |
129 | junit
130 | junit
131 | 3.8.1
132 | test
133 |
134 |
135 | org.timepedia.exporter
136 | gwtexporter
137 | ${version}
138 | provided
139 |
140 |
141 | com.google.gwt
142 | gwt-user
143 | ${gwtversion}
144 | provided
145 |
146 |
147 | com.google.gwt
148 | gwt-dev
149 | ${gwtversion}
150 | test
151 |
152 |
153 |
154 | com.sun
155 | tools
156 | 1.6
157 | system
158 | true
159 | ${java.home}/../lib/tools.jar
160 |
161 |
162 |
163 | javax.validation
164 | validation-api
165 | 1.0.0.GA
166 | provided
167 |
168 |
169 | javax.validation
170 | validation-api
171 | 1.0.0.GA
172 | sources
173 | provided
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/ExporterDemo.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/Employee.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportPackage;
5 | import org.timepedia.exporter.client.Exportable;
6 | import org.timepedia.exporter.client.NoExport;
7 |
8 | /**
9 | * Blacklist export policy. All public methods exported by default
10 | *
11 | * @author Ray Cromwell <ray@timepedia.org>
12 | */
13 | @Export
14 | @ExportPackage("test")
15 | public class Employee extends Person implements Exportable {
16 |
17 | public Employee(String firstName, String lastName) {
18 | super(firstName, lastName);
19 | }
20 |
21 | private String title;
22 |
23 | private int gender;
24 |
25 | private MyClickListener listener;
26 |
27 | public static final int MALE = 0, FEMALE = 1;
28 |
29 | public String getTitle() {
30 | return title;
31 | }
32 |
33 | public void setTitle(String title) {
34 | this.title = title;
35 | }
36 |
37 | public Employee() {
38 | }
39 |
40 | public Employee(String title, String firstName, String lastName, int gender) {
41 | super(firstName, lastName);
42 | this.title = title;
43 | this.gender = gender;
44 | people = new Person[2];
45 | people[0] = new Person("John", "McCain");
46 | people[1] = new Person("Barack", "Obama");
47 | arr = new String[]{"McCain", "Obama"};
48 | }
49 |
50 | public Employee(Employee old) {
51 | super(old.getFirstName(), old.getLastName());
52 | this.title = old.getTitle();
53 | this.gender = old.getGender();
54 | }
55 |
56 | /**
57 | * let's stop this one from being exported
58 | */
59 | @NoExport
60 | public String fullTitle() {
61 | return title + " " + super.fullTitle();
62 | }
63 |
64 | // should not be exported
65 | private String getBlah() {
66 | return "blah";
67 | }
68 |
69 | public int getGender() {
70 | return gender;
71 | }
72 |
73 | public static String sayHello(Person emp) {
74 | return "Hello " + emp.fullTitle();
75 | }
76 |
77 | public String overriden(String x) {
78 | return x + ".";
79 | }
80 |
81 | public double overriden(double x) {
82 | return x + 1;
83 | }
84 |
85 | public Employee overriden(Employee that) {
86 | return that;
87 | }
88 |
89 | /**
90 | * demonstrate how to avoid overload conflicts
91 | */
92 | @Export("sayHelloString")
93 | public static String sayHello(String foo) {
94 | return "Hello " + foo;
95 | }
96 |
97 | /**
98 | */
99 | @Export("addListener")
100 | public String addClickListener(MyClickListener listener) {
101 | this.listener = listener;
102 | return null;
103 | }
104 |
105 | /**
106 | */
107 | @Export("fire")
108 | public void fireClickListener() {
109 | if (listener != null) {
110 | listener.onClick(this, "Hello", gender);
111 | }
112 | }
113 |
114 | /**
115 | */
116 | @Export
117 | public InnerTest getInnerTest() {
118 | return new InnerTest();
119 | }
120 |
121 | /**
122 | */
123 | @Export
124 | public static class InnerTest implements Exportable {
125 |
126 | public InnerTest() {
127 | }
128 |
129 | public int getFoo() {
130 | return 10;
131 | }
132 | }
133 |
134 | String[] arr;
135 |
136 | @Export
137 | public String[] getStrArry() {
138 | return arr;
139 | }
140 |
141 | double values[] = new double[]{1, 2, 3, 4, 5};
142 |
143 | @Export
144 | public double[] getValues() {
145 | return values;
146 | }
147 |
148 | Person[] people;
149 |
150 | @Export
151 | public Person[] getPeople() {
152 | return people;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/ExportManager.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportOverlay;
5 | import org.timepedia.exporter.client.ExportPackage;
6 |
7 | /**
8 | *
9 | */
10 | @ExportPackage("sample")
11 | public interface ExportManager extends ExportOverlay {
12 |
13 | @Export("getEmp")
14 | Employee getEmployee();
15 |
16 | @Export
17 | String getManagerEmployeeTitle(Manager m);
18 |
19 | @Export
20 | Manager getSelf();
21 | }
22 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/ExporterDemo.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | import org.timepedia.exporter.client.ExporterUtil;
4 |
5 | import com.google.gwt.core.client.EntryPoint;
6 | import com.google.gwt.user.client.Window;
7 |
8 | /**
9 | * Entry point classes define onModuleLoad()
.
10 | */
11 | public class ExporterDemo implements EntryPoint {
12 |
13 | /**
14 | * This is the entry point method.
15 | */
16 | public void onModuleLoad() {
17 |
18 | try {
19 | ExporterUtil.exportAll();
20 | } catch (Exception e) {
21 | Window.alert("Exception " + e.toString());
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/Manager.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | /**
4 | * Non-exportable class
5 | */
6 | public class Manager {
7 |
8 | private Employee employee;
9 |
10 | public Manager(Employee employee) {
11 |
12 | this.employee = employee;
13 | }
14 |
15 | public Manager() {
16 | }
17 |
18 | public Employee getEmployee() {
19 | return employee;
20 | }
21 |
22 | public String getManagerEmployeeTitle(Manager m) {
23 | return m.getEmployee().getTitle();
24 | }
25 |
26 | public Manager getSelf() {
27 | return this;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/MyClickListener.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.ExportClosure;
5 | import org.timepedia.exporter.client.ExportPackage;
6 | import org.timepedia.exporter.client.Exportable;
7 |
8 | /**
9 | * Example of closure exporting, gwt.export says export the class methods, and
10 | * gwt.exportClosure says auto-generate the makeClosure() method and closure
11 | * handling code for any methods which take this interface as a parameter
12 | *
13 | * @author Ray Cromwell <ray@timepedia.org>
14 | */
15 | @Export
16 | @ExportPackage("test")
17 | @ExportClosure
18 | public interface MyClickListener extends Exportable {
19 |
20 | /**
21 | * the call back
22 | */
23 | @Export
24 | public String onClick(Employee emp, String foo, int num);
25 | }
26 |
27 |
28 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/client/Person.java:
--------------------------------------------------------------------------------
1 | package exporterdemo.client;
2 |
3 | import org.timepedia.exporter.client.Export;
4 | import org.timepedia.exporter.client.Exportable;
5 | import org.timepedia.exporter.client.StructuralType;
6 |
7 | /**
8 | * Whitelist demo, manually export
9 | *
10 | * @author Ray Cromwell <ray@timepedia.org>
11 | */
12 | @StructuralType
13 | public class Person implements Exportable {
14 |
15 | private String firstName;
16 |
17 | private String lastName;
18 |
19 | // @Export
20 | // public enum TestEnum implements Exportable {
21 | //
22 | // @Export INSTANCE {
23 | // Employee getSomeClass() {
24 | // return some;
25 | // }
26 | // };
27 | // public Employee some;
28 | // @Export
29 | // abstract Employee getSomeClass();
30 | // }
31 | /**
32 | */
33 | @Export
34 | public Person(String firstName, String lastName) {
35 | this.firstName = firstName;
36 | this.lastName = lastName;
37 | }
38 |
39 | public Person() {
40 | }
41 |
42 | /**
43 | */
44 | @Export
45 | public String getLastName() {
46 | return lastName;
47 | }
48 |
49 | /**
50 | */
51 | @Export
52 | public void setLastName(String lastName) {
53 | this.lastName = lastName;
54 | }
55 |
56 | /**
57 | */
58 | @Export
59 | public String getFirstName() {
60 | return firstName;
61 | }
62 |
63 | /**
64 | */
65 | @Export
66 | public void setFirstName(String firstName) {
67 | this.firstName = firstName;
68 | }
69 |
70 | /**
71 | */
72 | @Export
73 | public String fullTitle() {
74 | return firstName + " " + lastName;
75 | }
76 |
77 | /**
78 | */
79 | @Export
80 | public Person getSelf() {
81 | return this;
82 | }
83 |
84 | @Export
85 | public static Person salute(String name) {
86 | return new Person();
87 | }
88 |
89 | @Export
90 | public static String salute(int x) {
91 | return "Hello " + x;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/java/exporterdemo/public/ExporterDemo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | ExporterDemo
4 |
5 |
6 |
27 |
28 |
30 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
90 |
91 | ExporterDemo
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/exporterdemo/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/samples/testdemo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | org.timepedia.exporter
5 | gwtexporter-testdemo
6 | war
7 | 2.5.0-SNAPSHOT
8 |
9 |
10 | ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
11 |
12 |
13 | org.codehaus.mojo
14 | gwt-maven-plugin
15 | ${gwtmaven}
16 |
17 | ${gwt.loglevel}
18 |
19 | ${gwt.target}
20 | ${project.build.directory}/www
21 | ${gwt.draft}
22 | ${gwt.xdisable}
23 | ${gwt.xdisable}
24 | ${gwt.soyc}
25 | ${gwt.workers}
26 | -Xmx256m
27 | ${gwt.inplace}
28 |
29 | testdemo.TestDemo
30 |
31 |
32 |
33 |
34 | prepare-package
35 |
36 | compile
37 |
38 |
39 |
40 |
41 |
42 | org.apache.maven.plugins
43 | maven-compiler-plugin
44 |
45 | 1.6
46 | 1.6
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-eclipse-plugin
52 |
53 | true
54 | false
55 |
56 |
57 | com.google.gwt.eclipse.core.gwtProjectValidator
58 |
59 |
60 |
61 | com.google.gwt.eclipse.core.gwtNature
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | repo1
71 | http://repo1.maven.org/maven2/
72 |
73 |
74 | maven2-repository.dev.java.net
75 | Repository for wagon svn
76 | http://download.java.net/maven/2/
77 |
78 |
79 | sonatype-snapshot
80 | http://oss.sonatype.org/content/repositories/snapshots
81 | true
82 | false
83 |
84 |
85 | timepedia
86 | http://gwt-chronoscope.googlecode.com/svn/mavenrepo/
87 |
88 |
89 | timefire
90 | http://timefire-repository.googlecode.com/svn/mavenrepo/
91 |
92 |
93 |
94 |
95 | UTF-8
96 | 2.5.1-rc1
97 | 2.5.1-rc1
98 | INFO
99 | PRETTY
100 |
101 | false
102 | false
103 | true
104 | true
105 | false
106 |
107 | index.html
108 |
109 |
110 |
111 |
112 |
113 |
114 | bind
115 |
116 | INFO' -bindAddress '0.0.0.0
117 |
118 |
119 |
120 | pretty
121 |
122 | PRETTY
123 |
124 |
125 |
126 |
127 |
128 |
129 | junit
130 | junit
131 | 3.8.1
132 | test
133 |
134 |
135 | org.timepedia.exporter
136 | gwtexporter
137 | ${version}
138 | provided
139 |
140 |
141 | com.google.gwt
142 | gwt-user
143 | ${gwtversion}
144 | provided
145 |
146 |
147 | com.google.gwt
148 | gwt-dev
149 | ${gwtversion}
150 | test
151 |
152 |
153 |
154 | com.sun
155 | tools
156 | 1.6
157 | system
158 | true
159 | ${java.home}/../lib/tools.jar
160 |
161 |
162 |
163 | javax.validation
164 | validation-api
165 | 1.0.0.GA
166 | provided
167 |
168 |
169 | javax.validation
170 | validation-api
171 | 1.0.0.GA
172 | sources
173 | provided
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/samples/testdemo/src/main/java/testdemo/TestDemo.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/samples/testdemo/src/main/java/testdemo/client/TestDemo.java:
--------------------------------------------------------------------------------
1 | package testdemo.client;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Date;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | import org.timepedia.exporter.client.Export;
9 | import org.timepedia.exporter.client.ExportClosure;
10 | import org.timepedia.exporter.client.ExportConstructor;
11 | import org.timepedia.exporter.client.ExportInstanceMethod;
12 | import org.timepedia.exporter.client.ExportJsInitMethod;
13 | import org.timepedia.exporter.client.ExportOverlay;
14 | import org.timepedia.exporter.client.ExportPackage;
15 | import org.timepedia.exporter.client.ExportStaticMethod;
16 | import org.timepedia.exporter.client.Exportable;
17 | import org.timepedia.exporter.client.ExporterUtil;
18 | import org.timepedia.exporter.client.NoExport;
19 | import org.timepedia.exporter.client.test.JsTestUtil;
20 |
21 | import com.google.gwt.core.client.EntryPoint;
22 | import com.google.gwt.core.client.GWT;
23 | import com.google.gwt.core.client.JavaScriptObject;
24 | import com.google.gwt.dom.client.Document;
25 | import com.google.gwt.dom.client.Element;
26 | import com.google.gwt.dom.client.NodeList;
27 | import com.google.gwt.user.client.ui.Label;
28 | import com.google.gwt.user.client.ui.RootPanel;
29 |
30 | public class TestDemo implements EntryPoint {
31 |
32 | JsTestUtil jsTest = new JsTestUtil(TestDemo.class);
33 |
34 | private void fail(String failed) {
35 | RootPanel.get().add(new Label(failed));
36 | throw new RuntimeException(failed);
37 | }
38 |
39 | public void onModuleLoad() {
40 | GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
41 | Logger logger = Logger.getLogger("TestDemo");
42 | public void onUncaughtException(Throwable e) {
43 | logger.log(Level.SEVERE, "Uncauch Exception", e);
44 | }
45 | });
46 |
47 | test();
48 |
49 | RootPanel.get().add(new Label("OK"));
50 | }
51 |
52 | public void test() {
53 | GWT.create(C.class);
54 | runJsTests1(jsTest);
55 | if (jsTest.isFailed()) fail(jsTest.getFailed());
56 |
57 | ExporterUtil.export(false);
58 | runJsTests2(jsTest);
59 | if (jsTest.isFailed()) fail(jsTest.getFailed());
60 | }
61 |
62 | ///////////////////// Classes used to test types, arrays, static, public, override
63 | @ExportPackage("gwt")
64 | @Export
65 | public static class HelloAbstract implements Exportable {
66 | public String helloAbstract(){
67 | return this.getClass().getName();
68 | }
69 |
70 | @NoExport
71 | public String noHelloAbstract(){
72 | return this.getClass().getName();
73 | }
74 | }
75 |
76 | @ExportPackage("gwt")
77 | @Export("HelloClass")
78 | public static class HelloClass extends HelloAbstract implements Exportable {
79 | public String hello(){
80 | return this.getClass().getName();
81 | }
82 |
83 | public static String[] test0(char c, byte b, int i, double d, float f, String s, Object o, Exportable e) {
84 | String[] ret = new String[8];
85 | ret[0] = "" + (int)c;
86 | ret[1] = "" + b;
87 | ret[2] = "" + i;
88 | ret[3] = "" + d;
89 | ret[4] = "" + f;
90 | ret[5] = "" + s;
91 | ret[6] = "" + o.getClass().getName();
92 | ret[7] = "" + e.getClass().getName();
93 | return ret;
94 | }
95 |
96 | public static int[] test1(char[]c, byte[] b, int[] i, double[]d, float[] f, long[] l, String[] s, Object[] o, Exportable[] e) {
97 | int[] ret = new int[9];
98 | ret[0] = c.length;
99 | ret[1] = b.length;
100 | ret[2] = i.length;
101 | ret[3] = d.length;
102 | ret[4] = f.length;
103 | ret[5] = l.length;
104 | ret[6] = s.length;
105 | ret[7] = o.length;
106 | ret[8] = e.length;
107 | return ret;
108 | }
109 |
110 | public static long[] test2() {
111 | return new long[]{1l,2l};
112 | }
113 |
114 | public static Exportable[] test3() {
115 | return new HelloClass[]{new HelloClass()};
116 | }
117 |
118 | public static char test4() {
119 | return 1;
120 | }
121 |
122 | public static byte test5() {
123 | return 2;
124 | }
125 |
126 | public static int test6() {
127 | return 3;
128 | }
129 |
130 | public static double test7() {
131 | return 4;
132 | }
133 |
134 | public static float test8() {
135 | return 5;
136 | }
137 |
138 | public static String test9() {
139 | return "A";
140 | }
141 |
142 | public static JavaScriptObject test10() {
143 | return new Label("").getElement();
144 | }
145 |
146 | public static long test11() {
147 | return 6;
148 | }
149 |
150 | public static String test12(long l){
151 | return "" + l;
152 | }
153 |
154 | public static long test13(long l, double d) {
155 | return l + (long)d;
156 | }
157 |
158 | public long test14(long l, double d, long[] a) {
159 | return l + (long)d + a[0];
160 | }
161 |
162 | public long[] test15(long[] a) {
163 | return a;
164 | }
165 |
166 | public static String test16(long l) {
167 | return "" + l;
168 | }
169 |
170 | public static long test16(long a, long b) {
171 | return (a + b);
172 | }
173 |
174 | public String test17(long l) {
175 | return "" + l;
176 | }
177 |
178 | public long test17(long a, long b) {
179 | return (a + b);
180 | }
181 |
182 | public static String test18(String a, String[] b) {
183 | return a + "_" + b.length;
184 | }
185 |
186 | public static String test18(String a, String b, String[] c) {
187 | return a + "_" + b + "_" + c.length;
188 | }
189 |
190 | public String test19(String a, String[] b) {
191 | return test18(a, b);
192 | }
193 |
194 | public String test19(String a, String b, String[] c) {
195 | return test18(a, b, c);
196 | }
197 |
198 | public static String test20(String a, long b, String...c) {
199 | return a + "_" + b + "_" + c.length;
200 | }
201 |
202 | public String test21(String a, long b, String...c) {
203 | return test20(a, b, c);
204 | }
205 |
206 | public static Date test22(Date d) {
207 | return d;
208 | }
209 |
210 | @SuppressWarnings("deprecation")
211 | public String test23(Date...ds) {
212 | String ret = "";
213 | for (Date d : ds) {
214 | ret += d.getYear() + "-";
215 | }
216 | return ret;
217 | }
218 |
219 | public Date[] test24() {
220 | Date[] ret = new Date[1];
221 | ret[0] = new Date(0);
222 | return ret;
223 | }
224 |
225 |
226 | public boolean test25(boolean a) {
227 | return a;
228 | }
229 |
230 | public boolean test26(long l) {
231 | return l > 2;
232 | }
233 |
234 | public boolean test27(boolean a) {
235 | return a;
236 | }
237 |
238 | public boolean test27(boolean a, boolean b, long l) {
239 | return a && b && l > 2;
240 | }
241 | }
242 |
243 | ///////////////////// Classes used to test closures
244 | @ExportPackage("gwt")
245 | @Export("Foo")
246 | public static class Foo implements Exportable {
247 |
248 | String n = "foo";
249 | public Foo() {
250 | }
251 | public Foo(String id) {
252 | n= id;
253 | }
254 | public Foo(String id, String a) {
255 | n= id + a;
256 | }
257 | public String toString(){
258 | return n;
259 | }
260 | public String toString(String a){
261 | return n + ">" + a;
262 | }
263 |
264 | @ExportClosure
265 | public interface Closure extends Exportable {
266 | public String execute(String par1, String par2);
267 | }
268 |
269 | public String executeJsClosure(Closure closure){
270 | return closure.execute("Hello", "Friend");
271 | }
272 | }
273 |
274 | ///////////////////// Classes used to test that we can mark methods in interfaces
275 | public static interface MInterface extends Exportable {
276 | @Export
277 | String m1();
278 | String m1(int a);
279 | @Export
280 | String m1(int a, int b);
281 | }
282 |
283 | public static abstract class MBase implements MInterface {
284 | @Export
285 | public String m0() {
286 | return "m0";
287 | }
288 | public String m1() {
289 | return "m1";
290 | }
291 | public String m1(int a) {
292 | return "m1-" + a;
293 | }
294 | public String m1(int a, int b) {
295 | return "m1-" + a + b;
296 | }
297 | @Export
298 | public String m2() {
299 | return "m2";
300 | }
301 | }
302 |
303 | ///////////////////// Classes used to test that unused parent classes are not exported
304 | @ExportPackage("gwt")
305 | public static class MClass extends MBase {
306 | @Export
307 | public String m0() {
308 | return "om0";
309 | }
310 | @Export
311 | public String m3() {
312 | return "m3";
313 | }
314 | public String m4() {
315 | return "m4";
316 | }
317 | @Export
318 | public final String f() {
319 | return "final";
320 | }
321 | }
322 |
323 | @ExportPackage("gwt")
324 | public static class A implements Exportable {
325 | public B convertToB() {
326 | return new B();
327 | }
328 | @Export
329 | public String foo() {
330 | return "foo";
331 | }
332 | @Export
333 | public String toString() {
334 | return this.getClass().getName().replaceAll("^.+[\\.\\$]", "");
335 | }
336 | }
337 |
338 | @ExportPackage("gwt")
339 | public static class B extends A {
340 | public C convertToC() {
341 | return new C();
342 | }
343 | public String toString() {
344 | return "A";
345 | }
346 | }
347 |
348 | @ExportPackage("gwt")
349 | public static class C extends A {
350 | @Export
351 | public A convertToA() {
352 | return new A();
353 | }
354 | }
355 |
356 | ///////////////////// Classes used to test exported methods in parent classes if export.all = true. And name-spaces
357 | public static class Parent {
358 | public String m(String a) {
359 | return a;
360 | }
361 | public String getParentName(Parent p) {
362 | return p.getClass().getName().replaceAll("^.*[\\.\\$]", "");
363 | }
364 | public Parent parent() {
365 | return this;
366 | }
367 | }
368 |
369 | @Export(value = "$$", all = true)
370 | @ExportPackage("")
371 | public static class Son extends Parent implements Exportable {
372 | @Export
373 | public String f = "F";
374 |
375 | @Export("sonName")
376 | public String getSonName(Son c) {
377 | return super.getParentName(c);
378 | }
379 |
380 | @Export("$wnd.$$$")
381 | public static String $() {
382 | return "$$$";
383 | }
384 | }
385 |
386 | ///////////////////// Classes used to test export overlay
387 | public static class Func {
388 | public boolean f(Element e) {
389 | return true;
390 | }
391 | }
392 |
393 | public static class GQ implements Exportable {
394 | private String echoMsg = "empty";
395 |
396 | @ExportConstructor
397 | public static GQ $(String s) {
398 | GQ ret = new GQ();
399 | ret.echoMsg = s;
400 | return ret;
401 | }
402 | public String echo() {
403 | return echoMsg;
404 | };
405 | public Element element() {
406 | return Document.get().getDocumentElement();
407 | };
408 | public Element[] elements() {
409 | ArrayList e = new ArrayList();
410 | e.add(element());
411 | return e.toArray(new Element[0]);
412 | };
413 | public String countElements(Element... elms) {
414 | return "" + elms.length;
415 | }
416 | public GQ[] exports() {
417 | ArrayList j = new ArrayList();
418 | j.add(this);
419 | return j.toArray(new GQ[0]);
420 | }
421 | public GQ gq() {
422 | return this;
423 | }
424 |
425 | public boolean executeFunction(Func... f) {
426 | boolean ret = false;
427 | for (Func ff : f) {
428 | ret = ret || ff.f(element());
429 | }
430 | return ret;
431 | }
432 |
433 | public boolean executeFunction(String s, Func... f) {
434 | boolean ret = executeFunction(f);
435 | return ret;
436 | }
437 |
438 | public GQ executeFunction2(Func... f) {
439 | echoMsg = "ret-" + executeFunction(f);
440 | return this;
441 | }
442 |
443 | public String executeClosure(Clos f) {
444 | return f.execute("A", "B");
445 | }
446 |
447 | public String executeClosure(int i, Clos f) {
448 | return f.execute("A", "B");
449 | }
450 | }
451 |
452 | @ExportPackage("gwt")
453 | @Export("j")
454 | public static class JQ implements ExportOverlay {
455 | public String echo() {return null;}
456 |
457 | public Element element(){return null;}
458 | public Element[] elements(){return null;}
459 | public String countElements(Element... elms){return null;}
460 |
461 | public GQ[] exports() {return null;}
462 |
463 | public GQ gq() {return null;}
464 |
465 | public boolean executeFunction(Func... f) {return false;}
466 | public boolean executeFunction(String s, Func... f) {return false;}
467 | public GQ executeFunction2(Func... f) {return null;}
468 |
469 | public String executeClosure(Clos f) {return null;}
470 | public String executeClosure(int a, Clos f) {return null;}
471 |
472 | @Export("$wnd.$")
473 | public static GQ $(String s){return null;};
474 | }
475 |
476 | @ExportClosure
477 | public interface Clos extends Exportable {
478 | public String execute(String par1, String par2);
479 | }
480 |
481 | @ExportClosure()
482 | public interface FuncClos extends ExportOverlay {
483 | public boolean f(Element e);
484 | }
485 |
486 | ///////////////////// Class used to test static constructors
487 | @ExportPackage("gwt")
488 | @Export("c")
489 | public static class TestConstructors implements Exportable {
490 | private static TestConstructors instance;
491 | private String msg;
492 |
493 | @ExportConstructor
494 | public static TestConstructors constructor(String msg) {
495 | if (instance == null) {
496 | instance = new TestConstructors();
497 | instance.msg = msg;
498 | }
499 | return instance;
500 | }
501 | // Constructor is private
502 | private TestConstructors() {
503 | }
504 | public String echo() {
505 | return msg;
506 | }
507 | }
508 |
509 | // ExportOverlay issue_30
510 | public static class Child {
511 | private String name;
512 | public Child(String cname) { name = cname; }
513 | public String getName1() { return name; }
514 | public String getName2(long l) { return name + l; }
515 | public String getName3(Child c) { return c==null? "NULL" :c.getName1(); }
516 |
517 | public String wrapped_method(long l) {return "" + l;}
518 | }
519 |
520 | public static class Mother {
521 | Child child;
522 | public void setChild(Child c) {child = c;}
523 | public Child getChild() {return child;}
524 | }
525 |
526 | @ExportPackage("ex")
527 | @Export("Child")
528 | public static class XChild implements ExportOverlay{
529 | public XChild(String s){}
530 | @Export("name")
531 | public String getName1() {return null;}
532 | @Export("name")
533 | public String getName2(long l) {return null;}
534 | @Export("name")
535 | public String getName3(Child c) {return null;}
536 |
537 | @ExportConstructor
538 | public static Child constructor(String name, String surname) {
539 | return new Child(name + " " + surname);
540 | }
541 |
542 | @ExportInstanceMethod("foo")
543 | public static String instanceMethod(Child instance, String name, String surname, long l) {
544 | return name + "-" + surname + "-Foo-" + l;
545 | }
546 | @ExportInstanceMethod("foo")
547 | public static String instanceMethod(Child instance, String name) {
548 | return name + "-Caa";
549 | }
550 |
551 | @ExportStaticMethod("sfoo")
552 | public static String staticMethod(String name) {
553 | return name + "-Cas";
554 | }
555 | @ExportStaticMethod("sfoo")
556 | public static String staticMethod(long l) {
557 | return l + "-Cas";
558 | }
559 |
560 | public String wrapped_method(long l) {return null;}
561 | }
562 |
563 | @ExportPackage("ex")
564 | @Export("Mother")
565 | public static class XMother implements ExportOverlay{
566 | public void setChild(Child c) {}
567 | public Child getChild() {return null;}
568 | }
569 |
570 | public static class Q {
571 | private NodeList nodeList = JavaScriptObject.createArray().cast();
572 | public Q() {
573 | nodeList = Document.get().cast().getElementsByTagName("body");
574 | }
575 | public int size() {
576 | return nodeList.getLength();
577 | }
578 | public NodeList get() {
579 | return nodeList;
580 | }
581 | }
582 |
583 | @ExportPackage("")
584 | @Export("JQ")
585 | public static class EJQ implements ExportOverlay {
586 | public int size(){return -1;}
587 | @ExportJsInitMethod
588 | public NodeList get(){return null;}
589 | }
590 |
591 | public native JavaScriptObject runJsTests1(JsTestUtil jsTest) /*-{
592 | var assertEq = function(a, b) {jsTest.@org.timepedia.exporter.client.test.JsTestUtil::assertEquals(*)(a, b);}
593 | try {
594 | var c = new $wnd.gwt.C();
595 | assertEq("C", c);
596 | assertEq("C", c.toString());
597 | var a = c.convertToA();
598 | assertEq("A", a);
599 | a = new $wnd.gwt.A();
600 | assertEq("A", a);
601 |
602 | // GWT.create(C) should not export B
603 | var c = $wnd.gwt.B ? "defined" : "undefined";
604 | assertEq("undefined", c);
605 | } catch(e) {
606 | assertEq(null, "JS Exception: " + e);
607 | };
608 | }-*/;
609 |
610 | public native JavaScriptObject runJsTests2(JsTestUtil jsTest) /*-{
611 | var assertEq = function(a, b) {jsTest.@org.timepedia.exporter.client.test.JsTestUtil::assertEquals(*)(a, b);}
612 |
613 | try {
614 | var h = new $wnd.gwt.HelloClass();
615 | assertEq("1,2,3,4,5,S,JavaScriptObject,HelloClass", $wnd.gwt.HelloClass.test0(1, 2, 3, 4, 5, "S", window.document, h));
616 | assertEq("1,1,1,1,1,2,2,2,1", $wnd.gwt.HelloClass.test1([0], [0], [0], [0], [0], [1,2], ["a","b"], [window,document], [h]));
617 | assertEq("1,2", $wnd.gwt.HelloClass.test2());
618 | assertEq("HelloClass", $wnd.gwt.HelloClass.test3()[0].hello());
619 | assertEq("HelloClass", $wnd.gwt.HelloClass.test3()[0].helloAbstract());
620 | assertEq("undefined", "" + $wnd.gwt.HelloClass.test3()[0].noHelloAbstract);
621 |
622 | assertEq("1", $wnd.gwt.HelloClass.test4(1, "A"));
623 | assertEq("2", $wnd.gwt.HelloClass.test5());
624 | assertEq("3", $wnd.gwt.HelloClass.test6());
625 | assertEq("4", $wnd.gwt.HelloClass.test7());
626 | assertEq("5", $wnd.gwt.HelloClass.test8());
627 | assertEq("A", $wnd.gwt.HelloClass.test9());
628 | assertEq("div", $wnd.gwt.HelloClass.test10().tagName.toLowerCase());
629 | assertEq("6", $wnd.gwt.HelloClass.test11());
630 | assertEq("1", $wnd.gwt.HelloClass.test12(1));
631 | assertEq("5", $wnd.gwt.HelloClass.test13(2, 3));
632 | assertEq("4", $wnd.gwt.HelloClass.test16(4));
633 | assertEq("14", $wnd.gwt.HelloClass.test16(4, 10));
634 | assertEq("a_2", $wnd.gwt.HelloClass.test18("a", ["b", "c"]));
635 | assertEq("a_b_1", $wnd.gwt.HelloClass.test18("a", "b", ["c"]));
636 | assertEq("a_1_0", $wnd.gwt.HelloClass.test20("a", 1));
637 | assertEq("a_1_3", $wnd.gwt.HelloClass.test20("a", 1, "a", "e", "i"));
638 | assertEq("1970", "" + ($wnd.gwt.HelloClass.test22(new Date(0)).getYear() + 1900));
639 |
640 | var h = new $wnd.gwt.HelloClass();
641 | assertEq("102", h.test14(1, 1, [100]));
642 | assertEq("100,200", h.test15([100, 200]));
643 | assertEq("5", h.test17(5));
644 | assertEq("15", h.test17(5,10));
645 | assertEq("a_2", h.test19("a", ["b", "c"]));
646 | assertEq("a_b_1", h.test19("a", "b", ["c"]));
647 | assertEq("a_1_0", h.test21("a", 1));
648 | assertEq("a_1_3", h.test21("a", 1, "a", "e", "i"));
649 | assertEq("70-111-", h.test23(new Date(0), new Date(1309777010000)));
650 | assertEq("70", "" + h.test24()[0].getYear());
651 | assertEq("true", h.test25(true));
652 | assertEq("false", h.test25(false));
653 | assertEq("true", h.test26(3));
654 | assertEq("true", h.test27(true, true, 3));
655 |
656 | var v1 = new $wnd.gwt.Foo();
657 | assertEq("foo", v1);
658 | var v2 = new $wnd.gwt.Foo("foo2");
659 | assertEq("foo2", v2);
660 | var v3 = new $wnd.gwt.Foo("foo3", "bbb");
661 | assertEq("foo3bbb", v3);
662 | assertEq("foo3bbb>ccc", v3.toString("ccc"));
663 | assertEq("Hello,Friend", v3.executeJsClosure(function(arg1, arg2) {
664 | return arg1 + "," + arg2;
665 | }));
666 |
667 | var m = new $wnd.gwt.MClass();
668 | assertEq("om0", m.m0());
669 | assertEq("m1", m.m1());
670 | assertEq("m1-23", m.m1(2, 3));
671 | assertEq("m2", m.m2());
672 | assertEq("m2", m.m2());
673 | assertEq("m3", m.m3());
674 | var m5 = $wnd.gwt.MClass.m5 ? "defined" : "undefined";
675 | assertEq("undefined", m5);
676 | assertEq("final", m.f());
677 |
678 | // exportAll must export B
679 | var c = $wnd.gwt.B ? "defined" : "undefined";
680 | assertEq("defined", c);
681 |
682 | var ch = new $wnd.$$();
683 | assertEq("Son", ch.sonName(ch));
684 | assertEq("Son", ch.getParentName(ch.parent()));
685 | assertEq("$$$", $wnd.$$$());
686 |
687 | // export overlay
688 | var gq = new $wnd.$('hello');
689 | assertEq("hello", gq.echo());
690 | assertEq("hello", gq.gq().echo());
691 |
692 | var ex = gq.exports();
693 | assertEq("hello", ex[0].echo());
694 |
695 | assertEq("0", gq.countElements());
696 | assertEq("1", gq.countElements(document));
697 | assertEq("2", gq.countElements([document, window]));
698 |
699 | assertEq("object", (typeof gq.element()));
700 | assertEq("object", (typeof gq.elements()[0]));
701 |
702 | assertEq('whatever', gq.executeClosure(function(){return 'whatever';}));
703 | assertEq('false', gq.executeFunction(function(e){return e == null;}));
704 | assertEq('true', gq.executeFunction(function(e){return false;}, function(e){return e != null;}));
705 | assertEq('ret-true', gq.executeFunction2(function(e){return true;}).gq().echo());
706 | assertEq('ret-false', gq.executeFunction2(function(e){return false;}).echo());
707 |
708 | // export static constructors
709 | var cs1 = new $wnd.gwt.c('hello');
710 | assertEq("hello", cs1.echo());
711 | var cs2 = new $wnd.gwt.c('by');
712 | assertEq("hello", cs2.echo());
713 |
714 | // more tests for exportoverlay
715 | var child = new $wnd.ex.Child("Bill");
716 | var mother = new $wnd.ex.Mother();
717 | mother.setChild(child);
718 | assertEq("Bill", mother.getChild().name());
719 | assertEq("Bill2", mother.getChild().name(2));
720 | assertEq("Joe", child.name(new $wnd.ex.Child("Joe")));
721 | assertEq("s1-s2-Foo-2", child.foo('s1', 's2', 2));
722 | assertEq("s1-Caa", child.foo('s1'));
723 | assertEq("null-Caa", child.foo(null));
724 | assertEq("s-Cas", $wnd.ex.Child.sfoo('s'));
725 | assertEq("2-Cas", $wnd.ex.Child.sfoo(2));
726 |
727 | // tests for ExportJsInit
728 | var jq = new $wnd.JQ();
729 | assertEq("1", "" + jq.length);
730 | assertEq("1", "" + jq.size());
731 | } catch(e) {
732 | assertEq(null, "JS Exception: " + e);
733 | };
734 | }-*/;
735 |
736 | }
737 |
--------------------------------------------------------------------------------
/samples/testdemo/src/main/java/testdemo/public/TestDemo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | TestDemo
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/samples/testdemo/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/testdemo/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------