-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathreference.html
More file actions
1139 lines (967 loc) · 41.6 KB
/
reference.html
File metadata and controls
1139 lines (967 loc) · 41.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
layout: default
title: Reference
---
<h3><a id="writing">Writing ST-JS code</a></h3>
<p>Please start by reading our <a href="faq.html#whatDoesItLookLike">What does it look
like?</a> section. It contains most of the information you need to write usual ST-JS
code. On top of that, our <a href="tutorial.html">tutorial</a> will guide you through
all the steps necessary to create and run your first ST-JS project with Maven.</p>
<p>If you need to use more advanced features of ST-JS, or haven't found out how
a particular JavaScript construct can be expressed in Java, then keep on reading.</p>
<h4>Special fields and methods</h4>
<p>Most of the Java code you write will be translated basically
as-is to its JavaScript counterpart. However, there are some
JavaScript constructs that cannot be written as-is in Java. For
these cases, ST-JS provides workarounds as special fields and
methods.</p>
<p>All of those special fields and methods are easy to identify:
there name always starts with the dollar sign ($). When you use
these methods you should expect the generated JavaScript code to
look slighty different (it is usually prettier, actually) than the
corresponding Java construct.</p>
<p>Here is the list of these constructs and methods:
<h5>Collection initialization (org.stjs.javascript.JSCollections)</h5>
<pre class="code prettyprint">
// JavaScript // Java equivalent
// Create a map with the given keys and values
{k1:v1, k2:v2} $map(k1,v1,k2,v2)
// Create an array with the given items
[a, b, c] $array(a, b, c)
// Convert a java array to the org.stjs.javascript.Array type
var a=b Array<T> a = $castArray(T[]b)
</pre>
<h5>Associative array, maps, etc... (org.stjs.javascript.Map)</h5>
<pre class="code prettyprint">
// JavaScript // Java equivalent
// Put a key and a value in a map
x[a] = b x.$put(a, b)
// Retrieve a value from a map
x[a] x.$get(a)
// Delete an entry from a map
delete x[a] x.$delete(a)
</pre>
<h5>Arrays (org.stjs.javascript.Array)</h5>
<pre class="code prettyprint">
// JavaScript // Java equivalent
// Retrieve an item from an array
x[a] x.$get(a)
// Modify an item in an array
x[index] = val x.$set(index, val)
</pre>
<h5>Working with object properties (org.stjs.javascript.JsObjectAdapter)</h5>
<pre class="code prettyprint">
// JavaScript // Java equivalent
// expose all the properties of an object as a map
propsMap = obj propsMap = $properties(obj)
// get the value of a property of an object by name
obj["prop"] $properties(obj).$get("prop")
// convert a map as an object of a given type with the same properties
var obj = map T obj = $object(map)
// Return the prototype of a JavaScript objects
obj.prototype $prototype(obj)
// Return the constructor of a JavaScript object
obj.constructor $constructor(obj)
// Replaces with the given javascriptCode (only String literals accepted).
// Use it only in extreme cases as it makes it impossible to minimize the code.
javascriptCode $js(javascriptCode)
</pre>
<h5>Other Javascript operations (org.stjs.javascript.Global)</h5>
<pre class="code prettyprint">
// JavaScript // Java equivalent
// Return first value the is equivalent to true in JavaScript
a || b || c $or(a,b,c)
</pre>
<h3><a id="controlling">Controlling the JavaScript output</a></h3>
<p>In most cases, there is no need to change the way the
JavaScript is generated. There are however come cases where this is
useful</p>
<p>ST-JS lets you customize the way the JavaScript is generated
(if you want to). You can give hints to the generator by placing
annotations in your Java code.</p>
<h4>@Namespace</h4>
<p>The annotated Class, or all the classes in the annotated package
will be placed in the specified namespace. This is useful to avoid
name clashes with classes coming from other libraries.</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java with @Namespace
@Namespace("genie.in.a")
public class Bottle {
public Bottle() {
doSomething();
}
}
// Java without @Namespace
public class Plain {
public Plain() {
doNothing();
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript with @Namespace
stjs.ns("genie.in.a");
genie.in.a.Bottle = function() {
doSomething();
}
// JavaScript without @Namespace
Plain = function() {
doNothing();
}
</pre>
</div>
<div class="clear"></div>
<h4>@JavascriptFunction</h4>
<p>All the anonymous implementations of the annotated single-method Java interface
will be generated as a JavaScript anonymous function. All invocations of the method
contained in the annotated interface will be generated as a direct call to that function.
The interface itself will not be generated in Javascript
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java
@JavascriptFunction
public interface EventHandler {
public boolean onEvent(Event evt);
}
public class Something {
public Something(Event event){
// defining a new anonymous implementation
EventHandler handler = (evt) -> {
console.print(evt.name);
};
// calling the single-method
handler.onEvent(event);
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript
// the interface is not generated
Something = function(event){
// translated as an anonymous function
var handler = function(evt) {
console.print(evt.name);
};
// invoke the function directly
handler(event);
}
</pre>
</div>
<div class="clear"></div>
<h4>@GlobalScope</h4>
<p>The static fields and methods in the annotated type are considered
already being part of the global scope at runtime, typically provided by
an existing imported JavaScript library. When a type is
annotated with @GlobalScope, no corresponding JavaScript is generated.
</p>
<p>This annotation is useful when writing bridges for an existing JavaScript
library which declares some of its members in the global scope (typical
example: the $ identifier for JQuery). org.stjs.javascript.Global is an
example of class with this annotation, which contains the declaration
of several global objects such as "window" or "console".
</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java (declaration)
@GlobalScope
public class JQuerySubset {
public static JQuery $;
public static JQuery $(String selector) {
// this doesn't need to be implemented
// the real implementation comes
// directly from jquery.js
throw new UnsupportedOperationException();
}
}
// Java (usage)
import static JQuerySubset.$;
public class Something {
public Something(){
$(".hello").addClass(".world");
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript (declaration)
// nothing is generated, implementation comes from
// including jquery.js
// JavaScript (usage)
Something = new function(){
$(".hello").addClass(".world");
}
</pre>
</div>
<div class="clear"></div>
<h4>@SyntheticType</h4>
<p>The annotated class is marked as a data-only object. Objects marked with
this annotation can only contain non-private fields and cannot
contain any methods. Instance of a class marked with this annotation
can be initialized using the double-brace syntax in your java source
code, and will be translated to a Javascript Object Literal.
</p>
<p>This annotation is typically used by bridges to provide a correctly typed
equivalent of a parameter that the javscript library expects to be an
Object Literal. An example is AjaxParams used by JQuery.ajax</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java (declaration)
@SyntheticType
public class AjaxParams {
// some fields are omitted for brevity
public boolean async;
public String url;
}
// Java (usage)
import static JQuerySubset.$;
public class Something {
public Something(){
$.ajax(new AjaxParams(){ {
async = false;
url = "http://example.com";
} });
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript (declaration)
var AjaxParams = function(){};
stjs.extend(AjaxParams, null, [],
function(constructor, prototype){
prototype.async = null;
prototype.url = null;
}, {});
// JavaScript (usage)
Something = function(){
$.ajax({
async : false,
url : "http://example.com"
});
}
</pre>
</div>
<div class="clear"></div>
<h4>@STJSBridge</h4>
<p>The annotated package or type is marked as a simple bridge between ST-JS
Java source code and an existing JavaScript library. The purpose of types
annotated (or contained withing packages that are annotated) with @STJSBridge
is only to provide information about types, fields and methods contained
defined by an existing external JavaScript library to the Java tooling.
</p>
<p>The JavaScript source file that contains the actual implementation that the bridge
corresponds to should be specified using the sources field of @STJSBridge. By default
the sources location is specified as relative to the classpath. Since ST-JS 3.2.0,
the sources location can be specified using a webjar: url.
</p>
<div class="grid_10 alpha">
<pre class="code prettyprint language-java">
// Classpath URI
@STJSBridge( sources = {"/path/to/js/jquery.1.11.js"} )
public class WithClassPath {
...
}
// Webjar URI
@STJSBridge( sources = {"webjar:/jquery.js"} )
public class WithWebjar {
...
}
</pre>
</div>
<div class="clear"></div>
<h4>@Adapter</h4>
<p>The static methods in the annotated type are marked as being members of another
existing JavaScript type. The scope of this annotation is rather narrow,
and is used by ST-JS to make it possible to use all the methods that the
JavaScript standard library defines for types analog to those in the
java.lang package, such as Number(and its subclasses), String, Object,
etc...</p>
<p>ST-JS tries to keep the Java code as close as possible to the generated
JavaScript code, and therefore uses java.lang.Number (and subclasses)
and java.lang.String to represent the equivalent types of JavaScript.
However, the member methods of each of these types are different in Java
and in JavaScript. ST-JS hides this difference by providing JavaScript
implementations of Java methods in stjs.js (when the Java method doesn't
exist in JavaScript), and by using @Adapter Java methods corresponding
to the JavaScript methods (when the JavaScript method doesn't exist in Java).
</p>
<p>For all the methods of an adapter class, the first parameter must be object
to which the method is applied. The other parameters are the parameters normally
supplied to the JavaScript method.</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java (declaration)
@Adapter
public class JSNumberAdapter {
public static String toFixed(Number n, int p) {
throw new UnsupportedOperationException();
}
public static String toPrecision(Number n, int p) {
throw new UnsupportedOperationException();
}
}
// Java (usage)
public class Something {
public Something(int val){
String fixed = JSNumberAdapter.toFixed(val, 2);
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript (declaration)
// nothing is generated. The implementation is
// already provided by the bridged library
// JavaScript (usage)
Something = function(val){
var fixed = val.toFixed(2);
}
</pre>
</div>
<div class="clear"></div>
<h4>@Template</h4>
<p>this annotation can be used on a method to control how the
call to this method will be generated. The parameter taken by this
annotation is a name of a defined template.
object.$get(i) for example will generate object.$get(i) instead of
object[i].
The current list of templates:
<pre>
adapter = org.stjs.generator.writer.template.AdapterTemplate
assert = org.stjs.generator.writer.template.AssertTemplate
array = org.stjs.generator.writer.template.ArrayTemplate
delete = org.stjs.generator.writer.template.DeleteTemplate
get = org.stjs.generator.writer.template.GetTemplate
invoke = org.stjs.generator.writer.template.InvokeTemplate
js = org.stjs.generator.writer.template.JsTemplate
map = org.stjs.generator.writer.template.MapTemplate
toProperty = org.stjs.generator.writer.template.MethodToPropertyTemplate
none = org.stjs.generator.writer.template.NoneTemplate
or = org.stjs.generator.writer.template.OrTemplate
properties = org.stjs.generator.writer.template.PropertiesTemplate
put = org.stjs.generator.writer.template.PutTemplate
set = org.stjs.generator.writer.template.SetTemplate
typeOf = org.stjs.generator.writer.template.TypeOfTemplate
</pre>
</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java bridge
public interface A {
public int field; //< Illegal, oops...
public String method();
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript source (bridged lib)
var A = {
field: null,
method: function(){}
}
</pre>
</div>
<div class="clear"></div>
<p>As you probably know, it is impossible to place a field in an interface in
Java. ST-JS provides a workaround by using the template <b>property</b>.</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java bridge (declaration)
public interface A {
/** Legal */
@Template("toProperty")
public int $field();
/** Legal. Don't add, if the field is read-only*/
@Template("toProperty")
public void $field(int s);
public String method();
}
// Java application code (usage)
public class App {
public App(A a){
a.$field(42);
String b = a.$field();
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript source (bridged lib)
var A = {
field : null,
method : function(){}
}
// Generated JavaScript application code (usage)
App = function(a){
a.field = 42;
var b = a.field;
}
</pre>
</div>
<div class="clear"></div>
<!-- ---------- -->
<h4>@Native</h4>
<p>This annotation is used to mark the constructors that are less generic when you need to overload the constructors of a class.
The effect of using this annotation on a constructor or even a method is that the code of the given constructor/method is not generated at all.
When you need to overload constructors, ST-JS checks that only ONE constructor has a body and all the others are marked with @Native. Also, the constructor that
has the most generic signature should be left without @Native.
</p>
<div class="grid_5 alpha">
<pre class="code prettyprint language-java">
// Java (declaration)
public class MyClass {
@Native
public MyClass(){
}
@Native
public MyClass(int p1){
}
public MyClass(Integer p1, Integer p2){
//do something here
}
}
</pre>
</div>
<div class="grid_5 omega">
<pre class="code prettyprint language-javascript">
// JavaScript (declaration)
var MyClass = function(p1, p2){}; //only this constructor is generated!
stjs.extend(MyClass, null, [],
function(constructor, prototype){
}, {});
</pre>
</div>
<div class="clear"></div>
<!-- ------------------------ -->
<h4>STJS helper</h4>
<p>The org.stjs.javascript.stjs.STJS interface is the bridge to
the JavaScript code coming with the generator. It offers some
helpers for different type inexistent in JavaScript:
</p>
<ul>
<li><b>boolean isEnum(obj)</b> - return true if the given
JavaScript object is an enum entry (the JavaScript wrapper needed
to allow the usage of Java enums)</li>
<li><b>Exception exception(Object obj)</b> - allows you in
Java to use any object as an exception. At runtime, the executed
JavaScript code will return exactly the received parameter</li>
<li><b>public <T> T parseJSON(String json,
Class<T> clazz)</b> - parses a JSON string in a "type-safe"
manner by creating the object hierarchy using the given type
definition</li>
</ul>
<h3><a id="jsdombridge">The JavaScript and DOM bridge libraries</a></h3>
<p>The JavaScript library (js-lib) is a Java library that you need as
a compile-time dependency for the Java source code. This library
conveniently exposes a properly typed version of the standard
JavaScript library and DOM objects as defined by the browsers. The
maven dependency for this library is the following:</p>
For JavaScript and DOM the global functions and objects (like setInterval or window) are found in the org.stjs.javascript.Global class.
For jQuery, the $ object and function are found in the org.stjs.javascript.jquery.GlobalJQuery class.
<pre class="code prettyprint language-xml">
<dependency>
<groupId>org.st-js.bridge</groupId>
<artifactId>html</artifactId>
<version>5.0.bv0</version>
</dependency>
</pre>
<p>We currently do not have a place to store the javadoc of those libraries, so
for the moment, please use the documentation provided by
<a href="http://www.w3schools.com/jsref/default.asp">w3schools</a>.</p>
<p>ST-JS also comes with another Java library that allows you to share
objects easily between your client (JavaScript) app and you server (Java) by
providing concrete java implementations of some of the classes in the
org.stjs.javascript package (such as Array and Map). The maven dependency for
this library is the following</p>
<pre class="code prettyprint language-xml">
<dependency>
<groupId>org.st-js</groupId>
<artifactId>server</artifactId>
<version>${stjs.version}</version>
</dependency>
</pre>
<p>This dependency allows you to create maps and arrays and to serialize them
(as JSON for example).</p>
<h3><a id="jslibbridge">JavaScript library bridges</a></h3>
<p>As we have mentionned before, STJS is NOT a web framework, so no visual components
or other components are bundled with STJS. You should therefore rely on existing
components defined by other JavaScript frameworks like jQuery, DOJO, etc. There are
two different ways integrate STJS-generated code with existing JavaScript libraries: </p>
<p><em>By writing parts of your application in JavaScript,</em> and using the existing
library and directly calling the generated STJS code. While you can probably make do with
this for a while, this is not the recommended technique.</p>
<p>By writing all your application in ST-JS enabled Java, by writing a Java bridge for the
JavaScript library. This is the recommended approach, and will allow you to take
advantage of all the benefits and tooling of Java, while still using your favorite,
cross-browser library.</p>
<p>STJS already provides bridges for jQuery and jQuery UI plugins. The bridge is composed
mostly of Java interfaces that have the same name as their JavaScript counterpart.
Sometimes you may also need to provide global objects or functions (that will be
implemented as static fields or methods of the object). In the case of a static method,
the method should throw UnsupportedOperationException - to indicate it's a method to be
used in the JavaScript code (not in some server-side Java code).</p>
<p>One interesting feature of the bridges is that they are not submitted to the same list
of constrains as the regular STJS Java code. This means that you can overload methods
in order to provide more clarity to the user. A good example is the way plugins are
built in jQuery where the same function (usually the plugin's name) has many different
usages: activate the plugin, change an option, get a state value, call a method, etc.</p>
<p>The JQuery bridge must be added as a compile time dependency to your project. Here is
the maven dependency section for this artifact.</p>
<p>We currently do not have a place to store the javadoc for the jQuery and jQuery UI bridges,
so for the moment please use the documentation provided by
<a href="http://docs.jquery.com" target="_blank">jQuery</a> and
<a href="http://jqueryui.com/demos/" target="_blank">jQuery UI</a></p>
<pre class="code prettyprint language-xml">
<dependency>
<groupId>org.st-js.bridge</groupId>
<artifactId>jqueryui</artifactId>
<version>1.10.3.bv0</version>
</dependency>
</pre>
<h3><a id="maven">Maven Plugin - the JavaScript Generator</a></h3>
<p>This is the STJS module that will actually take your both Java source code and the
corresponding compiled classes, and generate the corresponding JavaScript code that your
browser can execute. This module can be used either on the command line, or as a maven
plugin.</p>
<p>To use the command line version of the module, please send us an email to
ask us to write the documentation for it...</p>
<p>To use the generator as a maven plugin, include the following snippet in your pom.xml</p>
<pre class="code prettyprint language-xml">
<plugin>
<groupId>org.st-js</groupId>
<artifactId>stjs-maven-plugin</artifactId>
<version>${stjs.version}</version>
<executions>
<execution>
<id>main</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
<!-- if you use the JUnit runner -->
<execution>
<id>test</id>
<goals>
<goal>generate-test</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
</configuration>
</plugin>
</pre>
<h2>Configuration</h3>
<p>You can activate separately the JavaScript generation for
main sources and tests. Here are the goals of the maven plugin:</p>
<ul>
<li><b>generate</b> - activate the generation for the main
sources (in the "process-sources" phase)</li>
<li><b>generate-test</b> - activate the generation for the
test sources (in the "process-test-classes" phase)</li>
<li><b>copy-js</b> - copies the JavaScript files (either
generated or just bridged) from the dependencies to the final
artifact (war file), so that they can be used in the web pages</li>
</ul>
<p>There are some parameters that can be used to configure the plugin:</p>
<ul>
<li><b>includes/include</b> - the path specifier describing
for what Java source you want to generate JavaScript. It's the
standard path Maven/Ant specifiers. Defaults to **.</li>
<li><b>excludes/exclude</b> - the path specifier describing
what Java source you want to exclude from the JavaScript generate.
It's the standard path Maven/Ant specifiers. Defaults to ""
(nothing).</li>
<li><b>allowedPackages</b> - it's a list of Java packages that
are allowed to be used inside the Java sources used for
generation. A common usage is when you reserved in the Java
sources a package for bridges to some JavaScript libraries. This
package should than be excluded from the generation process.
This can also include specific java class cannonical names (e.g.:
"com.acme.util.MyStringBuilder")</li>
<li><b>generateArrayHasOwnProperty</b> - true to generate
inside each array iteration if (!array.hasOwnProperty(index))
continue; in order to protect array iteration from the inclusion
of the methods added to Array's prototype. Default value if true</li>
<li><b>pack</b> - if true, a single JavaScript will be created
containing all the generated JavaScript files in a correct order
(follows the dependencies)</li>
<li><b>generateSourceMap</b> - if true, sourcemaps that allow you to see the
original Java sources in the browser instead of the generated
JavaScript files</li>
<li><b>webjar</b> - if true and the pom's packaging is set to jar, st-js will
package the generated JavaScript in a .jar that follows the webjar
specification.</li>
<li><b>annotations</b> - the list of annotations (only the class name) to be generated in the client</li>
</ul>
<!-- ------------------------------------------------------------ -->
<h3><a id="eclipse">Maven configuration for auto-generation in Eclipse</a></h3>
<p>If you use Eclipse you can take advantage of the Maven / Eclipse integration.
The Javascript code is generated each time the corresponding Java class is modified and saved.
This way any modification you bring to your code will be instantly observed on the browser!
Note: you need the at least the 1.0 version of the <a href="http://wiki.eclipse.org/M2E_updatesite_and_gittags" target="_blank">Eclipse plugin for Maven</a>.
</p>
<pre class="code prettyprint language-xml">
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.st-js</groupId>
<artifactId>
stjs-maven-plugin
</artifactId>
<versionRange>
[${stjs.version},)
</versionRange>
<goals>
<goal>generate</goal>
<!-- if you use the test helper -->
<goal>generate-test</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</pre>
<!-- ------------------------------------------------------------ -->
<h3><a id="junit">The JUnit runner</a></h3>
<h4>Using STJSTestDriverRunner to execute JavaScript unit tests in a browser</h4>
<p>The ST-JS JUnit runner module allows you to write your unit tests in ST-JS enabled
Java, have JUnit run them on a browser of your choice (or multiple browsers in
parallel) and report the test results.</p>
<p>In order to use the STJS JUnit runner, you must first make sure it is included in
your test classpath. If you are using maven, you can simply add the following
dependency to your pom.xml</p>
<pre class="code prettyprint language-xml">
<dependency>
<groupId>org.st-js</groupId>
<artifactId>test-helper</artifactId>
<version>${stjs.version}</version>
<scope>test</scope>
</dependency>
</pre>
<p>To activate the STJS JUnit runner, annotate your JUnit test classes this way
<pre class="code prettyprint language-java">
import org.stjs.testing.driver.STJSTestDriverRunner;
import org.junit.annotations.Test;
@RunWith(STJSTestDriverRunner.class)
public class TestMyStuff {
@Test
public void testMyThing(){
// Your test code goes here
}
}
</pre>
<p>This is all you need to get your unit tests to execute in your system's default browser.
While writing your unit tests, you can of course use the main JUnit annotations such
as <em>@Test</em>, <em>@Before</em> and <em>@After</em></p>
<h4>Customizing the way the unit tests run</h4>
<p>In order to run your unit tests in a browser, the STJS Junit runner builds an HTML page
that includes all the necessary HTML and javascript to execute your tests and
return the result to JUnit. By default, the HTML page that is sent to the browser
includes the following things:</p>
<ul>
<li>The javascript version of all the classes that are being
tested, as well as that of all classes they depend on.</li>
<li>If any bridge class or interface is used, the javascript
code that corresponds. For example, if the classes under test use
jQuery 1.7.1, then jQuery-1.7.1.js is imported in the HTML page
that is sent to the browser.</li>
</ul>
<p>You can have a better control on what is sent in that HTML page by using some annotations
defined by STJS.</p>
</p>
<h5>@HtmlFixture</h5>
<p>This optional annotation can be applied to your test class to force the
STJSTestDriverRunner to include a specific HTML fragment on the page it sends to the
browser. This is useful if the piece of code you are unit testing does some DOM
manipulation and needs some DOM elements to be present to function as expected.</p>
<p>If the HTML fragment is short enough, it can be specified verbatim in the annotation.</p>
<pre class="code prettyprint language-java">
@RunWith(STJSTestDriverRunner.class)
@HtmlFixture("<div id='importantContainer'></div>")
public class TestSimpleFixture {
...
}
</pre>
<p>If the fragment is longer, the annotation allows you to specify a path to a classpath
resource that contains the HTML code. The HTML fragment file will be looked up using
ClassLoader.getResourceAsStream(). This means that STJSTestDriverRunner (trough the
ClassLoader) will first attempt to find the file in your classpath. If the file cannot
be found in your classpath, then STJSTestDriverRunner will look for the file starting at
the "document root" or your webapp, if any. For a typical maven project, this means it
will first look in <em>/target/WEB-INF/classes</em>, and then in <em>/target</em>.</p>
<pre class="code prettyprint language-java">
@RunWith(STJSTestDriverRunner.class)
@HtmlFixture(url = "/SomeComplexHtmlFragment.html")
public class TestSimpleFixture {
...
}
</pre>
<h5>@ScriptsBefore and @ScriptsAfter</h5>
<p>These optional annotations can be applied to your test class to force the
STJSTestDriverRunner to include extra javascript files in the <head>
section of the HTML page that is sent to the browser. This is useful when you are using
a bridged JavaScript library that depends on a third party (unbridged) library, and that
the unit tests require this library to be in the JavaScript execution environment.</p>
<p>Script files specified in
<em>@ScriptsBefore</em> will be included in the HTML page before the class under test
and all its dependencies. Script files specifed in <em>@ScriptsAfter</em> will be
included in the HTML page after the class under test and all its dependencies.</p>
<p>Each of the strings passed as a value to these annotations will be used verbatim in the
generated HTML. This means that you can pass either a path to a javascript file that
exists within your project, or one that resides on another domain.</p>
<pre class="code prettyprint language-java">
@RunWith(STJSTestDriverRunner.class)
@ScriptsBefore({"/someLibBefore.js"})
@ScriptsAfter({"http://example.com/someLibAfter.js"})
public class TestHelloWorld {
...
}</pre>
<p>Will generate the following fragment of HTML</p>
<pre class="code prettyprint language-html">
<head>
<!-- contents of @ScriptsBefore -->
<script src="/someLibBefore.js" type="text/javascript"></script>
<!-- Class under test plus other stuff required by stjs -->
<script src="/stjs.js" type="text/javascript"></script>
<script src="/HelloWorld.js" type="text/javascript"></script>
<!-- contents of @ScriptsAfter -->
<script src="http://example.com/someLibAfter.js" type="text/javascript"></script>
</head>
</pre>
<p>If the script passed to this annotation is a reference to a file defined in your
project (ie: it doesn't start with a protocol handler such as http:, file:, ftp:,
https:, etc...), then the script file will be looked up using
ClassLoader.getResourceAsStream(). This means that STJSTestDriverRunner (trough the
ClassLoader) will first attempt to find the file in your class path. If the file
cannot be found in your classpath, then STJSTestDriverRunner will look for the
file starting at the "document root" or your webapp, if any. For
a typical maven project, this means it will first look in
<em>/target/WEB-INF/classes</em>, and then in <em>/target</em>.</p>
<h4>Configuring the JUnit runner</h4>
<h5>Basic configuration</h5>
<p>You can configure some of the test driver's parameters in a file
called <strong>stjs-test.properties</strong> that must be placed the root of
your class path. The properties supported by this file are the
described in the table below</p>
<p>All these properties can be overridden by specifying them as
system properties when launching the java vm. For example to force
debug mode when launching the tests via Maven you can run `mvn test
-Dstjs.test.debug=true`.</p>
<table class="properties">
<tr>
<th>Property</th>
<th>Description</th>
</tr>
<tr>
<td class="name">stjs.test.config</td>
<td class="description">The classpath location of properties file that contains
the stjs test driver configuration. Default value is
"/stjs-test.properties"</td>
</tr>
<tr>
<td class="name">stjs.test.browsers</td>
<td class="description">A comma separated list of browsers on which to run the
tests. A test is successful only if it has been run successfully
on all the browsers in this list. See the table below for a
description of the supported browsers. The default value is
"desktopDefault".</td>
</tr>
<tr>
<td class="name">stjs.test.port</td>
<td class="description">the port opened by the test driver waiting for connection
from the browsers. Default value is 8055</td>
</tr>
<tr>
<td class="name">stjs.test.wait</td>
<td class="description">the time (in seconds) the test driver waits for the
number of configured browsers to connect. Default value is 10</td>
</tr>
<tr>
<td class="name">stjs.test.skipIfNoBrowser</td>
<td class="description">if this is true, if no browser was connected that it
considers the tests as ignored (can be used in some batch
processing, without failing completely the tests). Default value
is false</td>
</tr>
<tr>
<td class="name">stjs.test.startBrowser</td>
<td class="description">if true, if after 2 seconds (normally check of the
client's code check is 1 second) no browser connected to the test
driver, it tries to start the system's default browser. This can
only work is the Desktop.isDesktopSupported() check return true
(so usually a developer's machine). Default value is true</td>
</tr>
<tr>
<td class="name">stjs.test.testTimeout</td>
<td class="description">the time (in seconds) the test driver waits for a test to
return a result from the browser. Passed this time the test is
considered failed. Default value is 2 seconds</td>
</tr>
<tr>
<td class="name">stjs.test.debug</td>
<td class="description">if this is true, debug information is displayed. Default
value is false</td>
</tr>
<tr>
<td class="name">stjs.test.debugJavaScript</td>
<td class="description">if true, JUnit tests are run in JavaScript debug mode, where ST-JS