-
Notifications
You must be signed in to change notification settings - Fork 0
/
.cheatsheet.xml
695 lines (666 loc) · 34.9 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
<?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="CDI + JSF + EJB + JTA + Bean Validation + JAX-RS + Arquillian: Samba-Personal-Project quickstart">
<intro>
<description>
This quickstart shows off all the new features of Java EE 7, and makes a great starting point for your project.
<br/><br/>
<b>Bean Validation 1.1</b>
<br/><br/>
Bean Validation 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/>
<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.
</description>
</intro>
<item
skip="false"
title="The Samba-Personal-Project example in depth">
<description>
The Samba-Personal-Project application shows off a number of Java EE technologies such as CDI, JSF, EJB, JTA, JAX-RS and Arquillian.
It does this by providing a member registration database, available via JSF 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> and <b>faces-config.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 in <b>WEB-INF/classes/META-INF</b>
(which can be found in the <b>src/main/resources</b> directory of the example) — <b>persistence.xml</b>,
which sets up JPA, and <b>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
title="default.xhtml">
<description>
Next, let's take a look at the JSF view the user sees. As usual, we use a template to provide the sidebar and footer. This one lives in <b>WEB-INF/templates/default.xhtml</b>:
</description>
<subitem
label="We have a common <head> element, where we define styles and more. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/WEB-INF/templates/default.xhtml,fromLine=22,toLine=26)"/>
</subitem>
<subitem
label="This application defines a common sidebar, putting them in the template means we only have to define them once."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/WEB-INF/templates/default.xhtml,fromLine=37,toLine=46)"/>
</subitem>
<subitem
label="and a common footer... "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/WEB-INF/templates/default.xhtml,fromLine=47,toLine=52)"/>
</subitem>
<subitem
label="The content is inserted here, and defined by views using this template. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/WEB-INF/templates/default.xhtml,fromLine=32,toLine=36)"/>
</subitem>
</item>
<item
title="index.xhtml">
<description>
That leaves the main page, index.xhtml, in which we place the content unique to the main page:
</description>
<subitem
label="The JSF form allows us to register new users. There should be one already created when the application started."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.xhtml,fromLine=33,toLine=62)"/>
</subitem>
<subitem
label="The application uses Bean Validation to validate data entry. The error messages from Bean Validation are automatically attached to the relevant field by JSF, and adding a messages JSF component will display them."
skip="true">
</subitem>
<subitem
label="Name validation">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.xhtml,fromLine=39,toLine=40)"/>
</subitem>
<subitem
label="Email validation"
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.xhtml,fromLine=43,toLine=44)"/>
</subitem>
<subitem
label="Phone number validation"
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.xhtml,fromLine=47,toLine=49)"/>
</subitem>
<subitem
label="This application exposes REST endpoints for each registered member. The application helpfully displays the URL to the REST endpoint on this page. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/webapp/index.xhtml,fromLine=86,toLine=90)"/>
</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:
</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/jboss/tools/examples/model/Member.java,fromLine=37)"/>
</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/jboss/tools/examples/model/Member.java,fromLine=38)"/>
</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/jboss/tools/examples/model/Member.java,fromLine=46,toLine=48)"/>
</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/jboss/tools/examples/model/Member.java,fromLine=53,toLine=53)"/>
</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/jboss/tools/examples/model/Member.java,fromLine=56,toLine=58)"/>
</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/jboss/tools/examples/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/jboss/tools/examples/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/jboss/tools/examples/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/jboss/tools/examples/data/MemberRepository.java,fromLine=51,toLine=58)"/>
</subitem>
</item>
<item
skip="true"
title="MemberListProducer.java">
<description>
Next, let's take a look at MemberListProducer, which is responsible for building the list of members, ordered by name. It uses JPA 2 criteria to do this.
</description>
<subitem
label="This bean is request scoped, meaning that any fields (such as members) will be stored for the entire request."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/data/MemberListProducer.java,fromLine=30)"/>
</subitem>
<subitem
label="The MemberRepository is responsible for interactions with the persistence layer"
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/data/MemberListProducer.java,fromLine=33,toLine=34)"/>
</subitem>
<subitem
label="The list of members is exposed as a producer method. It's also available via EL. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/data/MemberListProducer.java,fromLine=40,toLine=41)"/>
</subitem>
<subitem
label="The observer method is notified whenever a member is created, removed, or updated. This allows us to refresh the list of members whenever they are needed. This is a good approach as it allows us to cache the list of members, but keep it up to date at the same time."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/data/MemberListProducer.java,fromLine=46,toLine=48)"/>
</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 JSF page
</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/jboss/tools/examples/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/jboss/tools/examples/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/jboss/tools/examples/service/MemberRegistration.java,fromLine=43)"/>
</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/jboss/tools/examples/util/Resources.java,fromLine=43)"/>
</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/jboss/tools/examples/util/Resources.java,fromLine=47)"/>
</subitem>
<subitem
label="We expose the FacesContext via a producer method, which allows it to be injected. If we were adding tests, we could also then mock it out."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/util/Resources.java,fromLine=52)"/>
</subitem>
<subitem
label="If you want to define your own datasource, take a look at the Administration 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-DatasourceDefinitions/)"/>
</subitem>
</item>
<item
skip="true"
title="MemberController.java">
<description>
Of course, we need to allow JSF to interact with the services. The MemberController class is responsible for this:
</description>
<subitem
label="The MemberController class uses the @Model stereotype, which adds @Named and @RequestScoped to the class. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=34)"/>
</subitem>
<subitem
label="The FacesContext is injected, so that messages can be sent to the user."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=37)"/>
</subitem>
<subitem
label="The MemberRegistration bean is injected, to allow the controller to interact with the database."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=40)"/>
</subitem>
<subitem
label="The Member class is exposed using a named producer field, which allows access from JSF. Note that the named producer field has dependent scope, so every time it is injected, the field will be read "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=43,toLine=45)"/>
</subitem>
<subitem
label="The @PostConstruct annotation causes a new member object to be placed in the newMember field when the bean is instantiated."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=47)"/>
</subitem>
<subitem
label="When the register method is called, the newMember object is passed to the persistence service."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=54)"/>
</subitem>
<subitem
label="We also send a message to the user, to give them feedback on their actions."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=56)"/>
</subitem>
<subitem
label="Finally, we replace the newMember with a new object, thus blanking out the data the user has added so far. This works as the producer field is dependent scoped."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/controller/MemberController.java,fromLine=57)"/>
</subitem>
</item>
<item
skip="true"
title="JAX-RS">
<description>
Before we wrap up our tour of the Samba-Personal-Project example application,
let's take a look at how the JAX-RS endpoints are created. Firstly, {<b>JaxRSActivator</b>}},
which extends <b>Application</b> and is annotated with <b>@ApplicationPath</b>,
is the Java EE 6 <b>no XML</b> approach to activating JAX-RS.
</description>
<subitem
label="JaxRsActivator.java"
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/JaxRsActivator.java,fromLine=30, toLine=33)"/>
</subitem>
</item>
<item
skip="true"
title="MemberResourceRESTService.java">
<description>
The real work goes in MemberResourceRESTService, which produces the endpoint:
</description>
<subitem
label="The @Path annotation tells JAX-RS that this class provides a REST endpoint mapped to rest/members (concatenating the path from the activator with the path for this endpoint). "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=52)"/>
</subitem>
<subitem
label="The bean is request scoped, as JAX-RS interactions typically don't hold state between requests."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=53)"/>
</subitem>
<subitem
label="JAX-RS endpoints are CDI enabled, and can use CDI-style injection. "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=56)"/>
</subitem>
<subitem
label="CDI allows us to inject a Bean Validation Validator instance, which is used to validate the POSTed member before it is persisted."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=59)"/>
</subitem>
<subitem
label="MemberRepository is injected to allow us to query the member database "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=62)"/>
</subitem>
<subitem
label="MemberRegistration is injected to allow us to alter the member database."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=65)"/>
</subitem>
<subitem
label="The listAllMembers() method is called when the raw endpoint is accessed and offers up a list of endpoints. Notice that the object is automatically marshalled to JSON by RESTEasy (the JAX-RS implementation included in WildFly)."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=68,toLine=72)"/>
</subitem>
<subitem
label="The lookupMemberById() method is called when the endpoint is accessed with a member id parameter appended (for example rest/members/1). Again, the object is automatically marshalled to JSON by RESTEasy."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=74,toLine=83)"/>
</subitem>
<subitem
label="createMember() is called when a POST is performed on the URL. Once again, the object is automatically unmarshalled from JSON."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=89,toLine=120)"/>
</subitem>
<subitem
label="In order to ensure that the member is valid, we call the validateMember method, which validates the object, and adds any constraint violations to the response. These can then be handled on the client side, and displayed to the user."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=136,toLine=148)"/>
</subitem>
<subitem
label="The object is then passed to the MemberRegistration service to be persisted."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=100)"/>
</subitem>
<subitem
label="We then handle any remaining issues with validating the object, which are raised when the object is persisted."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/main/java/org/jboss/tools/examples/rest/MemberResourceRESTService.java,fromLine=104,toLine=117)"/>
</subitem>
</item>
<item
skip="true"
title="Run and deploy the application">
<description>
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="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>.
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=37)"/>
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=39)"/>
</subitem>
<subitem
label="We add just the classes needed for the test, no more "
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=42)"/>
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=43)"/>
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=44)"/>
</subitem>
<subitem
label="Finally, we add a test datasource, so that test data doesn't overwrite production data."
skip="true">
<command
required="false"
serialization="org.jboss.tools.project.examples.cheatsheet.openFileInEditor(path=/${currentProject}/src/test/java/org/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=46)"/>
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=49,toLine=50)"/>
</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/jboss/tools/examples/test/MemberRegistrationTest.java,fromLine=55,toLine=64)"/>
</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 pom.xml:
</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=238,toLine=314)"/>
</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=277,toLine=289)"/>
</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/>
More info on Arquillian you can find 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="Creating your own application ">
<description>
What we didn't tell you about the <b>Samba-Personal-Project quickstart</b> is that it is generated from a Maven archetype.
Using this archetype offers you the perfect opportunity to generate your own project.
<br/><br/>
In order to perform that, you should select <b>Help>JBoss Central</b> and click the <b>Java EE Web Project</b> wizard.
<br/>
You will get a brand new project with the same functionality as <b>Samba-Personal-Project</b>,
but customized with your details.
</description>
</item>
</cheatsheet>