-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.cheatsheet.xml
781 lines (756 loc) · 46.4 KB
/
.cheatsheet.xml
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
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the
distribution for a full listing of individual contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<cheatsheet title="HTML5 + Mobile + JAX-RS: Interfaces quickstart">
<intro>
<description>
This quickstart shows off HTML5 based desktop/mobile web application development with Java EE 7 on WildFly. This project uses HTML5, jQuery Mobile, JAX-RS, CDI 1.1, EJB 3.2, JPA 2.1 and Bean Validation 1.1. It includes a persistence unit and some sample persistence and transaction code to help you get your feet wet with database access in enterprise Java.
<br/><br/>
<b>HTML5</b>
<br/><br/>
HTML5 refers to both the newest version of HTML language, and the set of associated technologies that allow creation of web applications and sites that target various devices.
<br/><br/>
<b>jQuery Mobile</b>
<br/><br/>
jQuery Mobile is a client-side web framework with touch-friendly widgets. It provides a HTML5-based user-interface that uses semantic markup. Sites built with jQuery Mobile are accessible on all popular smartphone, tablet and desktop devices.
<br/><br/>
<b>JAX-RS: The Java API for RESTful Web Services</b>
<br/><br/>
JAX-RS is an update specification for Java EE 7. It allows application developers to easily expose Java services as RESTful web services.
<br/><br/>
<b>EJB 3.2</b>
<br/><br/>
EJB 3.2 is an update to the EJB specification for Java EE 7. It allows application developers to build business components and services.
<br/><br/>
<b>JPA 2.1</b>
<br/><br/>
JPA 2.1 is an update to the JPA specification for Java EE 7. It provides application developers with an object-relational mapping facility to manage relational data.
<br/><br/>
<b>Bean Validation 1.1</b>
<br/><br/>
Bean Validation 1.1 is an update specification for Java EE 7, inspired by Hibernate Validator. It allows application developers to specify constraints once (often in their domain model), and have them applied in all layers of the application, protecting data and giving useful feedback to users.
<br/><br/>
</description>
</intro>
<item
skip="false"
title="The Interfaces example in depth">
<description>
The Interfaces application shows off a number of Java EE technologies such as HTML5, jQuery Mobile, JAX-RS, CDI 1.1, EJB 3.2, JPA 2.1 and Bean Validation 1.1.
It does this by providing a member registration database, available via HTML5 and JAX-RS.
<br/><br/>
As usual, let's start by looking at the necessary deployment descriptors. By now, we're very used to seeing <b>beans.xml</b> in <b>WEB-INF/</b> (which can be found in the <b>src/main/webapp</b> directory of the example). Notice that, once again, we don't need a web.xml. There are two configuration files (which can be found in the <b>src/main/resources</b> directory of the example) — <b>WEB-INF/classes/META-INF/persistence.xml</b>, which sets up JPA, and <b>WEB-INF/classes/import.sql</b> which Hibernate, the JPA provider in WildFly, will use to load the initial users into the application when the application starts. We discussed both of these files in detail in The <b>greeter example in depth</b>, and these are largely the same.
</description>
<command
required="true"
returns="currentProject"
serialization="org.jboss.tools.project.examples.cheatsheet.getProjectForCheatsheet"/>
</item>
<item
skip="true"
title="jQuery Mobile pages in index.html">
<description>
Next, let's take a look the <b>index.html</b> file that displays the page the user sees. The HTML page consists of several jQuery Mobile pages.
</description>
<subitem
label="jQuery Mobile and other required JavaScript and CSS artifacts are added to the page in the head element."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=24,toLine=60,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="When you perform the previous action, the page is now open in the Visual Page Editor. The Visual Page Editor provides a live-editing experience - it allows you to make changes to the source of the HTML page and view the results in an embedded browser, all within Eclipse."
skip="true">
</subitem>
<subitem
label="You can add jQuery Mobile components to the page via the Palette. When the "index.html" file is open in the "Visual Page Editor", the palette will offer jQuery Mobile components that can be added to the page. To view the palette, perform the current action. The palette will be opened in a new tab in your workspace."
skip="true">
<command
required="false"
serialization="org.eclipse.ui.views.showView(org.eclipse.ui.views.showView.viewId=org.eclipse.gef.ui.palette_view)"/>
</subitem>
<subitem
label="You could even open the palette manually. Click the "Window" entry in the menu bar. Select the "Show View" entry in it, and then choose the "Other..." entry. This opens a dialog displaying several other views that can be opened. Select the "Palette" item located under the "General" section; doing so will open the "Palette"."
skip="true">
</subitem>
<subitem
label="The first jQuery Mobile page is the introduction page."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=140,toLine=184,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="A jQuery Mobile page can be added to HTML page by clicking the page component in the palette. This adds a new jQuery Mobile page at the current cursor location in the editor. You can also drag and drop the page component from the palette to the HTML page."
skip="true">
</subitem>
<subitem
label="We have a header that displays a button to view information about the application. Clicking the button opens a jQuery Mobile page as a dialog, displaying information about the application."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=142,toLine=145,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="Note that headers can be added to pages by clicking the Header Bar component in the palette."
skip="true">
</subitem>
<subitem
label="The content section contains text introducing the application features."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=148,toLine=165,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="And we have a footer containing a navigation bar to navigate to the Home page (the current page), and the Add member and List member pages."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=266,toLine=275,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="Note that footers can be added to pages by clicking the Footer Bar component in the palette."
skip="true">
</subitem>
<subitem
label="The page also contains an embedded dialog that displays information about the application. It was introduced earlier as the dialog displayed when clicking the button in the header section. Dialogs can be added to the jQuery Mobile page through the Dialog widget in the palette."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=167,toLine=183,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The next jQuery Mobile page is the one that allows you to create a new member. The header and footer is similar to the one in the introduction page."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=187,toLine=221,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The content section allows us to register new members via a registration form (with id "reg"). There should be one member already created when the application starts. The form in the content section allows input of the name, email and telephone number of a member."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=231,toLine=262,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="Forms can be added to pages by clicking the Form component in the jQuery Mobile palette. The rest of the form can be constructed using other form components available in the palette."
skip="true">
</subitem>
<subitem
label="The name is input via a HTML form text field. Such a field can be added with the text input component."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=200,toLine=203,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The member's email is input through a HTML5 form input field of type 'email'. Browsers supporting this form of input will perform validation of the email keyed in by the user. Like the name field, the email field can also be added through the jQuery Mobile palette via the text input component. The displayed dialog will allow you to specify that the type should be an email field, among other parameters."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=204,toLine=207,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The telephone number is input through a HTML form field of type 'telephone number' with a pattern allowing numbers of length 10 through 12. Browsers supporting the telephone number as input may display an reduced keyboard (mobile browsers typically display such a keyboard). Browsers supporting 'telephone number' input will also perform validation of the number keyed in by the user. And like the email field, the palette can be used to construct this field."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=208,toLine=211,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The next jQuery Mobile page is the one to display members. The header and footer is similar to the one in the introduction page."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=224,toLine=264,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="The content section allows us to refresh the list of members displayed. The members are displayed in a placeholder div element with id: "members"."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=231,toLine=262,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
</item>
<item
skip="true"
title="Presentation logic in index.html">
<description>
Next, let's take a look at the wiring done in JavaScript, defined in the <b>index.html</b> file.
</description>
<subitem
label="Event handlers are attached to handle various events."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=65,toLine=118,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="On entering the member list page, the table displaying all members is updated via an event handler for the 'pagebeforeshow' event."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=72,toLine=82,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="When the submit button in the registration page is clicked, the registered event handler serializes the data in the form and delegates the registration process to another function."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=90,toLine=97,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="When the cancel button in the registration page is clicked, the registered event handler ensures that the form fields are cleared and any messages are removed from the view."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=100,toLine=107,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="When the refresh button in the member list page is clicked, the registered event handler delegates the work of updating the table to another function."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=109,toLine=111,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="On entering the registration page, any messages displayed in the registration form are cleared, This is similar to the registered event handler for the cancel button on the same page."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=113,toLine=117,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
<subitem
label="We also define a very simple jQuery plugin that can be invoked on a jQuery object representing a form. This plugin converts the registration form values into a JavaScript object that can be easily passed to the server as a JSON object."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,fromLine=120,toLine=134,editorID=org.jboss.tools.jst.jsp.jspeditor.HTMLTextEditor)"/>
</subitem>
</item>
<item
skip="true"
title="app.js">
<description>
We now take a look at the core JavaScript functionality for the application referenced from JavaScript methods that were earlier defined in the <b>index.html</b> file.
This is defined in the <b>app.js</b> file present in the <b>src/main/webapp/js/app.js</b> file of the project.
The core functionality invokes the REST API on the server to register new members. It also updates the member list when the refresh button is clicked.
</description>
<subitem
label="In the "buildMemberRows" function, we apply the Underscore.js template present in the element with id "member-tmpl" using the array of members as an argument to the template."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/js/app.js,fromLine=23,toLine=25)"/>
</subitem>
<subitem
label="In the "updateMemberTable" function, we invoke the REST API located at "/rest/members" to obtain the collection of members. Once the collection is available in the response, we update the contents of the "members" element with the output of the "buildMemberRows" function."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/js/app.js,fromLine=28,toLine=47)"/>
</subitem>
<subitem
label="The "registerMember" function invokes the the REST API located at "/rest/members" with the JSON representation of the values in the registration form. Any existing error messages are removed."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/js/app.js,fromLine=54,toLine=98)"/>
</subitem>
<subitem
label="On successful registration, the form values are cleared, a message indicating successful registration is displayed and the list of members is updated."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/js/app.js,fromLine=68,toLine=78)"/>
</subitem>
<subitem
label="On a failure to register, if the HTTP response code is 400 or 409, the response is parsed and any error messages are displayed adjacent the form input fields."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/js/app.js,fromLine=79,toLine=92)"/>
</subitem>
</item>
<item
skip="true"
title="Setup LiveReload">
<description>
LiveReload is an open source tool that refreshes web pages open in browsers as their source is edited. Immediate and automatic web page refreshing, without the need to manually refresh, simplifies the workflow of web developers. JBoss Developer Studio provides tooling that implements LiveReload in the IDE.
<br/><br/>
Open the Servers view, right-click in it, select "New" and choose to create a new <b>Server</b>.
Select "LiveReload Server", located in the "Basic" section, as the new server to create. Click Finish to create a new server.
</description>
</item>
<item
skip="true"
title="Using LiveReload">
<description>
We shall now explore the use of LiveReload to optimise our web development workflow.
</description>
<subitem
label="Once again in the Servers view, select the LiveReload Server created in the previous step, and start it."
skip="true">
</subitem>
<subitem
label="Right-click the "index.html" file, select the "Open With" entry, and choose the "Web Browser via LiveReload Server" option. If you're starting LiveReload for the first time, you will be prompted with a dialog. You will be asked whether you want to "Inject the livereload.js script in HTML pages" and to "Allow Remote connections". The defaults are sufficient - click Yes to proceed. If you do not choose to inject the livereload.js script, you must use a LiveReload extension with your browser."
skip="true">
<!-- Disable this command for now. We cannot open the same file in two different editors.
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.html,editorID=org.jboss.tools.livereload.openFileInBrowserWithLiveReload)"/>
-->
</subitem>
<subitem
label="You can make changes to the "index.html" page without refreshing it in the browser. All you need to do is save your changes, and the LiveReload tooling will ensure that the browser is updated. Note that we haven't written a backend service yet, so the page in the web browser will only display changes to the static content. It will not display any members, nor will it allow new members to be added. We will get LiveReload to work in the context of a running application with backend services, at a later stage in the tutorial."
skip="true">
</subitem>
</item>
<item
skip="true"
title="Member.java">
<description>
Next, let's take a look at the Member entity, before we look at how the application is wired together with the backend:
</description>
<subitem
label="As usual with JPA, we define that the class is an entity by adding @Entity"
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/model/Member.java,fromLine=36)"/>
</subitem>
<subitem
label="Members are exposed as a RESTful service using JAX-RS. We can use JAXB to map the object to XML and to do this we need to add @XmlRootElement."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/model/Member.java,fromLine=37)"/>
</subitem>
<subitem
label="Bean Validation allows constraints to be defined once (on the entity) and applied everywhere. Here we constrain the person's name to a certain size and regular expression. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/model/Member.java,fromLine=47,toLine=49)"/>
</subitem>
<subitem
label="Hibernate Validator also offers some extra validations such as @Email. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/model/Member.java,fromLine=54,toLine=54)"/>
</subitem>
<subitem
label="@Digits, @NotNull and @Size are further examples of constraints. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/model/Member.java,fromLine=57,toLine=59)"/>
</subitem>
</item>
<item
skip="true"
title="MemberRepository.java">
<description>
Let's take a look at MemberRepository, which is responsible for interactions with the persistence layer:
</description>
<subitem
label="The bean is application scoped, as it is a singleton."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/data/MemberRepository.java,fromLine=29)"/>
</subitem>
<subitem
label="The entity manager is injected, to allow interaction with JPA."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/data/MemberRepository.java,fromLine=32)"/>
</subitem>
<subitem
label="The JPA criteria api is used to load a member by his or her unique identifier, email address."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/data/MemberRepository.java,fromLine=40,toLine=47)"/>
</subitem>
<subitem
label="The criteria api can also be used to load lists of entities ."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/data/MemberRepository.java,fromLine=51,toLine=58)"/>
</subitem>
</item>
<item
skip="true"
title="MemberRegistration.java">
<description>
Let's now look at MemberRegistration, the class that allows us to create new members from the server-side REST service.
</description>
<subitem
label="This bean requires transactions as it needs to write to the database. Making this an EJB gives us access to declarative transactions - much simpler than manual transaction control! "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/service/MemberRegistration.java,fromLine=28)"/>
</subitem>
<subitem
label="Here we inject a JDK logger, defined in the Resources class."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/service/MemberRegistration.java,fromLine=31)"/>
</subitem>
<subitem
label="An event is sent every time a member is updated. This allows other pieces of code (in this quickstart the member list is refreshed) to react to changes in the member list without any coupling to this class. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/service/MemberRegistration.java,fromLine=43)"/>
</subitem>
</item>
<item
skip="true"
title="MemberService.java">
<description>
Let's now look at MemberService, the class that is responsible for exposing the RESTful service.
</description>
<subitem
label="The RESTful service is accessible at the "/members" URI relative to the base URI of the server."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=53)"/>
</subitem>
<subitem
label="Again, we inject a JDK logger, defined in the Resources class."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=57)"/>
</subitem>
<subitem
label="We inject a JSR-303 Validator to use it for validating the JPA entity attributes before passing it down to other classes."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=60)"/>
</subitem>
<subitem
label="We also inject instances of MemberRepository and MemberRegistration to act as delegates in this RESTful service."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=63,toLine=65)"/>
</subitem>
<subitem
label="The listAllMembers method processes all HTTP GET requests to the "/members" URI, providing a list of all Member instances, in a JSON response."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=69,toLine=73)"/>
</subitem>
<subitem
label="The lookupMemberById method processes HTTP GET requests to a URI with path template "/members/{id}". It provides a single Member instance (whose id matches the provided id in the URI), as response of type JSON."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=75,toLine=84)"/>
</subitem>
<subitem
label="The createMember method processes all HTTP POST requests to the "/members" URI. It consumes a POST request with a body containing a JSON object representing a Member instance. The JAX-RS provider de-serializes the POST body into a Member. It validates the provided Member, registers it if the Member is valid, and creates a HTTP response, It provides the newly registered Member instance as a JSON object, in the response."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=90,toLine=121)"/>
</subitem>
<subitem
label="The validateMember method is a private method whose responsibility is to validate the provided Member instance for violations of the declared constraints, and also to verify if the supplied email of a Member is unique. It uses the JSR-303 validator instance to validate the Member. Any constraint violations reported by the validator are rethrown as a ConstraintViolationException."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=137,toLine=149)"/>
</subitem>
<subitem
label="The createViolationResponse is used to construct a meaningful HTTP response when violations of declared constraints are found by the JSR-303 validator. Every violation is serialized with the name of the attribute that failed violation, and a message describing the violation."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=158,toLine=168)"/>
</subitem>
<subitem
label="The emailAlreadyExists method verifies for uniqueness of the email address in the supplied Member. It uses the MemberRepository to determine if an existing member with the same email can be found."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/rest/MemberService.java,fromLine=177,toLine=185)"/>
</subitem>
</item>
<item
skip="true"
title="Resources.java">
<description>
Now, let's take a look at the Resources class, which provides resources such as the entity manager. CDI recommends using "resource producers", as we do in this example, to alias resources to CDI beans, allowing for a consistent style throughout our application:
</description>
<subitem
label="We use the 'resource producer' pattern, from CDI, to 'alias' the old fashioned @PersistenceContext injection of the entity manager to a CDI style injection. This allows us to use a consistent injection style (@Inject) throughout the application. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/util/Resources.java,fromLine=40,toLine=42)"/>
</subitem>
<subitem
label="We expose a JDK logger for injection. In order to save a bit more boiler plate, we automatically set the logger category as the class name! "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/aaf/interfaces/util/Resources.java,fromLine=44,toLine=47)"/>
</subitem>
<subitem
label="If you want to define your own datasource, take a look at the Admin Guide for WildFly"
skip="true">
<command
required="false"
serialization="org.eclipse.ui.browser.openBrowser(url=https://docs.jboss.org/author/display/WFLY8/Admin+Guide#AdminGuide-Datasources)"/>
</subitem>
</item>
<item
skip="true"
title="Run and deploy the application">
<description>
Before you proceed, ensure that you have setup and configured a WildFly server.
<br/><br/>
Right-click the project and select <b>Run As</b> > <b>Run On Server</b> or click on the "Click to Perform" link below.
</description>
<!-- the runOnServer command is not implemented yet
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.actions.runOnServer(project=${currentProject})"/>
-->
<action
pluginId="org.jboss.tools.project.examples.cheatsheet"
class="org.jboss.tools.project.examples.cheatsheet.actions.RunOnServer"
param1="${currentProject}"/>
</item>
<item
skip="true"
title="Open the application in BrowserSim">
<description>
Locate the "Run BrowserSim" button on the toolbar and click it, or click on the "Click to Perform" link below.
This launches BrowserSim where you can simulate the execution of the application on a mobile browser.
Once you launch BrowserSim, navigate to the deployed application via the BrowserSim address bar. The application is usually accessible at this following link: <b>http://localhost:8080/jboss-Interfaces/</b>
</description>
<command
required="false"
serialization="org.jboss.tools.vpe.browsersim.eclipse.commands.runBrowserSim"/>
</item>
<item
skip="true"
title="Using LiveReload with the deployed application">
<description>
Once again in the Servers view, select the "jboss-Interfaces" deployment under the WildFly Runtime Server, and right-click on it.
Select the "Show In" entry in the menu, and open the deployed resource in a <b>Web Browser via LiveReload Server</b>. This launches the application in a web browser with the LiveReload scripts injected into it.
You can proceed to make changes to the <b>index.html</b> and it would immediately reflect in the opened Web Browser on saving the changes.
<br/><br/>
As is the case with LiveReload tooling, there is no need to refresh the web browser after you save the changes in the editor. At the same time, opening the application in this manner will allow the client-side JavaScript in <b>app.js</b> to access the <b>MemberResource</b> REST API on the server-side. You can make changes to the page without refreshing them while continuing to use the backend services deployed on WildFly.
<br/><br/>
<b>Note:</b> In the earlier section in the tutorial, where the <b>index.html</b> file was opened via the LiveReload Server, the file was not deployed in an application running on a WildFly server. Hence, it could not access the backend - and member details could not displayed and new members could not be added. We have just demonstrated how to overcome that problem.
</description>
</item>
<item
skip="true"
title="Arquillian">
<description>
If you've been following along with the Test Driven Development craze of the past few years,
you're probably getting a bit nervous by now, wondering how on earth you are going to test your application.
Lucky for you, the Arquillian project is here to help!
<br/><br/>
Arquillian provides all the boiler plate for running your test inside WildFly,
allowing you to concentrate on testing your application.
In order to do that, it utilizes Shrinkwrap, a fluent API for defining packaging,
to create an archive to deploy.
We'll go through the testcase, and how you configure Arquillian in just a moment,
but first let's run the test.
</description>
</item>
<item
skip="true"
title="Start Arquillian tests">
<description>
Arquillian defines two modes, managed and remote.
The managed mode will take care of starting and stopping the server for you,
while the remote mode connects to an already running server.
<br/><br/>
The following action starts the test in the <b>remote</b> mode because you have started the server in the previous step.
<br/>
Right-click the project, select <b>Properties>Maven</b> and
enter <b>arq-jbossas-remote</b> to the <b>Active Maven Profile</b> field.
After that, right-click the project and select <b>Run As>JUnit test</b>.
<br/><br/>
After performing this action, you should see a green bar in the <b>JUnit</b> view!
All three tests should have completed successfully.
</description>
<!-- the launchJUnitTest command is not implemented yey
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.actions.launchJUnitTest(project=${currentProject}, activateProfile=arq-wildfly-remote)"/>
-->
<action
pluginId="org.jboss.tools.project.examples.cheatsheet"
class="org.jboss.tools.project.examples.cheatsheet.actions.LaunchJUnitTest"
param1="${currentProject}"
param2="arq-wildfly-remote"/>
</item>
<item
skip="true"
title="MemberRegistrationTest.java">
<description>
So far so good, the test is running. But what does the test look like?
</description>
<subitem
label="@RunWith(Arquillian.class) tells JUnit to hand control over to Arquillian when executing tests."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=49)"/>
</subitem>
<subitem
label="The @Deployment annotation identifies the createTestArchive static method to Arquillian as the one to use to determine which resources and classes to deploy "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=51)"/>
</subitem>
<subitem
label="We add just the classes needed for the test, nothing more "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=55,toLine=56)"/>
</subitem>
<subitem
label="We also add persistence.xml as our test is going to use the database "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=57)"/>
</subitem>
<subitem
label="Of course, we must add beans.xml to enable CDI."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=58)"/>
</subitem>
<subitem
label="Finally, we add a test datasource, so that our test data doesn't overwrite the production data."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=59)"/>
</subitem>
<subitem
label="Arquillian allows us to inject beans into the test case."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=62,toLine=63)"/>
</subitem>
<subitem
label="The test method works as you would expect - creates a new member, registers them, and then verifies that the member was created "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/aaf/interfaces/test/MemberRegistrationTest.java,fromLine=68,toLine=76)"/>
</subitem>
</item>
<item
skip="true"
title="arquillian.xml">
<description>
As you can see, Arquillian has lived up to the promise - the test case is focused on what to test
(the @Deployment method) and how to test (the @Test method).
It's also worth noting that this isn't a simplistic unit test - this is a fully fledged integration
test that uses the database.
<br/><br/>
Now, let's look at how we configure Arquillian.
First of all, let's take a look at <b>arquillian.xml</b> in <b>src/test/resources</b>.
</description>
<subitem
label="Arquillian deploys the test war to WildFly, and doesn't write it to disk. For debugging, it can be very useful to see exactly what is in your war, so Arquillian allows you to export the war when the tests runs "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/resources/arquillian.xml)"/>
</subitem>
</item>
<item
skip="true"
title="pom.xml">
<description>
Now, we need to look at how we select between containers in the <b>pom.xml</b>.
<br/><br/>
Note - Depending on your preferences, when you 'Click to perform' the following steps, the pom.xml file opens by default in the "Overview" view. Click on the "pom.xml" view to see the lines of code in the file.
</description>
<subitem
label="The profile needs an id so we can activate from Eclipse or the command line "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/pom.xml,fromLine=317,toLine=342)"/>
</subitem>
<subitem
label="Arquillian decides which container to use depending on your classpath. Here we define the remote WildFly container. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/pom.xml,fromLine=331,toLine=345)"/>
</subitem>
</item>
<item
skip="true"
title="Arquillian project page">
<description>
And that's it! As you can see Arquillian delivers simple and true testing.
You can concentrate on writing your test functionality, and run your tests in the same environment in which you will run your application.
<br/><br/>
Arquillian also offers other containers, allowing you to run your tests against Weld Embedded (super fast, but your enterprise services are mocked), GlassFish, and more.
<br/><br/>
You can find more info on Arquillian on the Arquillian project page.
</description>
<command
required="false"
serialization="org.eclipse.ui.browser.openBrowser(url=http://www.jboss.org/arquillian)"/>
</item>
<item
skip="true"
title="Create your own application ">
<description>
What we didn't tell you about the <b>Interfaces quickstart</b> is that it is generated from a Maven archetype.
You can use this archetype to generate your own project.
<br/><br/>
Simply select <b>Help>JBoss Central</b> and click the <b>HTML5 Project</b> wizard.
<br/>
You will get a brand new project with the same functionality as <b>Interfaces</b>,
but customized with your details.
</description>
</item>
</cheatsheet>