You are on page 1of 262

www.it-ebooks.

info
Flex on J ava
BERNERD ALLMON
J EREMY ANDERSON
1 1
M A N N I N G
Gr eenwi ch
(74
ü
w. l ong. )
www.it-ebooks.info
For online information and ordering of this and other Manning books, please visit
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact
Special Sales Department
Manning Publications Co.
180 Broad St.
Suite 1323
Stamford, CT 06901
Email: orders@manning.com
©2011 by Manning Publications Co. Al l rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in
any form or by means electronic, mechanical, photocopying, or otherwise, without pri or written
permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial caps
or all caps.
©Recognizing the importance of preserving what has been written, it is Manning's policy to have
the books we publish printed on acid-free paper, and we exert our best efforts to that end.
Recognizing also our responsibility to conserve the resources of our planet, Manning books
are printed on paper that is at least 15 percent recycled and processed without the use of
elemental chlorine.
Manning Publications Co.
180 Broad St.
Suite 1323
Stamford, CT 06901
Devel opment Editors:
Copyeditor:
Typesetters:
Cover designer:
Nermi na Pascal-Miller
Sebastian Stirling
Betsey Henkels
Dennis Dalinnik
Marija Tudor
I SBN 9781933988795
Printed in the Uni ted States of America
1 2 3 4 5 6 7 8 9 10 - MAL - 16 15 14 13 12 11 10
www.it-ebooks.info
contents
foreword xi
preface xiii
acknowledgments xv
about this book xvii
author online xix
about the authors xx
about the cover illustration xxi
PARTI LAYING THE FOUNDATION 1
J Some Flex with your J ava? 3
1.1 A whirlwind tour of Flex 5
MXMLandActionScript 5' The Rex SDK 6
Flash Player 10 6
1.2 Creating an application in Flex 7
1.3 Finding the right tools and patterns 8
Building a Flex interface. 9 • Integrating with web
services 9 • Integration with BlazeDS, logging, and
messaging 10 • Securing Hex applica tions 10 • Crea ting
custom Flex controls with Dégrafa I I ' Desktop 2.0
with Adobe AIR I I ' Flex and Grails 11
1.4 Summary 11
V
www.it-ebooks.info
X C O N T E N T S
Beginning with J ava 12
2.1 Working with AppFuse 13
2.2 Generating the application structure with Maven 13
Download and install the J DK 14 • Download and install
MySQL 15 • Download and install Maven 15 • Create a
Maven multimodule project 16
1
Maven provides a build able
project 18* Running the NexBugs web application 19
2.3 Build the model objects 20
2.4 Build the DAOs 23
2.5 Build the services 24
2.6 Wiring things together with Spring 2V
2.7 Constructing the web tier 28
Building Struts 2 action classes 28 • Editing the issue
menu item 30 • Adding J SP resources 30 • Adding
property resources 33 • Configuring the struts.xml 34
Configuring Hibernate 36
2.8 Summary 37
Getting rich with Flex 38
3.1 Generating the application structure 38
3.2 Configuring the flex-bugs-ria module 40
3.3 Configure Maven for the flex-bugs-web module 42
3.4 Adding a wrapper for our SWF 44
3.5 "Hel l o Worl d!" in Flex 44
3.6 Developing the FlexBugs application 46
Introducing ViewStack 47 * HeaderView 49 • FooterView
Master view 52 • Detail view 53 • Commen ts view 54
3.7 Laying out the components 55
3.8 Creating a pop-up component 57
3.9 The finished application 58
3.10 Summary 59
Connecting to web services 60
4.1 Model View Presenter 61
4.2 Web services in Flex 62
4.3 Dispatching and handling events 63
Creating a custom ei>ent, 63 • Event, dispatching 64
www.it-ebooks.info
C O N T E N T S vi i
4.4 Creating Issue and Comment transfer objects 65
4.5 Enhancing the master view 66
Creating a Presenter for the master view 67 * Creating an
Issue Model 69 • Updating the master view 70
4.6 Enhancing the detail view 72
Creating a DetailPresenter 72 • Updating the
IssueModel 75 • Updating the detail view 76
4.7 Enhancing the comments view 77
Creating a comments presenter 77 • Creating a
comment model 80 • CommentView 81
4.8 Adding a pop-up form for editing comments 83
Updating the CommentPresenter 83 • Updating the
CommentModel 85 • Creating the pop-up
component 85* Updating CommentsListView 87
4.9 Summary 88
PART I I BLAZEDS REMOTING 89
5
BlazeDS remoting and logging 91
5.1 Introducing BlazeDS 92
5.2 Getting BlazeDS 93
5.3 Building a BlazeDS configuration Maven module 94
Configuring BlazeDS 96
5.4 Exposingjava services to Flex remoting 100
Web module configura tion upda tes 100 • Expose AMF
remoting destinations 102
5.5 Connecting to J ava with BlazeDS 104
5.6 Loggi ng 105
BlazeDS logging 105 • Built-in BlazeDS benchmarking 107
5.7 Summaiy 110
Flex messaging 112
6.1 Setting up BlazeDS for messaging 113
Modifying the
:
services-config.xml 113 • Updating the
webapp server-side module 114
www.it-ebooks.info
viii C O N T E N T S
6.2 Modifying the client for messaging 117
Creating a ChannelSetFactory 117 • Changing
the IssueModel 118
6.3 Summaiy 120
PART I I I THE J OYS OF FLEX ON J AVA 121
7
8
Securing and personalizing your application 123
7.1 Authentication 124
Modifying the ChannelSetFactory 124 • Creating a
UserEvent 125 • Creating a login panel 126 • Creating a
login Presenter 128 • Creating a login manager 130
Upda ting the header 131 • Enabling security for Flex 132
7.2 Authorization 133
Hex Spring Security primer 133 • Spring Integration
Security 135 • @Secured annotations 135
Overriding default security settings 137 • Updating
IssueModel and CommentModel 138
7.3 Personalization 139
Adding the• UserServiceto the
:
LoginModel 140 • Updating
the LoginPresenter 141 • Updating the DetailPresenter
and CommentsListPresenter 142
7.4 Summaiy 145
Charting with Degrafa 147
8.1 Drawing in Flex 148
8.2 Common Degrafa concepts 149
8.3 Creating a pie chart for fun and profit 150
New custom ei>ent. 151 • PieChart component 152
PieChartSlice 154 • Custom ItemRenderer 155 • Presenter
for the PieChart 156 • Model for the PieChart, 158
8.4 Adding your pie chart to the application 159
Updating the GraphView 159 • Creating a Presenter for
the GraphView 161 • Creating the graph model 163
8.5 Beyond the example 165
8.6 Summaiy 167
www.it-ebooks.info
X C O N T E N T S
Desktop 2.0 with AIR 168
9.1 Creating a common library 169
Creating an SWC project 170 ' Extracting common
classes 172 ' Extracting a MainCanvas 172
9.2 Creating the AI R application 174
9.3 Packaging the AI R application 176
Crea ting a project to package the AIR app 177 * Genera ting
a certificate 177 * Adding icons 178 * Adding the AIR
configuration 179 * Configuring the package build 180
9.4 Distributing the AI R application 186
Assembly configuration 187 * Updating the
build 187 * Creating a download badge 189
9.5 Summaiy 191
Testing your Flex application 192
10.1 Unit testing and TDD 193
10.2 Updating the project 194
10.3 Testing the Presenter 196
Testing refresh issues 198* Issues result event
test 199* Testing issue removed 200
Remove issue result test 201
10.4 Testing the View 202
Testing the issues set property 203 * Testing resetlssueGrid
function 204 * Testing refresh issues button click 204
Testing DataGrid item select 205
10.5 Testing the Model 206
Mocking and Remote-Object 207 * Testing
getlssues 209 * Testing get single issue 209
10.6 Continuous integration with Hudson 210
Downloading and installing Hudson 211 * Configuring
Hudson 211 * Con figuring a Hudson job 214
10.7 Summaiy 217
Flex on Grails 218
11.1 Why Groovy and Grails? 218
11.2 Downloading and installing Grails 219
www.it-ebooks.info
X C O N T E N T S
11.3 Creating the Grails application 220
Create the Contact domain model 221 • Create the
ContactService 222 • Bootstrap sample data 223
11.4 Getting rich with Flex 223
Installing the Flex plugin 223 • Creating the domain classes
in Flex 224 • Creating the Flex application 225 • Adding the
RemoteSeruice 228 • Putting it all together 228
11.5 Install the Grails J MS and Acti veMQ plugins 229
11.6 Add the Acti veMQ Spring bean 230
11.7 Subscribe the Flex client to the Grails J MS service 230
Update the services-config.xml 231 • Modifying the
ContactService 232 • Update the Main, mxml 233
11.8 Summary 234
index 235
www.it-ebooks.info
foreword
Every ten to fi fteen years there is a radical software paradi gm shift. Many of us experi -
enced di e last shift as di e web gai ned momentum and software was rebui l t for a new
and game- changi ng depl oyment model . Today we are in di e midst of anodi er great
software paradi gm shift. User and business needs now requi re software to be mor e
usable, extensible, and portabl e.
Ri ch I nternet Appl i cati ons (RI As) represent a new generati on of software. As the
name implies, RIAs provi de users with a rich and interactive experi ence. At the same
time, they offer the ease of depl oyment that made early web applications so successful.
RIAs are the future of software because they combi ne the strengths of the web deploy-
ment model with the ful l client capabilities of thick-client software.
Since 2004 Adobe Flex has been di e most prol i fi c tool ki t for bui l di ng RIAs. A pri-
mary advantage of Flex for RIA devel opment is that it integrates easily with any back-
end technol ogy. By provi di ng native XML, SOAP, and Data Remoti ng capabilities, Flex
enables devel opers to bui l d rich new UIs on top of existing services. For J ava devel op-
ers this combi nati on is especially compel l i ng because many J ava systems have already
embraced service-oriented architectures with SOAP Web Services, Spring, or one of
numerous other technol ogi es.
The uni on of J ava on the backend and Flex on di e fr ontend is so powerful that
hundreds of thousands of devel opers have already embraced this new paradi gm to
create better software. You've probabl y pi cked up this book because you want to do
the same tiling—build better software. We all want to build software that we are proud
of—software that users will love. Flex on J ava will teach you how to do j ust that.
xi
www.it-ebooks.info
xi i F O R E W O R D
Ther e are many aspects to bui l di ng great software. I f software l ooks sexy but does
not per for m wel l or is not mai ntai nabl e, its val ue is di mi ni shed. What I l ove about this
book is that it teaches a holistic approach to bui l di ng great software wi th Fl ex and
J ava. As you woul d expect, you wi l l l earn how to create ri ch data visualizations. But,
j ust as i mportantl y, you wi l l l earn how to effi ci entl y move data between the cl i ent and
server using BlazeDS, set up uni t tests, add security to an appl i cati on, and mor e. These
are the pr obl ems we have to solve i n real software. Knowi ng how to address these fun-
damental issues frees us to focus on what matters most—cr eati ng software that users
wi l l l ove.
These are exci ti ng times for software devel opers! Today we are bui l di ng the next
gener ati on of software—a gener ati on that will be r emember ed as the first to be
usable, beauti ful , and truly hel pful . Flex on J ava empowers you to create that future! I
l ook forward to seei ng the future that YOU bui l d wi th Fl ex and J ava.
J AMES WARD
TECHNICAL EVANGELIST FOR FLEX AT ADOBE
www.j amesward.com
www.it-ebooks.info
preface
I f you'd asked me a few years ago i f I 'd ever write a book, I woul d have l aughed at the
thought. Al l through hi gh school and col l ege I l oathed wri ti ng anything mor e than a
short answer, and when it came to wri ti ng papers, I was usually one of the peopl e ask-
i ng about the mi ni mum l ength requi red for a passing grade. Now here we are, thou-
sands of words and hundreds of pages later, and BJ and I have survived wri ti ng our
first book, twice.
So how di d I go fr om absolutely l oathi ng wri ti ng to bei ng wi l l i ng to dedi cate so
many nights and weekends to wri ti ng this book? Since the first 1.0 release of the Flex
framework, I 've been a fan. I di scovered Flex whi l e I was distaining HTML/ J avaScript
and browser compatibility issues. I was trying to prototype a form-heavy appl i cati on
with compl ex business rules and validation, struggling with goofy layout issues and
J avaScript errors, and was l ooki ng for a better solution. Al though it's possible to make
ri ch web applications using HTML and J avaScript, it's easy to make ugly ones. Most of
the ni ce AJ AX frameworks we take for granted today di dn't exist at the time, and many
devel opers had absolutely no idea what AJ AX was.
One night, whi l e searching for an alternative, I ran across this excel l ent framework
that al l owed you to write Flash-based applications using a declarative syntax and a pro-
totypi ng scripting l anguage similar to J avaScript, wi thout the cross browser issues
because it all ran in the Flash Player. So I pi cked up a copy of Developing Rich Clients
with Macromedia Flex by Steven Webster and Alistair McL eod and i mmedi atel y fel l in
l ove with the Flex framework. Ther e was only one probl em: it was expensive. I t was
goi ng to be a hard sell for any but the largest projects.
www.it-ebooks.info
xi v P R E F A C E
Fl ex effecti vel y dr opped off my radar as bi l l abl e proj ects took pr ecedence, and I
di dn't have the ti me or desi re to work on any side proj ects. Then in 2007 Adobe
announced that it woul d open source the Fl ex fr amewor k and porti ons of the Li ve-
Cycle Data Services server components as an open source pr oj ect of its own cal l ed
BlazeDS. When I heard this announcement I fi gur ed it was time to start l earni ng Fl ex
agai n. I had di scovered a sel f-publ i shed book cal l ed Flexible Rails, about i ntegrati ng Fl ex
wi th Ruby on Rails, and because I was al ready l earni ng Ruby on Rails, this book was a
good choi ce. So I purchased the PDF and a few short weeks l ater the author, Peter Ar m-
strong, announced that Manni ng Publ i cati ons was goi ng to publ i sh the book.
Bei ng a J ava devel oper for most of my professi onal career, I began to think about
the lack of good books on i ntegrati ng Fl ex wi th a server-side backend. Ther e was a
pl ethora of Fl ex books available on the market; however most wer e wri tten fr om the
perspecti ve of a Flash devel oper and used techni ques that woul d make any seasoned
J ava devel oper cri nge. Few discussed connecti ng to ei ther Li veCycl eDS or BlazeDS. So
I pr oposed the i dea of wri ti ng a book on Fl ex fr om a web devel oper perspecti ve to
Mi chael Stephens at Manni ng.
The book took many shapes. At one time, we contempl ated wri ti ng a book on both
J ava and .NET wi th Fl ex; we fi nal l y settled on an early versi on of what you now hol d i n
your hands. The mai n premi se of the book is that you can add a Fl ex fr ontend to an
exi sti ng appl i cati on. The first versi on of this book attempted to use an exi sti ng open
source J ava web appl i cati on as its sampl e appl i cati on. When we wer e about two-thirds
of the way through the book, we real i zed that the sampl e appl i cati on wasn't worki ng
as i ntended. We' d pl anned to have a sampl e appl i cati on that woul d be mor e than j ust
a throwaway. We wanted the readers to devel op an appl i cati on that woul d i ncorporate
techni ques they coul d appl y to thei r everyday work, but not somethi ng so compl ex
that it woul d distract readers fr om what we wer e tryi ng to accompl i sh—demonstrati ng
Fl ex and J ava.
After much refl ecti on and discussion on the sampl e appl i cati on, we deci ded to
scrap it and use AppFuse, an open source pl atfor m for quickly bui l di ng J ava web appli-
cations, as the basis for our appl i cati on. Thi s al l owed us to construct a sampl e applica-
tion i n j ust one short chapter. AppFuse pr ovi ded many functi ons out of the box that
we woul d have otherwi se had to spend ti me discussing and setting up. Unfortunatel y
this also meant that much of what we had al ready wri tten had to be changed, but I feel
this was a necessary change for the better.
Her e we are, two years later, wi th a fi nal pr oduct that I can proudl y say I hel ped to
wri te. I hope that you enj oy this book and that it hel ps you i n your j our ney of i ntegrat-
i ng Fl ex i nto your everyday work.
J EREMY ANDERSON
www.it-ebooks.info
acknowledgments
Thi s book woul d not have been possible i f not for the hard work of many peopl e.
We'd like to thank everyone at Manni ng, especially Mai j an Bace and Mi chael Ste-
phens, for gi vi ng us the opportuni ty to wri te—and rewri te—the book. Wi thout the
hard work and dedi cati on of our devel opment editors, Nermi na Pascal-Miller and
Sebastian Stirling, this book woul d not have happened. Thanks for your gui dance
and encouragement. Thanks to Karen Tegtmeyer, our review editor, for arrangi ng
the peer reviews and to Stephen Hong, for hel pi ng to market and pr omote the book.
The rest of Manni ng's staff was patient and supportive and provi ded us with invalu-
able assistance to hel p make this book a success, in particular our copyedi tor Betsey
Henkel s and our pr oofr eader Elizabeth Marti n.
Special thanks go to Ri chard Dammkoehl er for doi ng such an excel l ent j ob in his
technical review of the fi nal manuscript shortly befor e it went to press.
We'd also like to express our thanks to Mi chael Kimsal for publishing a two-part
article based on the Grails chapter of this book in the excel l ent GroovyMag.
Thank you to Matt Rai bl e for gi vi ng us AppFuse, whi ch al l owed us to bui l d a sam-
pl e appl i cati on in j ust one short chapter, and for pr omoti ng our book in his travels.
Thanks to the Adobe team for gi vi ng the Flex framework, BlazeDS, and mor e to
the open source community.
Thanks to Marvi n Froeder (also known as Vel o) for his hard work in devel opi ng
the Fl exMoj os Maven pl ugi n, whi ch we use extensively throughout the book.
Thank you to Gi acomo "Pel di " Guilizzoni, founder of the outstanding Balsamiq
Mockups tool (a fi ne exampl e of an Adobe AI R appl i cati on) for provi di ng us with
xv
www.it-ebooks.info
xvi A C K N O W L E D G M E N T S
licenses. Many of di e mockups you see as illustrations throughout this book were cre-
ated using this tool .
Thanks to the fol l owi ng reviewers who read di e manuscript at di fferent stages of its
devel opment and contri buted invaluable feedback: J eremy Flowers, Sopan Shewale,
Rick Evans, Chri stophe Bunn, Phi l Hanna, Ni kol aos Kaintantzis, J ohn Gri ffi n, Doug
Warren, Brian Curnow, and Peter Pavlovich. Thanks also to everyone who contri buted
on di e MEAP forum.
Last but not least, thank you to J ames Ward for contri buti ng the for ewor d to
our book.
Jeremy Anderson
F d like to thank God for blessing me with the talent necessary to write this book.
Second only to God is my wi fe Karla, who had the pati ence to see me through this
and keep me on task. To my chi l dren, Emily and Isaac, thanks for al l owi ng Daddy to
hi de in his basement offi ce to write. Wi thout their support, understanding, and sacri-
fi ce, this book woul d not have been possible.
Next, bi g thanks to my coauthor and partner in crime, BJ . I f he hadn't j oi ned me
on this venture, there mi ght not have been a Flex on J ava.
Thanks to everyone at Pillar Technol ogy, especially Gary Gentry, Bob Meyers, Chris
Beale, Patrick Welsh, Matt VanVl eet, Ri ch Dammkoehl er —and everyone else who pro-
vi ded support.
Thank you to Carl Erickson and everyone at Atomi c Obj ect for hel pi ng me solidify
my i nterpretati on of di e Passive Vi ew pattern in the sample application.
BJ Al l mon
Thanks to my God and Father in heaven who is the author of l i fe. Your l ove
endures forever.
I 'm humbl ed by the pati ence and di e l ove demonstrated to me by my wonder ful
bri de Sarah and our kids Hannah, Zacharee, Elliot, and J ennessee. Thank you for
al l owi ng me to steal preci ous ti me away to work on this book. I l ove you so much!
Wi thout my coauthor J eremy Anderson's talent and thoughtfulness, I woul dn't
have been able to contri bute to this proj ect. Thank you J eremy for your hard work in
l eadi ng this proj ect!
Others who have hel ped me al ong in myj our ney i ncl ude Bob Myers, Chri stopher
J udd, Kevi n Smith, Charlie Close, Gary Gentry, Ri chard Dammkoehl er, Matt Van Vl eet,
Randy Thomas, and Dan Wi ebe; di e many talented devel opers at Pillar Technol ogy
Group i ncl udi ng Mark Flickinger, Ankur Gupta, Beth Seabl oom, and Shawn Steinb-
runner; the wonder ful staff at Mettl er- Tol edo; di e entire staff at Click4Care; the Dela-
ware City Vi neyard, Vi neyard Church Delaware County, Vi neyard Columbus; and my
extended family.
www.it-ebooks.info
about this book
Ther e are many books available that are purposed for teachi ng technol ogy topics
inside and out. These books are necessary for understandi ng how to use a technol ogy
correctly but many times are not meant to teach you what a normal day of a devel op-
ment woul d l ook like using that technol ogy. Thi s book was wri tten to demonstrate prac-
tical devel opment with two powerhouse technol ogi es, Flex on J ava. I t will gui de you in
bui l di ng your own applications that scale for real-world business needs, l eavi ng you
feel i ng equi pped with the fundamental s that are perti nent to the software feature or
task at hand.
Thr oughout the book, the fundamental s of bui l di ng testable and ri ch UIs that
communi cate with a powerful server side are brought together in bite-sized chunks.
The topi c of bui l di ng a robust Flex cl i ent that sits on top of a J ava server-side applica-
ti on will be discussed throughout as it pertains to the i ntegrati on of the two and pass-
i ng data back and forth.
Al ong with the mai n topic of i ntegrati ng Flex with J ava, topics such as Maven,
Spri ng i ntegrati on, addi ng security and personalization, charting, messaging, AI R
desktop applications, l oggi ng, continuous i ntegrati on, AppFuse, and even Flex on
Grails will be demonstrated.
Who shoul d read t hi s book
Thi s book is geared toward devel opers with a need for creating rich applications, on a
budget, with Flex 4 and J ava. Al l the tools we use for our exampl es are open source or
fr ee and very proven.
xvii
www.it-ebooks.info
xviii A B O U T T H I S B O O K
Thi s book assumes familiarity with software devel opment in general , specifically
Flex and J ava. Though it was wri tten with the i ntent to teach i ntegrati on techniques
for Flex and J ava, not l anguage fundamentals, it was done so to make it easy for even
Flex or J ava begi nners to get rol l i ng quickly with both.
How t he book i s organi zed
Flex on J ava is made up of three parts:
• Part 1 Getti ng started
• Part 2 Strengtheni ng the backend
• Part 3 Goi ng above and beyond
We start off by i ntroduci ng the two technol ogi es and bui l di ng a sample J ava applica-
tion you can play with. We go on to build a Flex cl i ent for the J ava appl i cati on that ties
i nto some J ava web services. Part 1 covers the first four chapters.
I n chapters 5 and 6 we dive deeper i nto backend i ntegrati on with J ava on the
server side. Part 2 i ntroduces topics that allow Flex to connect to J ava through obj ect
remoti ng, l oggi ng, and messaging. Usi ng the Spri ng Framework for Flex i ntegrati on is
very powerful and we demonstrate how that can be done.
Part 3, chapters 7-11, covers topics that are off the beaten path, such as security
and personalization, bui l di ng graphs, desktop devel opment with AI R, unit testing, and
bui l di ng a Flex and Grails application.
Code convent i ons
Al l source code in listings or in text is in a f i xed- wi dt h font l i k e t hi s to separate it
fr om ordi nary text. Code annotations accompany many of the listings, hi ghl i ghti ng
i mportant concepts. I n some cases, numbered bullets link to explanations that fol l ow
the listing. At times, only the i mportant segments of a code listing are displayed on the
page. The source code for all of the exampl es in ful l can be downl oaded fr om the pub-
lisher's website atwww.manni ng.com/ Fl exonJ ava.
www.it-ebooks.info
Author Online
The purchase of Flex on J ava includes free access to a private for um run by Manni ng
Publications where you can make comments about di e book, ask technical questions,
and recei ve hel p fr om di e autiiors and oti i er users. To access and subscribe to di e
forum, poi nt your browser to www.manning.com/ FlexonJ ava. Thi s page provi des
i nformati on on how to get on the for um once you are registered, what kind of hel p is
available, and the rules of conduct in the forum.
Manni ng's commi tment to our readers is to provi de a venue where a meani ng-
ful di al ogue between individual readers and between readers and di e autiiors can
take place. It's not a commi tment to any specific amount of participation on the
part of the autiiors, whose contri buti on to the book's for um remains voluntary
(and unpai d). We suggest you try asking di e authors some chal l engi ng questions,
lest their interest stray!
The Author Onl i ne for um and di e archives of previous discussions will be accessi-
bl e fr om di e publisher's website as l ong as the book is in print.
xi x
www.it-ebooks.info
about the authors
J EREMY ANDERSON is a software devel oper for Pi l l ar Technol ogy Group, an Agi l e con-
sulting fi r m i n the Mi chi gan and Ohi o Val l ey r egi on. He is a sel f- procl ai med autodi -
dact, constantly ti nkeri ng wi th cutti ng edge technol ogi es such as Groovy, Grails, and
Fl ex. He's been devel opi ng web-based appl i cati ons on the J VM in one shape or
another for over fi ve years. When he's not sitting behi nd a keyboard hacki ng away at
code, you can usually fi nd hi m out on the single-track on his bi ke or someti mes even
on foot. He someti mes has ti me to update his bl og http:/ / bl og.code- adept.com.
BJ ALLMON is a software devel oper for Pi l l ar Technol ogy Group. He enj oys participat-
i ng in l ocal user groups and confer ences and becomi ng a mor e seasoned software
practi ti oner. When he is not dabbl i ng i n software devel opment he can be found
spendi ng ti me wi th his fami l y of six and pl ayi ng the six-string.
xx
www.it-ebooks.info
about the cover illustration
The fi gure on the cover of Flex on J ava is a "Soldier." The illustration is taken fr om a
col l ecti on of costumes of di e Ottoman Empi re publ i shed on J anuary 1, 1802, by Wi l -
l i am Mi l l er of Ol d Bond Street, London. The tide page is missing fr om di e collec-
ti on and we have been unable to track it down to date. The book's table of contents
i denti fi es di e fi gures in both English and French, and each illustration bears di e
names of two artists who worked on it, both of whom woul d no doubt be surprised
to fi nd di ei r art graci ng di e front cover of a computer pr ogr ammi ng book...two hun-
dred years later.
The col l ecti on was purchased by a Manni ng edi tor at an antiquarian fl ea market in
the "Garage" on West 26th Street in Manhattan. The seller was an Ameri can based in
Ankara, Turkey, and di e transaction took place j ust as he was packi ng up his stand for
the day. The Manni ng edi tor di d not have on his person the substantial amount of
cash that was requi red for the purchase and a credi t card and check were both pol i tel y
turned down. Wi ti i di e seller fl yi ng back to Ankara tiiat eveni ng the situation was get-
ting hopeless. What was di e solution? I t turned out to be noti i i ng mor e than an old-
fashi oned verbal agreement sealed witii a handshake. The seller simply proposed that
the money be transferred to hi m by wi re and di e edi tor wal ked out witii the bank
i nformati on on a pi ece of paper and the por tfol i o of images under his arm. Needl ess
to say, we transferred di e funds di e next day, and we remai n grateful and impressed by
this unknown person's trust in one of us. I t recalls somethi ng that mi ght have hap-
pened a l ong ti me ago.
www.it-ebooks.info
xxi i A B O U T T H E C O V E R I L L US T R A T I ON
The pictures fr om the Ottoman col l ecti on, like the other illustrations that appear
on our covers, bri ng to l i fe the richness and variety of dress customs of two centuries
ago. They recall the sense of isolation and distance of that per i od—and of every other
historic per i od except our own hyperki neti c present. Dress codes have changed since
then and the diversity by regi on, so ri ch at the time, has faded away. I t is now often
hard to tell the inhabitant of one conti nent fr om another. Perhaps, trying to view it
optimistically we have traded a cultural and visual diversity for a mor e vari ed personal
l i fe. Or a mor e vari ed and interesting intellectual and technical l i fe.
We at Manni ng celebrate the inventiveness, the initiative, and, yes, the fun of the
computer business with book covers based on the ri ch diversity of regi onal l i fe of two
centuries ago, brought back to l i fe by the pictures fr om this col l ecti on.
www.it-ebooks.info
Part 1
Laying the foundation
J L ar t 1 lays the foundati on of Flex on J ava by touri ng Flex, J ava, and other sup-
porti ng technol ogi es that you will use throughout the book.
I n these first four chapters, you will bui l d a sample J ava web appl i cati on to
use with numerous code exampl es throughout the book. The J ava web applica-
ti on is built using a service-oriented architecture (SOA).
After maki ng a whi rl wi nd tour of Flex (chapter 1), your first step (chapter 2)
is to create a J ava appl i cati on that will expose web services you will later use to
connect to them fr om a Flex client.
I n chapter 3, you will create a Flex appl i cati on and words like AppFuse, Flex
Moj os, and FNA enter your vocabulary.
The focus of chapter 4 is to conti nue bui l di ng the client-side appl i cati on and
you will begi n bui l di ng a Flex client that will connect to the J ava web services
that you will choose to expose.
www.it-ebooks.info
Some Flex iimh
your J oBi
?
Thi s chapt er covers
• A b ri e f h i s t o ry o f J a v a a n d F le x
• A w h i rl w i n d t o u r o f F le x
• M X M L a n d A c t i o n S c ri p t
I n 1995, Sun i ntroduced the first J ava pl atform and gave birtii to di e applet which
allowed J ava applications to run inside di e browser with rich functionality and all
the benefits of di e J ava framework, including connecti ng to di e server side. The
applet became hugely popular for a coupl e of years before its popularity waned
mainly because of probl ems surrounding di e browser plugin.
Macromedi a embraced the idea of having a dedicated runtime envi ronment for
the browser, like di e J ava applet, and in 1997 released di e Flash Player. Adobe has
since taken over di e rights to di e Macromedi a suite of products and hel ped to
evolve what is now di e Flex framework and devel opment API .
Building features in an applet fr om scratch or even witii other rich imple-
mentations can be expensive compared to di e simplicity of using di e Flex frame-
work. Figure 1.1 displays a simple J ava applet data gri d next to a Flex data grid.
The Flex data gri d right out of di e box not only looks better tiian di e applet, it's
3
www.it-ebooks.info
Spreadsheet
27 CHAPTER 1 Some Flex with your J ava ?
kim. a
I I HI '
- i c D a c
d I .. I —Euntpb
R**«. l.r^^y Terri tory Rep Actual Elti AUl*
T & Sevthw**t
V &A
<0000
10000
aoooo
k| Q South«*tt Mm Barbara J-ennm-gp 36865 <0000
10000
aoooo
Q *Outhw»»t
¥ L3 Central Cali forni a
[J Seutti vwi t
* U Nevada
• Northern Cali forni a
Central Cali forni a
Dana Hmn
Jo« Smi th
29885
291X4
<0000
10000
aoooo
• _j Southern Cahfornu
Fi gur e 1 .1 Com par i ng a Java appl et Dat aGri d (l ef t ) t o a Fl ex Advanced Dat aGri d
much mor e functi onal wi th much less code overhead. The Fl ex DataGr i d and
AdvancedDataGr i d components pr ovi de built-in support for tasks such as sorti ng,
dr aggi ng col umns, r ow hi ghl i ghti ng, data nesti ng, and styling.
The Flash runti me provi des l i ghtwei ght graphi cs and ani mati on capabi l i ti es i n
manageabl e fi l e sizes, maki ng the pl ayer hugel y successful across OSs and browser
pl atforms. The Flash runti me allows for ri ch appl i cati ons to have true stateful experi -
ences and a hi gh l evel of security.
NOTE A stateful exper i ence wi th Fl ex means that the cl i ent (F l ex) wi l l man-
age or r emember everythi ng it needs to wi thout havi ng to: submi t to the
server side, update and manage a session or request thr ough HTTP, and
refresh the cl i ent side wi th updated data after a submi t wi th data f r om the ses-
si on or request.
I n general , J ava devel oper s have successfully l everaged the pri nci pl es of obj ect-
or i ented pr ogr ammi ng (OOP) to bui l d extremel y stable, testable, and extensi bl e
appl i cati ons. Fl ex has become a ri ch i nternet appl i cati on (RI A) sol uti on for J ava
devel oper s because it not onl y bri dges the gap between a sol i d server side and a
great UI , it is also bui l t on top of OOP pri nci pl es such as encapsul ati on, i nheri tance,
and pol ymor phi sm.
These advantages benefi t other technol ogi es besi des pur e J ava, as you'l l see i n
chapter 11, when we demonstrate Fl ex i ntegrati on wi th Grails, one of the hottest web
devel opment pl atforms. We'l l bui l d a si mpl e contact management system and l earn
how to get r ol l i ng wi th Gr oovy and Grails devel opment. I ntegrati ng Fl ex wi th Grails is
i n many respects easier than i ntegrati ng Fl ex wi th J ava.
Fl ex devel opment is now bol stered by many of the benefi ts of J ava-like frameworks
for per for mi ng uni t testing, functi onal testing, and conti nuous i ntegrati on. The com-
bi nati on of J ava and the Fl ex Software Devel opment Ki t (SDK) allows devel oper s new
to the business to start bui l di ng appl i cati ons i mmedi atel y.
www.it-ebooks.info
A whirlwind tour of Flex 5
A thri vi ng Fl ex open source communi ty can offer J ava devel oper s GUI components
as si mpl e and as compl ex as r equi r ed. Most of tiiese custom components extend stock
Fl ex obj ects found i n di e Fl ex SDK. Adobe made Fl ex 3 open source, and it now has
numer ous communi ty resources. The Fl ex SDK wi ti i Adobe's built-in charti ng compo-
nents is still commer ci al .
We have chosen Fl ex 4 wi ti i J ava because of the duality of a ri ch and stateful
cl i ent i n conj uncti on wi ti i a power ful server side. Al so, J ava is broadl y used i n di e
mai nstream and is di e exi sti ng server-side pl atfor m for many Fl ex mi gr ati on proj -
ects. Al though there are al ternati ve ways for doi ng RI A devel opment, Fl ex wi l l most
l i kel y pr ove to be the superi or RI A fr amewor k because of di e si mpl i ci ty and test-
ability it provi des to devel opers. We'r e now ready to discuss some of Fl ex frame-
wor k features.
1.1 A whi rl wi nd t our of Fl ex
I t's time to take a peek at the components we'l l use thr oughout this book. We
won't go i nto too much detai l about the components as that is beyond di e scope of
this book. I nstead, we'l l focus on di e usage of components and fr amewor k i n real-
wor l d devel opment.
1.1.1 MXML and ActionScript
At di e heart of every Fl ex appl i cati on you'l l fi nd a combi nati on of MXML fi l es (XML
fi l es wi th the . mxml extensi on) and Acti onScr i pt classes. These two components are
the basic bui l di ng bl ocks of di e Fl ex fr amewor k. The Fl ex compi l er takes these fi l es
and creates a small web for mat (SWF) fi l e, whi ch is executed i n the Flash Player.
M X M L
MXML is an XML- based markup l anguage si mi l ar to HTML / XHTML . The MXML syn-
tax, used to decl arati vel y defi ne your appl i cati on, has numer ous tags for common UI
obj ects, such as text i nput fi el ds, radi o buttons, and dr op- down lists. I t also has many
UI components and l ayout components that are common i n ri ch cl i ent devel opment,
such as menu bars, tabbed panels, data gri ds, and navi gati onal trees. I n addi ti on, it's
possi bl e to bui l d custom components that extend exi sti ng ones or pr oduce somethi ng
compl etel y di ffer ent l i ke the fl ow vi sual i zati on chart. Fi gure 1.2, whi ch was made wi th
Degr afa, shows this functi on.
I n chapter 8 we'l l be cover i ng the Degr afa drawi ng API for Fl ex to create a pi e
chart for a sampl e appl i cati on.
ACTI ONSCRI PT
Acti onScri pt, and mor e speci fi cal l y Acti onScr i pt 3.0, is a dynami c scri pti ng l anguage
based on di e ECMAScri pt Language Speci fi cati on, Thi r d Edi ti on. I t is composed of
the l anguage speci fi cati on and di e Flash Pl ayer API . I t is si mi l ar to J avaScri pt i n syntax,
so it shoul d l ook fami l i ar to any exper i enced web devel oper. Unl i ke J avaScript, Acti on-
Scri pt is compi l ed i nto byte code befor e bei ng executed, i nstead of bei ng parsed and
i nter pr eted at runti me.
www.it-ebooks.info
6 CHAPTER 1 Some Flex with your J ava ?
Fi gur e 1 .2 Fl ow vi sual i zat i on char t
NOTE Dozens of user control s, power ed by Acti onScri pt, are avai l abl e wi ti i
Fl ex out of the box. As we demonstrate l ater i n tiiis book, exi sti ng compo-
nents can be extended to create your own custom components. Because your
appl i cati on wi l l always run i nsi de di e Flash Pl ayer, you don't have to worry
about cross-browser compati bi l i ty issues ei ther. I n chapter 8 we'l l go over how
to uti l i ze custom components i n your Fl ex appl i cati ons usi ng Acti onScr i pt for
di e purpose of reuse.
Acti onScr i pt is a dynami cal l y typed l anguage si mi l ar to Pyti i on or Gr oovy and does its
type checki ng at runti me i nstead of at compi l e ti me. You have di e opti on of di recti ng
di e compi l er to per for m type checki ng at compi l e ti me by enabl i ng strict mode on di e
compi l er, but tiiis is not a good substitute for a compr ehensi ve set of uni t tests.
The Fl ex SDK and Flash Pl ayer are di e two key el ements i n maki ng a Fl ex appl i ca-
ti on come to l i fe.
1.1.2 The Flex SDK
The Fl ex 4 SDK comes i n two fl avors: di e Free Adobe Fl ex SDK and the Open
Source Fl ex SDK. Both contai n everyti i i ng you need for devel opi ng, opti mi zi ng, and
debuggi ng Fl ex appl i cati ons. The SDKs i ncl ude di e Acti onScr i pt and MXML compi l -
ers, tool s for creati ng J avaDoc-l i ke documentati on, and di e Fl ex Framework. The
onl y di ffer ence between di e two is tiiat di e Free Adobe Fl ex SDK contai ns addi -
ti onal components that enhance the Fl ex appl i cati on, such as tool s for advanced
font encodi ng, tool s for packagi ng Adobe I ntegr ated Runti me (AI R) appl i cati ons,
and di e Flash Player. These extra components are not open source but have been
made avai l abl e by Adobe. To l earn mor e about the Fl ex SDK downl oads visit http:/ /
opensour ce. adobe. com/ wi ki / di spl ay/ fl exsdk/ downl oads.
1.1.3 Flash Player 10
Of course none of tiiis coul d be possi bl e wi thout the Flash Pl ayer 10 runti me. I t is the
heart and soul of every Fl ex appl i cati on. Al though Flash Pl ayer itself is not open
www.it-ebooks.info
Creating an application in Flex 7
source, it has been free since its i ncepti on and can be found on nearly every computer
in the world. Flash Player gives your Flex applications the ability to execute in the
same manner and l ook the same no matter what browser your application runs in.
Because your Flex application runs inside Flash Player, you do not have to be con-
cerned with cross browser issues.
A d o b e co n tri b u te s A c ti o n S c ri p t e n g i n e so u rc e to M o zi lla
I n N o v e m b e r 2 0 0 6 , A d o b e c o n t ri b u t e d t h e s o u rc e c o d e fo r i t s A c t i o n S c ri p t v i rt u a l
m a c h i n e t o t h e M o zi l l a f o u n d a t i o n , s p a w n i n g t h e T a m a ri n p ro j e c t . T a m a ri n wi ll su p -
p o rt E C M A S c ri p t E d i t i o n 3 a n d b e i n t e g ra t e d i n to t h e S p i d e rM o n k e y p ro j e c t , M o zi l-
l a 's n e x t g e n e ra t i o n J a v a S c ri p t i n g e n g i n e t o b e i n c lu d e d w i t h fu t u re v e rs i o n s o f
M o zi l l a (h t t p s : / / d e v e l o p e r. m o zi l l a . o rg / e n / T a m a ri n ).
Because of the widely popul ar Flash Player and a powerful open source SDK, Flex is a
great fi t for J ava developers building rich clients.
Now comes the part we've all been waiting patiently for —we'r e goi ng to create a
"Hel l o Worl d!" styled application in Flex.
Creat i ng an appl i cat i on i n Fl ex
Let's start by model i ng our directory structure, shown
in fi gure 1.3, after the Maven default proj ect struc-
ture. This will prove useful because we're using Maven
to build the FlexBugs sample application in chapter 2.
The sample application can be placed in a proj-
ect directory such as C:\ de\ \ projects for Windows, or
/ home/ <YOUR_USERNAME>/ development for Linux.
The main source code location for our "Hel l o
Worl d!" sample application will be contained in the
src/ mai n/ fl ex folder. Because ActionScript follows a Figure 1 3 The f ol der st ruct ure f or
pattern similar to J ava for packages, if your Action- our " Hel l o Worl d!" appl i cat i on is
Script class belongs to the com. example package, the f ormat t ed f or t he Maven build
source for this class will be contained in the src/ main/
flex/ com/ example folder. The src/ main/ resources
fol der should contain any resources that bel ong to the application but are not com-
pi l ed with the sources. For example, any confi gurati on files or message bundles bel ong
in the resources folder. The src/ test/ flex and src/ test/ resources fol ders are identical
to the src/ main/ flex and src/ main/ resources fol ders respectively, except these fol ders
are for the test code of the application.
For the purpose of introducing Flex code, listing 1.1 demonstrates a trivial exam-
pl e of a simple Flex application. We'r e goi ng to create a single .mxml fi l e that will
print the words "Flex 4 is Fun" as seen in fi gure 1.4.
a . J helloviofldaop
- i j src
1= roain
O flex
resources
B Q test
Q flex
Q resources
www.it-ebooks.info
31 CHAPTER 1 Some Flex with your J ava ?
Fi gure 1 .4
A si mpl e Fl ex appl i cat i on
As you can see there's nothi ng fancy happeni ng her e and the code pr esented i n list-
i ng 1.1 is also si mpl e.
Li s t i n g 1 . 1 M a i n . m x m l
<?xml ver si on="1. 0" enc odi ng="ut f - 8" ?> < • - © XML document decl ar at i on
<s: Appl i c a t i on <—.
xml ns : f x="ht t p: / / ns. a dobe. c om/ mxml / 2009 " Q MXML appl i cat i on r oot
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k" >
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<f x: St yl e>
. hel l oText {
pa ddi ng- t op: 2 5px;
pa ddi ng- l ef t : 25px;
f ont - wei ght : bol d;
c ol or : ha l oBl ue;
}
</ f x: St yl e>
<s: Ri c hText st yl eNa me=" hel l oText " >
<s: t ext >
Fl ex 4 i s Fun
</ s: t ext >
</ s: Ri c hText >
</ s: Appl i c a t i on>
I f you've ever done any web devel opment, this shoul d l ook fami l i ar. MXML, l i ke
XHTML, is nodi i ng mor e tiian XML. At the begi nni ng of di e fi l e you'l l see di e stan-
dard XML decl arati on Q . Next you'l l see di e r oot node wi ti i the defi ned xml
namespaces Q , whi ch i n most Fl ex appl i cati ons wi l l be wi ti i i n di e <mx: A p p l i c a t i on
el ement. I n chapter 3, we'l l evol ve this exampl e by creati ng a ni ce Fl ex appl i cati on. I n
chapter 9, wher e we talk mor e about Adobe AI R, we'l l expl ai n that di e r oot node for
an AI R appl i cati on is typically <mx:Wi ndowedAppl i cati on>. I nsi de di e <mx: Appl i ca-
t i on> el ement is a style el ement Q and a si ngl e Ri chText el ement Q wi ti i its text
attri bute set to "Fl ex 4 is Fun".
Fi ndi ng t he ri ght t ool s and pat t erns
As di i s book's ti de suggests, Flex on J ava wi l l focus on Fl ex i ntegrati on wi th J ava. Wi ti i
that i n mi nd, we di l i gentl y searched for di e per fect i ngredi ents to equi p you wi th di e
ri ght tool s for real - worl d scenari os wi thout over compl i cati ng tilings.
| File : / / / C :/ D ocum e.. .n-debug/ t est.h t m I
Fl ex 4 i s Fun
Fl ex ess st yl e suppor t

Ri chText el ement
www.it-ebooks.info
Finding the right tools and patterns 9
We'r e not focusi ng on teachi ngj ava, but we bui l d a si mpl e J ava web appl i cati on i n
chapter 2. We chose frameworks that shoul d ease the J ava l earni ng curve necessary to
get a sampl e appl i cati on up and r unni ng fast. We won't di ve deep i nto every part of
Fl ex devel opment. I nstead, Flex on J ava wi l l pr ovi de you wi th si mpl e yet power ful
exampl es of i ntegrati ng the two technol ogi es.
Ther efor e, we'l l be tackl i ng i n detai l the topi cs outl i ned i n the secti ons that fol l ow.
1.3.1 Building a Flex interface
Oft en devel oper s begi n bui l di ng naked UI components wi thout bei ng connected to a
backend server and database. A di sconnected Fl ex cl i ent can take advantage of mock
data and al l ow devel oper s to easily pr ototype the UI wi thout the compl exi ty of exter-
nal dependenci es.
Thi s appr oach is demonstrated i n chapter 3 wher e we create the begi nni ngs of a
ri ch UI for the Fl exBugs sampl e appl i cati on shown i n fi gur e 1.5.
1.3.2 Integrating with web services
What may seem unfami l i ar to you i n this chapter is that when we connect to the server
side we'l l be model i ng our appl i cati on usi ng the Model - Vi ew- Presenter (MVP) desi gn
pattern i nstead of empl oyi ng the typical appr oach of usi ng the mxml tag el ement that
doesn't scale wel l for most appl i cati ons. Usi ng the MVP approach, all web services calls
FlexBugs
| Retrain US! |
Add Ndw Convrtdfil Ed*
UI
Da;e»Commam .
Shirty Saius
Lo»n j
10:
Project [
De&Cfi pDon:
OsiaiitVtew ( Gfa&ft Vte*
i
I
Rftpor»3 By
Reported On:
Aasiflned To:
Efrbtiaiad HOLTS:
Sovony |
J 3
Acdisfrue | Can»Cf-anges j
Copyr«ill C 2009 Fie* On Java
Fi gure 1 .5 The Fl exBugs sampl e Fl ex appl i cat i on
www.it-ebooks.info
10 CHAPTER 1 Some Flex with your J ava ?
wi l l be wr apped i n a Model obj ect wri tten i n Acti onScri pt. Thi s makes changi ng di e
i mpl ementati on less pai nful .
Connecti ng to server-side services, event di spatchi ng, and event handl i ng are all
di i ngs di at are critical to any Fl ex business appl i cati on and are bui l t i nto the cor e of
di e fr amewor k. That's why i n chapter 4 we'l l demonstrate connecti ng to di e J ava
server side and how to l everage the power ful Fl ex API for connecti ng to web services.
Pl enty of l i terature, i ncl udi ng di e Fl ex onl i ne documentati on, covers the typical
appr oach of connecti ng to services. I n this book, we'l l create cl ean i nterfaces and
views as we bui l d a wel l - desi gned Fl ex cl i ent that wi l l scale on demand.
1.3.3 Integration with BlazeDS, logging, and messaging
Unti l fai rl y recentl y i f you wanted to connect your data-dri ven appl i cati on to a J ava-
based backend, your choi ces wer e fai rl y l i mi ted. You coul d expose your J ava services
as XML web services, ei ti i er as SOAP-based or RESTful and connect to di em tiiis way,
wri te your own custom marshal er/ unmarshal er based on the Adobe AMF pr otocol ,
or pony up bi g bucks for a l i cense for Adobe's Li veCycl e Data Services. Wi th di e
rel ease of Fl ex 3, Adobe deci ded to spawn BlazeDS, an open source pr oj ect that con-
tains much of di e functi onal i ty speci fi c to connecti ng Fl ex to a J ava-based servi ce.
I ntegr ati ng Fl ex wi ti i J ava is what tiiis book is all about. That's why chapter 5 wi l l
demonstrate fur ti i er how to connect a Fl ex cl i ent mor e di recdy to di e server side
usi ng di e open source BlazeDS fr amewor k. BlazeDS provi des a mechani sm for allow-
i ng Fl ex to call methods on J ava obj ects thr ough bi nary seri al i zati on wi th di e Acti on
Message For mat or AMF. Thi s is much faster tiian what's possi bl e wi ti i web services or
XML / HTTP(s) because it uses real obj ects and doesn't have to marshal XML.
Because l oggi ng is a critical component of any appl i cati on and devel opment envi-
r onment, chapter 5 also covers BlazeDS l oggi ng i n detai l .
Real - ti me messagi ng is an i mpor tant feature i n most enterpri se appl i cati ons. Chap-
ter 6 wi l l demonstrate how to devel op Fl ex appl i cati ons di at take advantage of si mpl e
pol l i ng; i n chapter 11 we'l l discuss how to connect usi ng J ava Message Servi ce (J MS).
The Fl ex fr amewor k provi des an API di at enabl es di stri buted communi cati on wi ti i the
server side or communi cati on between clients that is l oosel y coupl ed and asynchro-
nous. Fl ex has both a power ful and si mpl e API for handl i ng messagi ng.
1.3.4 Securing Flex applications
Many techni cal books skip security, but it's always the el ephant i n di e l i vi ng r oom
when gather i ng r equi r ements for an appl i cati on. I t's i mpor tant to understand di e
security issues of Fl ex both to decrease risk and to mi ni mi ze di e cost of what can be
one of the most expensi ve features i n any business appl i cati on. Chapter 7 wi l l demon-
strate bui l di ng authenti cati on, authori zati on, and personal i zati on wi th Spri ng Secu-
rity (Acegi ) i ntegrati on.
www.it-ebooks.info
Summary 11
1.3.5 Creating custom Flex controls with Degrafa
Custom components are fi rst class citizens i nsi de the Fl ex fr amewor k, and many
Acti onScr i pt frameworks take advantage of this. One that real l y stands out is Degrafa,
whi ch is a decl arati ve graphi cs fr amewor k that provi des a suite of graphi cs classes.
Degr afa is open source and can be used to bui l d robust charts, tools, and other graph-
ical el ements wi th less effor t and compl exi ty than other frameworks.
We'l l create a custom pi e chart component that wi l l be appropri atel y ti ed i nto our
sampl e appl i cati on i n chapter 8. Whi l e we'r e at it we'l l also demonstrate creati ng a
DataGri d I temRender er and per f or m dynami c obj ect creati on.
1.3.6 Desktop 2.0 with Adobe AIR
A business someti mes can't l i ve wi th the web al one, and when a desktop cl i ent is the
best way to go, Fl ex goes beyond the web wi th Adobe AI R. A Fl ex appl i cati on can easily
be por ted to a desktop envi r onment wi th AI R. Thi s is especi al l y easy for wel l - desi gned
appl i cati ons that al l ow for opti mal reuse of code. Chapter 9 wi l l demonstrate how to
al l ow a Fl ex appl i cati on to l i ve i n two wor l ds—by demonstrati ng how to package and
di stri bute an AI R appl i cati on.
1 .3 .7 Flex and Grails
The Gr oovy pr ogr ammi ng l anguage is the fi rst dynami c scri pti ng l anguage to be
adopted as a standard thr ough the J ava Communi ty Process 0CP). The speci fi cati on
for Gr oovy can be found under J ava Speci fi cati on Request (J SR) 241 at http:/ / j cp.org/
en/ j sr/ detai l ?i d=241. Gr oovy supports power ful features that can be found i n other
l anguages l i ke Python, Ruby, and Smalltalk; Grails is a ful l devel opment stack for
Gr oovy that provi des a rapi d devel opment envi r onment for both server side and the
web that resembl es and rivals the Ruby on Rails (RoR) fr amewor k. Wi th Fl ex and
Grails you can qui ckl y create a dynami c appl i cati on that runs on the J VM wi th much
less effor t. Fl ex i ntegrati on wi th Gr oovy and Grails is cover ed i n chapter 11.
1.4 Summary
Whet her you'r e exper i enced or i nexper i enced i n bui l di ng web or desktop appl i ca-
ti ons wi th Fl ex on J ava, this book wi l l teach you how to i ntegrate Fl ex on J ava qui ckl y
and effecti vel y. Combi ni ng Fl ex wi th J ava allows devel opers to pr ovi de ri ch UI s wi th
robust server-side technol ogi es and does so wi th mi ni mal effor t and cost. Fl ex and J ava
are pr oven technol ogi es and have conti nued to be i mpr oved over ti me and used by
many compani es ar ound the wor l d.
I n chapter 2, we lay a foundati on by bui l di ng a sampl e J ava web appl i cati on for use
thr oughout the maj ori ty of the exampl es i n the rest of this book. Thi s shoul d be use-
ful i f you don't al ready have an appl i cati on or need assistance i n getti ng started wi th
setti ng up a Fl ex on J ava devel opment envi r onment. Setup-type chapters can feel
slightly mechani cal because of the downl oadi ng and i nstal l ati on they cover. We've
tri ed to keep it i nteresti ng and painless whi l e usi ng popul ar devel opment envi ron-
ment frameworks that the maj ori ty of you wi l l be pl eased to see uti l i zed.
www.it-ebooks.info
Thi s chapt er covers
• G e n e ra t i n g t h e a p p l i c a t i o n s t ru c t u re w i t h
M a v e n
• B u i l d i n g J a v a s e rv e r-s i d e d o m a i n o b j e c t s
a n d s e rv i c e s
• B u i l d i n g a s i m p l e J S P U l
We'l l begi n by creating a J ava application that will expose web services so we can
later connect to them fr om a Flex client. We have attempted to avoid tying di e
book to a specific sample application by focusing more on the concepts and tech-
niques of using various frameworks and tools. This should allow you to pick a topic
in di e book tiiat interests you and get rol l i ng on it. We'l l demonstrate many topics
by using an application built in tiiis chapter called FlexBugs. I f you want to fol l ow
the samples in di e book you can downl oad di e full code listings on di e book's web-
site at http:/ / manning.com/ allmon. You could also replace the application con-
tents with something tiiat's more meani ngful to you by changing the domain
objects to manage whatever you want, like contacts or movi e favorites.
Throughout di e book, especially in tiiis chapter, we leverage a few J ava frame-
works diat hel p to lighten di e amount of work requi red to build a fully func-
tional web application. This chapter is a bit mechanical because we need to set up
12
www.it-ebooks.info
Generating the application structure with Maven 13
a devel opment envi r onment. A few downl oads and installs must take pl ace i f you
choose to use our samples. Feel fr ee to browse thr ough this chapter and skip what
you al ready know.
The J ava frameworks used wi l l hel p keep devel opment to a mi ni mum whi l e
creati ng a sampl e appl i cati on to wor k wi th for i ntegrati on purposes. Thi s wi l l al l ow
us to focus on teachi ng and demonstr ati ng how to bui l d synergy between Fl ex
and J ava.
We'r e bui l di ng a J ava appl i cati on fi rst as a basis for wor k i n chapter 3, but you
can start wi ti i Fl ex i n chapter 3 i f you'd l i ke or move ar ound di e book as conve-
ni ent. The J ava appl i cati on comes first because we expect most readers to be refac-
tor i ng exi sti ng appl i cati ons to i ncl ude a Fl ex cl i ent and tiiis wi l l gi ve you someti i i ng
to pl ay wi th quickly.
We'l l start by gener ati ng di e pr oj ect structure wi ti i Apache Maven, a conventi on-
over- confi gurati on pr oj ect management fr amewor k. Maven wi l l bui l d di e appl i ca-
ti on for us and speed up the devel opment process. After we have a pr oj ect structure
gener ated, we'l l start bui l di ng the server-side components whi l e l ever agi ng MySQL
for di e database.
For di e J ava server-side pi eces, we'l l start wi th creati ng pl ai n ol d J ava obj ects
(POJ Os), Data Access Obj ects (DAOs), and servi ce obj ects that wi l l be exposed to a
web tier.
Let's wri te a si mpl e J ava server-side appl i cati on usi ng the AppFuse fr amewor k.
AppFuse was created by Matt Rai bl e of Rai bl e Desi gns to si mpl i fy di e constructi on of
J ava web appl i cati ons thr ough conventi on. Usi ng AppFuse on di e server side wi l l al l ow
us to focus on di e i ntegrati on of Fl ex wi ti i J ava creati ng si mpl e domai n and servi ce
J ava obj ects.
Work i ng wi t h AppFuse
Because di e layers of archi tecture and compl exi ty can make appr oachi ng di e bui l di ng
of a J ava web appl i cati on a bi t daunti ng, AppFuse is a great technol ogy choi ce because
it si mpl i fi es deal i ng wi th the layers and del i veri ng val ue faster.
AppFuse allows a J ava devel oper to qui ckl y start focusi ng on business domai n con-
cerns. A typical J ava appl i cati on wi l l be POJ O-driven and wi r ed together thr ough
Spri ng, the open source dependency i nj ecti on (DI ) fr amewor k. The DI desi gn pattern
hel ps to bui l d appl i cati ons wi th l oosel y coupl ed components maki ng your appl i cati on
mor e fl exi bl e and testable. I n addi ti on, AppFuse comes stocked wi th Maven i ntegra-
ti on to make tilings even easier. Let's get thi ngs r ol l i ng by i nstal l i ng Maven.
Generat i ng t he appl i cat i on st ruct ure wi t h Maven
To pi geonhol e Maven by cal l i ng it a bui l d system doesn't do it j usti ce. Apache Maven
is a software pr oj ect management and compr ehensi on tool . What exactly does that
mean? At the cor e of every Maven pr oj ect is a pr oj ect obj ect model , mor e affec-
ti onatel y known as di e POM, and f r om this POM Maven can bui l d our appl i cati on,
www.it-ebooks.info
1 4 CHAPTER 2 Beginning with J ava
gener ate reports, gener ate documentati on, and mor e, all f r om a si ngl e descri pti on
of the pr oj ect. To l earn mor e about Maven check out the Apache Maven pr oj ect site
at http:/ / maven.apache.org or downl oad the fr ee ebook f r om Sonatype at http:/ /
www.sonatype.com/ book.
Befor e movi ng ahead wi th Maven, be sure you have the J ava Devel opment Ki t
(J DK) versi on 1.5 or greater pr oper l y i nstal l ed. You can fol l ow the next secti on for that
or skip it i f you'r e ready to go. After you install the J DK, be sure to install the MySQL
database as wel l . You'l l need MySQL i nstal l ed befor e gener ati ng the pr oj ect wi th the
AppFuse Maven archetype.
2.2.1 Download and install the JDK
To run any J ava server-side envi r onment, you must install and confi gur e the J DK.
Downl oad and install J DK 1.5+ f r om the Sun websi te at http:/ / j ava.sun.com/ j avase/
downl oads/ i ndex.j sp. Refer to the J ava documentati on for i nstructi ons on how to
install J ava on your speci fi c pl atfor m. Set up an envi r onment vari abl e for J AVA_HOME
that poi nts to the J DK di rectory. I t's also hel pful to add the J DK's bi n di rectory to the
path. Open a command pr ompt and type i n the J ava versi on to veri l y that J ava is
i nstal l ed correctl y. The versi on i nfor mati on of the confi gur ed J DK shoul d be pre-
sented as shown i n fi gur e 2.1.
After J ava is confi gur ed you can move on to setti ng up the open source
MySQL database.
Fi gur e 2 .1 Ver i f y t hat Java i s set up cor r ect l y by check i ng t he ver si on
www.it-ebooks.info
Generating the application structure with Maven 15
2.2.2 Download and install MySQL
To demonstrate database i ntegrati on and persi stence you'l l use MySQL, whi ch is an
open source database that is extr emel y l i ghtwei ght. Downl oad and install MySQL 5.x
or hi gher f r om the MySQL websi te at http:/ / dev.mysql .com/ downl oads/ mysql .
Her e you'l l set up a database for the Fl exBugs sampl e appl i cati on. After you have
MySQL i nstal l ed pul l up the command pr ompt and l og i n to MySQL usi ng the r oot
account, then create the fl exbugs database as shown i n fi gure 2.2. Usi ng the com-
mand mysql - u r oot - p wi l l instruct MySQL to l og i n to the l ocal host i nstance of
MySQL usi ng the r oot account. I t wi l l ask for the password. Pl ease r ecor d the admi n
account's user and password for l ater r efer ence. Creati ng the database is as si mpl e as
executi ng the command cr eat e database f l exbu gs.
Let's move on to i nstal l i ng Maven to create the pr oj ect structure, manage the
dependenci es, and bui l d the appl i cati on.
2.2.3 Download and install Maven
Maven can be downl oaded at http:/ / maven.apache.org/ downl oad.html . Be sure to
downl oad versi on 2.0.9 or above. After Maven is downl oaded you shoul d set up an
M2_HOME envi r onment vari abl e that poi nts to the di rectory wher e Maven was
i nstal l ed. The M2_HOME/ bi n di rectory wi l l need to be set onto the path as wel l or
expor ted for any UNI X pl atfor m. For mor e assistance on i nstal l i ng or confi gur i ng
Maven r efer to the Maven documentati on at http:/ / www.sonatype.com/ books/
mvnex- books/ reference/ i nstal l ati on- sect- maven- i nstal l .html .
c\ C:\ WIND0WS\ systeiri32\ cmd.exe - mysql -u root -p
-J a )
x
C:\ Documents and Set t i ngs\ bal l mon>mysql - u r oot -
Enter password: hmmhkmmmm
Welcome to the MySQL moni t or . Commands end wi t h
Vour MySQL connect i on i d i s 4
Ser ver ver s i on : 5. 1. 31- communi ty MySQL Community
ip
; o i> .
Sei-uei- <CPL>
A
Type
J
h el p; * or '\ h* f o r h el p. Type
J
\ c* t o cl eai t he bill f er .
mysql > cr eat e database f l exbu gs ;
Query OK, 1 row a f f ec t ed <0. 00 s ec )
mysql > 1
Fi gur e 2 .2 Usi ng t he MySQL commands t o l og i nt o t he dat abase i nst ance and cr eat e t he f l exbugs
dat abase
www.it-ebooks.info
16 CHAPTER 2 Beginning with J ava
2.2.4 Create a Mavert multimodule project
We'r e goi ng to create a Maven mul ti modul e pr oj ect cal l ed Fl exBugs. A mul ti modul e
pr oj ect coul d be confi gur ed manual l y by creati ng a top-l evel super POM, addi ng proj -
ects under the super POM di rectory, and edi ti ng the super POM to i ncl ude di e mod-
ules wi th the modul es el ement. We'r e goi ng to use a techni que that expl oi ts a l i ttl e
known feature of the ar chetypexr eate pl ugi n, and the Maven site archetype to kick-
start di e proj ect.
Creati ng a mul ti modul e pr oj ect has many benefi ts, di e two most i mpor tant bei ng
(1) the ability to bui l d every arti fact i n a pr oj ect wi th a si mpl e mvn compi l e command
and (2) i f you are usi ng ei ther the Maven ecl i pse:ecl i pse pl ugi n or the i dea:i dea
pl ugi n, you can enter this command at di e r oot of the proj ect, and it wi l l gener ate all
di e pr oj ect fi l es for all of the contai ned modul es.
First you'l l gener ate di e top-l evel pr oj ect usi ng the maven- ar chet ype- si t e-
si mpl e archetype:
mvn a r c het ype: c r ea t e
- D gr oupI d=or g. f oj
- D a r t i f a c t l d=f l ex- bugs
- D a r c het ypeAr t i f a c t l d=ma ven- a r c het ype- si t e- si mpl e
Thi s generates a Maven pr oj ect wi th the di rectory structure as
shown i n fi gur e 2.3.
The pr oj ect gener ated is di e mi ni mum pr oj ect setup nec-
essary to gener ate site documentati on. The i ndex.apt fi l e is
di e mai n i ndex page for di e site, and is wri tten i n di e Al most
Pl ai n Text (APT) format, whi ch is a wiki-like for mat. You can
also gener ate a mor e compl ete site pr oj ect usi ng the maven-
ar ch et ype- s i t e archetype l i ke this:
mvn a r c het ype: c r ea t e
- D gr oupI d=[ J a va : t he pr oj ec t ' s gr oup i d]
- D a r t i f a c t l d=[ J a va : t he pr oj ec t ' s a r t i f a c t i d]
- D a r c het ypeAr t i f a c t l d=ma ven- a r c het ype- si t e
Thi s wi l l gener ate a pr oj ect structure si mi l ar to fi gur e 2.4.
After you have gener ated di e site proj ect, edi t di e pom. xml created f r om di e site
archetype pl ugi n. Make sure that the packagi ng type is set to pom. We've l eft secti ons
out (denoted by ...) to be bri ef.
Li s t i n g 2 . 1 Pa c k a g i n g of t y p e p o m i n d i c a t e s a m u l t i m o d u l e p r o j e c t
<pr oj ec t >
<model Ver si on>4. 0. 0</ model Ver si on>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs</ a r t i f a c t l d>
<ver si on>l . 0- SNAPSHOT</ ver si on> Q Art i f act t ype
<pa c ka gi ng>pom</ pa c ka gi ng> <1—' (j ar, war, ear )
£ } fle x-b u g s
E src
• Q site
Q apt
Fi gur e 2 .3 The
gener at ed t op-l evel
Maven pr oj ect
</ pr oj ec t >
www.it-ebooks.info
Generating the application structure with Maven 17
Because you set the packagi ng type to pomQ, any proj -
ects you gener ate f r om the r oot of the pr oj ect di rec-
tory wi l l i nsert tiiemselves i nto the pr oj ect by creati ng
an entry i nto the modul es secti on of the pom. xml for
the site.
AppFuse comes stocked wi th custom Maven arche-
types, whi ch al l ow AppFuse to create di ffer ent fl avors of
J ava web appl i cati ons wi th varyi ng technol ogy stacks.
You'l l use di e Struts 2 Basic archetype for di e Fl exBugs
sampl e appl i cati on.
I n di e r oot di rectory of your pr oj ect tiiat you created
previously, type di e command i n l i sti ng 2.2.
I m u lti -m o d u le - p ro je ct
* srt
j site
a p t
J * fml
- fr
J , a p t
J „ fm l
xd o c
* doc
Fi gur e 2 .4 A f ul l y dr essed up
Maven si t e pr oj ect
Li s t i n g 2 . 2 Cr e a t e t h e f l ex - b u gs - web m o d u l e f or t h e Ja va s e r v e r s i d e
mvn a r c het ype: c r ea t e
- D a r c het ypeGr oupI d=or g. a ppf use. a r c het ypes <—©
- D a r c het ypeAr t i f a c t l d=a ppf use- ba si c - st r ut s <—Q
- D r emot eReposi t or i es=ht t p: / / st a t i c . a ppf use. or g/ r el ea ses
- D a r c het ypeVer si on=2 . 0 . 2 <1 .
- D gr oupI d=or g. f oj . f l ex- bugs <1—© Q
- D a r t i f a c t l d=f l ex- bugs- web <1—Q
The a ppf use- ba si c - st r ut s © archetype isn't a built-in Maven resource. I nstead, it's
pr ovi ded thr ough a r emote reposi tory ©. You pr ovi de Maven wi ti i coordi nates to di e
archetype by also pr ovi di ng di e a r c het ypeGr oupI d O
a n
d a r c het ypeVer si on O
al ong wi th di e rest of di e r equi r ed details. The gr oupl d © poi nts to di e top-l evel proj -
ect and the a r t i f a c t l d © is the name of di e modul e you are about to create.
After you've executed di e command, l ook i nsi de di e top- l evel pom. xml f r om
di e mai n proj ect. Ther e shoul d now be an entry toward di e bottom of di e fi l e like
the fol l owi ng.
<modul es>
<modul e>f l ex- bugs- web</ modul e>
</ modul es>
Executi ng di e command i n l i sti ng 2.2 shoul d gener ate di e pr oj ect structure shown
i n fi gur e 2.5. Don't be concer ned wi ti i di e warni ngs whi l e creati ng your proj ect; tiiey
are expected. As l ong as you see BUI LD SUCCESSFUL at the end, your pr oj ect was
created successfully.
As you can see f r om fi gur e 2.5 Maven gener ated di e pr oj ect structure and added a
coupl e of fi l es for testing.
www.it-ebooks.info
18 CHAPTER 2 Beginning with J ava
Fi gur e 2 .5
Gener at ed modul e st r uct ur e usi ng t he
appfuse-basic-struts ar chet ype
2.2.5 Maven provides a buildable project
I f you l ook i n di e sr c/ mai n/ j ava/ or g/ f oj package you'l l fi nd a source fi l e
cal l ed App.j ava, and i n di e s r c/ t es t / j ava/ or g/ f o j package you'l l fi nd a uni t
test cal l ed AppTest.j ava. Remove both fi l es as you wi l l not need di em.
Noti ce that Maven appears to be bui l di ng somethi ng. I n fact, di e f l ex- bu gs- web
POM tries to bui l d a depl oyabl e J ava Web Ar chi ve or WAR but wi l l first choke on a con-
fi gur ati on issue. I f r unni ng the mvn j et t y: r u n - war command wi ti i out changi ng the
confi gur ati on you'l l most l i kel y get this error.
[ I NFO]
[ ERROR] BUI LD ERROR
[ I NFO]
[ I NFO] Er r or exec ut i ng da t a ba se oper a t i on: CLEAN_I NSERT
Embedded er r or : Ac c ess deni ed f or user
1
r oot
1
0
1
l oc a l host
1
( usi ng pa sswor d: NO)
[ I NFO]
[ I NFO] For mor e i nf or ma t i on, r un Ma ven wi t h t he - e swi t c h
Let's fi rst edi t the POM for di e f l ex- bu gs- web modul e. Thi s POM wi l l be l ocated
at di e r oot of that modul e. Ther e's a good deal goi ng but we'r e goi ng to focus on
di e pi ece we need to change. At di e bottom you need to speci fy your MySQL user
and password wi ti i the values we speci fi ed when you set up MySQL earlier. Her e's
an exampl e:
B i L J fle x-b u g s
B ¡j J fle x-b u g s-we b
B Q src
B l O m ain
B U ja va
B Q o rg
B t 2 | f o j
_ j fle x-b u g s
B re so u rce s
Q META-1NF
B Q webapp
O com m on
o WEB-INF
Q site
B I Q te st
B Q ja va
B ^ o rg
B l c l fo j
.. i fle x-b u g 5
i . *l re so u rce s
S src
www.it-ebooks.info
Generating the application structure with Maven 19
<j dbc . ur l x! [ CD ATA[ j dbc : mysql : / / l oc a l host /
f l ex_bugs_web?c r ea t eD a t a ba seI f Not Exi st =t r ueS; a mp; useUni c ode=t r ue&: a mp;
c ha r a c t er Enc odi ng=ut f - 8] ] ></ j dbc . ur l >
<j dbc . user na me>r oot </ j dbc . user na me>
<j dbc . pa sswor d>j a va 4ever </ j dbc . pa sswor d>
The Maven archetype we used, br ought to us by AppFuse, made it extremel y easy to
get to this poi nt—far easier tiian starting f r om scratch.
2 .2 .6 Running the FiexBugs web application
Maven equi ps a devel oper wi th di e ability to use di e appl i cati on i mmedi atel y wi ti i out
manual l y depl oyi ng it anywhere. Executi ng di e Maven j et t y: r u n - war goal f r om di e
f l ex- bu gs- web modul e wi l l gather all di e resources, compi l e all the code and tests,
execute di e uni t tests, gener ate test reports, bui l d a depl oyabl e WAR fi l e, and l aunch
the WAR fi l e i n an embedded i nstance of the popul ar and l i ghtwei ght J etty servl et
contai ner. Usi ng the appf u s e- bas i c- s t r u t s archetype wi l l also gener ate di e defaul t
database for us and add confi gur ati on fi l es to al l ow devel oper s to qui ckl y begi n devel -
opi ng features.
After you've run di e j et t y: run- war command, you can go to http:/ / l ocal host:
8080/ flex-bugs-1.0-SNAPSHC)T and l og i n f r om tiiere. By defaul t, you can l og i n to the
appl i cati on usi ng admi n for boti i di e username and password. After l oggi ng i n, you
are r edi r ected to the admi ni strati on panel as seen i n fi gur e 2.6. F r om tiiere you can
do basic thi ngs l i ke edi ti ng your user pr ofi l e and managi ng users.
Ap p Fu se
Providino integration and style to open source J ava.
Main Menu Edit Profile Administration Logout
Welcome!
Congratulations, you have logged in successfully! Now that you've logged in, you
have the following options:
0 Edit Profile
o Upload A File
Ve rs i o n l . O -S N A P S H O T | X H T M L Va l i d | C S S Va l i d | L o g g e d in a s : a d m i n © Z O O S Y
Fi gur e 2 .6 AppFuse def aul t appl i cat i on
www.it-ebooks.info
43 CHAPTER 2 Beginning with J ava
The appl i cati on shows nothi ng gl amor ous at this poi nt al though everythi ng you see
and can do has r equi r ed a mi nor setup effor t. AppFuse does much under di e cov-
ers for us f r om a fr amewor k and technol ogy perspecti ve. I t's possi bl e tiiat getti ng a
pr oj ect togedi er wi ti i hel p f r om Maven saved us a week or mor e of typical J ava
devel opment time.
Befor e we start devel opment of di e Fl exBugs sampl e appl i cati on downl oad the
source code at https:/ / i l exonj ava.googl ecode.com/ svn/ i l ex- bugs/ trunk.
Bui l d t he model obj ect s
A model obj ect is a POJ O tiiat is persi stabl e and mapped to di e database. I n our exam-
pl e we'r e usi ng AppFuse wi th di e Spri ng fr amewor k and Hi ber nate to manage per-
for mi ng database operati ons for obj ects tiiat are mapped to a database.
Let's start wi th I ssue. j a va as seen i n l i sti ng 2.3. For the Fl exBugs appl i cati on you
need someti i i ng to store issues and comments. An issue descri bes someti i i ng that
needs fi xi ng to meet a r equi r ement. Thi s coul d be a bug, a new feature, a refactor, or
an opti mi zati on. A si ngl e issue can have many comments so a rel ati onshi p is bui l t
between the issue and comment obj ects.
Li s t i n g 2 . 3 Th e I s s u e m o d e l o b j e c t
pa c ka ge or g. f oj . model ; <1—Q Model Java package
i mpor t or g. a pa c he. c ommons . l a ng. bui l der . Equa l sBui l der ; <—Q I m por t decl arat i ons
J ©Ent i t y
publ i c c l a ss I ssue ext ends Ba seObj ec t i mpl ement s Ser i a l i za bl e {
Java persi st ence
f r am ewor k
pr i va t e Long i d;
pr i va t e St r i ng pr oj ec t ;
pr i va t e St r i ng desc r i pt i on;
pr i va t e St r i ng t ype;
pr i va t e St r i ng sever i t y;
pr i va t e St r i ng st a t us;
pr i va t e St r i ng det a i l s;
pr i va t e St r i ng r epor t edBy;
pr i va t e D a t e r epor t edOn;
pr i va t e St r i ng a ssi gnedTo;
pr i va t e D oubl e est i ma t edHour s;
1
Class i nst ance
vari abl es
@I d
@Gener a t edVa l ue( st r a t egy =
publ i c Long get l dO {
r et ur n i d;
publ i c voi d set I d( Long i d)
t hi s. i d = i d;
Gener a t i onType. AUTO)
Issue ext ends
AppFuse BaseObj ect
J
Decl ares
dat abase pk
r el at i onshi p
?k O
"
P
J
Indi cat es
how t o
generat e Id
1>
1 )
" get t er " met hod
r et ur ns Id
" set t er " met hod
set s Id
www.it-ebooks.info
Build the model objects 21
( i Over r i de <1—.
publ i c i nt ha shCodeO { ^ j j ) hashCode
r et ur n new Ha shCodeBui l der ( 11, 37) . a ppend( i d) . t oHa shCode( ) ;
}
( i Over r i de <1—.
publ i c bool ea n equa l s ( Obj ec t o) { f n equal s
i f ( nul l == o) r et ur n f a l se;
i f ( ! ( o i nst a nc eof I ssue) ) r et ur n f a l se;
i f ( t hi s == o) r et ur n t r ue;
I ssue i nput = ( I ssue) o;
r et ur n new Equa l sBui l der ( )
. a ppend( t hi s. get l d( ) , i nput . get l d( ) )
. i sEqua l s( ) ;
'' { f t t oSt r i ng provi des
( i Over r i de <- J obj ect i nf o
publ i c St r i ng t oSt r i ng( ) {
r et ur n new ToSt r i ngBui l der ( t hi s, ToSt r i ngSt yl e. MULTI _LI NE_STYLE)
. a ppend( i d)
. a ppend( pr oj ec t )
. a ppend( desc r i pt i on)
. t oSt r i ng( ) ;
}
You'l l be stori ng the model obj ects i n di e or g. f oj . model J ava package © and wi l l use
the AppFuse fr amewor k i n conj uncti on wi ti i di e Spri ng Fr amewor k and Hi ber nate to
si mpl i fy our appl i cati on devel opment. Spri ng provi des DI and mor e whi l e Hi ber nate
is a database persi stence fr amewor k that enabl es obj ect rel ati onal mappi ng fr amewor k
Q . The I d Q and Gener a t edVa l ue O annotati on hel p to faci l i tate the persi stence by
desi gnati ng a fi el d as a database pri mary key.
The I ssue obj ect is a subclass of di e AppFuse Ba seObj ec t © and contai ns di e
i nstance vari abl es © you need to descri be an issue. Al l of the i nstance vari abl es or
fields have di e getters © and setters © r equi r ed by the J avaBean speci fi cati on.
NOTE E xtendi ng Ba seObj ec t requi res us to over r i de di e t oSt r i ng
equa l s Q , and ha shCode (J J ) meti i ods because they're defi ned as abstract i n
the Ba seObj ec t class. T o i mpl ement these meti i ods we'r e l ever agi ng the
Apache Commons Bui l der package © for creati ng the el ements for these
meti i ods. Whenever you'r e i mpl ementi ng the Ser i a l i za bl e i nterface, it's a
good i dea to also i mpl ement the equa l s and ha shCode meti i ods and pr ovi de
a ser i a l Ver si onUI D member .
Next you'l l create a model obj ect for a comment. The Comment wi l l be another persis-
tabl e obj ect. Ther e can be many comments to a si ngl e issue. For the r emai nder of the
code sni ppets i n this chapter we'l l use "..." for trivial thi ngs l i ke i mports and getters
and setters of similar obj ects.
www.it-ebooks.info
22 CHAPTER 2 Beginning with J ava
Li st i ng 2 .4 The com m ent model obj ect
©Ent i t y
publ i c c l a ss Comment ext ends Ba seObj ec t i mpl ement s Ser i a l i za bl e { <1—
pr i va t e Long i d;
pr i va t e I ssue i ssue;
pr i va t e St r i ng a ut hor ;
pr i va t e D a t e c r ea t edD a t e;
pr i va t e St r i ng c omment Text ;
@I d
@Gener a t edVa l ue( st r a t egy = Gener a t i onType. AUTO)
publ i c Long get l dO {
r et ur n i d;
publ i c voi d set I d( Long i d) {
t hi s. i d = i d;
@Ma nyToOne( f et c h = Fet c hType. EAGER)
publ i c I ssue get l s s ueO {
r et ur n i ssue;
publ i c voi d set l ssue( I ssue i ssue) {
t hi s. i ssue = i ssue;
( i Over r i de
publ i c i nt ha s hCodeO {
r et ur n new Ha shCodeBui l der ( 11, 37) . a ppend( i d) . t oHa shCode( ) ;
}
( i Over r i de
publ i c bool ea n equa l s( Obj ec t o) {
i f ( nul l == o) r et ur n f a l se;
i f ( ! ( o i nst a nc eof I ssue) ) r et ur n f a l se;
i f ( t hi s == o) r et ur n t r ue;
I ssue i nput = ( I ssue) o;
r et ur n new Equa l sBui l der ( )
. a ppend( t hi s. get l d( ) , i nput . get l d( ) )
. i sEqua l s( ) ;
( i Over r i de
publ i c St r i ng t oSt r i ngO {
r et ur n new ToSt r i ngBui l der ( t hi s, ToSt r i ngSt yl e. MULTI _LI NE_STYLE)
. a ppend( i d)
. t oSt r i ng( ) ;
}
Com m ent 1
decl ar at i on V
A Com m ent has m any-t o-one
^ T r el at i onshi p wi t h Issue
}
www.it-ebooks.info
Build the DAOs 23
There's not much di fference between an I ssue and a Comment The class fields are
related to comments and tiiere is a many-to-one relationship Q with I ssue. We've also
told Hi bernate that we'd like it to eagerly fetch the I ssue when returning di e
Comment . I n typical J ava web devel opment you woul d keep the session open to lazily
load di e I ssue obj ect only when it's referred to at runtime, but because your Flex
application runs external to the J VM you cannot take advantage of this luxury.
Now that you have your model objects built you can create a set of DAOs. You'l l
need a DAO for issue and comment.
2.4 Bui l d t he DAOs
AppFuse provides generi c implementations for DAOs that you can leverage if your
DAOs do nothi ng more than the basic create, retrieve, update, delete (CRUD) opera-
tions. Because your I ssueD a o will do only basic operations, there is no need to defi ne
a concrete I ssueDa o. You can instead use di e Gener i c Hi ber na t eD a o which you'l l see
later when you wire the beans in the application context. The Comment D a o needs to
i mpl ement a couple of operations that go beyond di e basic CRUD operations so you'l l
first create an interface for the Comment D a o.
Li st i n g 2 .5 Th e Com m en t Da o. j a va
publ i c i nt er f a c e Comment Da o ext ends Gener i c Da o<Comment , Long> {
Li st <Comment > get Comment sByl ssuel d( Long i ssuel d) ;
voi d del et eAHComment sFor l ssuel d( Long i ssuel d) ;
The Comment D a o has two simple methods, one that returns a list of Comment objects by
passing in the i ssuel d argument, and another to delete all of di e Comment objects for
an issue. The second method facilitates the del eti ng of I ssue objects. Because
Comment has a forei gn key relationship with I ssue, you cannot delete an I ssue if any
Comment s refer to it.
NOTE We defi ned di e relationship between Comment and I ssue by annotat-
i ng di e fi el d with a OOneToOne annotation, and could have also defi ned di e
reverse of that relationship in the I ssue class by including a Set of Comment
objects bel ongi ng to an I ssue. Because we could not lazy load those objects, it
woul d have forced us to eager load di e Comment objects into the Set , which
woul d force those Comment objects to eager load their I ssue objects. This
forces the I ssue objects to eager load their Comment s, and so on. This usually
results in a stack overfl ow because you've effectively got a circular reference
that causes an infinite l oop of eager fetchi ng.
Now let's i mpl ement the Comr nent Da oI m. pl .
www.it-ebooks.info
47 CHAPTER 2 Beginning with J ava
Li s t i n g 2 . 6 Th e Co m m e n t Da o l m p l . j a v a
publ i c c l a ss Comment D a oI mpl ext ends Gener i c D a oHi ber na t e<Comment , Long>
i mpl ement s Comment D a o {
publ i c Comment D a oI mpl ( ) {
super ( Comment . c l a ss) ;
}
( i Over r i de
( i Suppr essWa r ni ngs ( " unc hec ked" )
publ i c Li st <Comment > get Comment sByl ssuel d( Long i ssuel d) {
r et ur n get Hi ber na t eTempl a t e( ) . f i nd
( "f r om Comment wher e i ssue_i d = ?", i ssuel d) ;
}
Much l i ke tl i e I ssueD a oI mpl , Comment D a oI mpl extends Gener i c D a oHi ber na t e but
i mpl ements Comment D a o. The onl y i nteresti ng thi ng happeni ng her e is tiiat you have a
method tiiat returns a list of Comment obj ects by l ever agi ng the Hi ber nate templ ate
and a query. Spri ng and Hi ber nate are a wonder ful combi nati on and make for cl ean
and i ntui ti ve DAOs.
Now that you've constructed di e DAOs you can bui l d services.
Bui l d t he servi ces
Now you need to expose services to di e web tier. You'l l be abl e to take advantage of
tiiese services for the Fl ex cl i ent you'l l be bui l di ng. Agai n you'l l start wi th i nterfaces
l i ke I ssueMa na ger i n listing 2.7.
Li s t i n g 2 . 7 Th e I s s u e M a n a g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . I ssue;
i mpor t j a va x. j ws. WebSer vi c e;
i mpor t j a va . ut i l . Li st ;
( i WebSer vi c e
publ i c i nt er f a c e I ssueMa na ger
Li st <I ssue> get AHO;
I ssue get ( Long i d) ;
I ssue sa ve( I ssue i ssue) ;
voi d r emove( Long i d) ;
You defi ne the I ssueManager as a web servi ce by annotati ng it usi ng OWebServi ce
O - I ssueManager contai ns methods defi ni ng your basic CRUD operati ons for read-
i ng © and ©, creati ng and updati ng Q , and del eti ng Q . Now l et's take a l ook at
the CommentManager.
A IssueManager i nt erf ace
decl ar at i on wi t h
WebSer vi ce annot at i on
Ret urn al l
1>
Q R
< j _J is
< , _r i ssue by i t s ID
1>
i ssues A Get speci f i c
< - J is
_ Save i ssue
Del et e i ssue
www.it-ebooks.info
Build the services 25
Li s t i n g 2 . 8 Th e Co m m e n t M a n a g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . Comment ;
i mpor t j a va x. j ws. WebSer vi c e;
i mpor t j a va . ut i l . Li st ;
@WebSer vi c e
publ i c i nt er f a c e Comment Ma na ger
Comment Manager
i nt erf ace decl arat i on
wi t h WebSer vi ce
annot at i on
{
Li st <Comment > f i ndComment sByl ssuel d( Long i ssuel d) ;
voi d del et eAHComment sFor l ssuel d( Long i ssuel d) ;
Comment get ( Long i d) ;
Comment sa ve( Comment c omment ) ;
voi d r emove( Long i d) ;
1 ,
Remove
comment
Save
comment
Get comment s
f or i ssue Id
Del et e al l
comment s
f or i ssue
Comment Ma na ger is also a web servi ce O by vi rtue of it havi ng the OWebSer vi c e anno-
tati on j ust as wi th the I ssueMa na ger . I t contai ns a method to return a list of Comment
obj ects by pr ovi di ng an i ssuel d a method for del eti ng all comments for an issue
i d Q , a method for saving a comment Q and a method for del eti ng a comment Q .
Now l et's pr ovi de i mpl ementati on for the servi ces l i ke I ssueMa na ger l mpl .
Li s t i n g 2 . 9 Th e I s s u e M a n a g e r l m p l . j a v a
pa c ka ge or g. f oj . ser vi c e. i mpl ;
i mpor t or g. AppFuse. da o. Gener i c D a o;
i mpor t or g. f oj . model . I ssue;
i mpor t or g. f oj . ser vi c e. I ssueMa na ger ;
i mpor t or g. f oj . ser vi c e. Comment Ma na ger ;
i mpor t j a va . ut i l . Li st ;
i mpor t j a va x. j ws. WebSer vi c e;
( i WebSer vi c e( ser vi c eNa me = " I ssueSer vi c e" ,
endpoi nt l nt er f a c e = " or g. f oj . ser vi c e. I ssueMa na ger " )
publ i c c l a ss I ssueMa na ger l mpl i mpl ement s I ssueMa na ger {
pr i va t e Gener i c D a o<I ssue, Long> i ssueD a o;
pr i va t e Comment Ma na ger Comment Ma na ger ;
publ i c I ssueMa na ger l mpl ! ) {
}
publ i c I ssueMa na ger l mpl ( Gener i c D a o<I ssue, Long> i ssueD a o,
Comment Ma na ger Comment Ma na ger ) {
t hi s. i ssueD a o = i ssueD a o;
t hi s. Comment Ma na ger = Comment Ma na ger ;
}
A IssueManagerl mpl
decl arat i on wi t h
WebSer vi ce
annot at i on
J
Def aul t no arg
const r uct or
1>
Const r uct or
publ i c Li st <I ssue> get AHO {
r et ur n i ssueD a o. get Al l ( ) ;
}
Met hod t hat
r et ur ns al l Issues
www.it-ebooks.info
CHAPTER 2 Beginning with J ava
publ i c I ssue get ( Long i d) {
r et ur n i ssueD a o. get ( i d) ;
}
publ i c I ssue sa ve( I ssue i ssue) {
r et ur n i ssueD a o. sa ve( i ssue) ;
}
publ i c voi d r emove( Long i d) {
c omment Ma na ger . del et eAHComment sFor l ssuel d( i d) ;
i ssueD a o. r emove( i d) ;
}
Get speci f i c i ssue
Save i ssue
1>
Remove an i ssue
}
The I ssueManager l mpl also uses the OWebServi ce annotati on j ust as i n the i nterface,
but provi des di e ser vi ceName and en dpoi n t l n t er f ace attributes Q . You pr ovi de a
defaul t no args constructor Q as wel l as one tiiat wi l l be used by Spri ng to i nj ect di e
I ssueDao and CommentManager ©. Next i mpl ement di e methods for returni ng the list
of I ssue obj ects Q , returni ng a speci fi c I ssue Q , and saving an I ssue Q by del egat-
i ng di e calls to di ose meti i ods to di e I ssueDao. The i mpl ementati on for r emovi ng an
issue Q first del etes any comments for di e issue by cal l i ng di e CommentManager, tiien
r emoves di e issue by cal l i ng di e r emove meti i od on di e I ssueDao. Now l et's l ook at
di e CommentManager.
Li s t i n g 2 . 1 0 Th e Co m m e n t M a n a g e r l m p l . j a v a
pa c ka ge or g. f oj . ser vi c e. i mpl ;
i mpor t or g. f oj . da o. Comment D a o;
i mpor t or g. f oj . model . Comment ;
i mpor t or g. f oj . ser vi c e. Comment Ma na ger ;
i mpor t j a va . ut i l . Li st ;
i mpor t j a va x. j ws. WebSer vi c e;
Comment Managerl mpI
decl ar at i on wi t h
WebSer vi ce annot at i on
( i WebSer vi c e ( ser vi c eNa me = " Comment Ser vi c e" ,
endpoi nt l nt er f a c e = " or g. f oj . ser vi c e. Comment Ma na ger " )
publ i c c l a ss Comment Ma na ger l mpI i mpl ement s Comment Ma na ger {
pr i va t e Comment D a o c omment D a o;
publ i c Comment Ma na ger l mpI ( ) {
}
J ?
Def aul t no args
const r uct or
publ i c Comment Ma na ger l mpI ( Comment D a o c omment D a o) { <—
t hi s. c omment D a o = c omment D a o;
publ i c Li st <Comment > f i ndComment sByl ssuel d( Long i ssuel d)
r et ur n c omment D a o. get Comment sByl ssuel d( i ssuel d) ;
}
publ i c voi d del et eAHComment sFor l ssuel d( Long i ssuel d) {
c omment D a o. del et eAHComment sFor l ssuel d( i ssuel d) ;
}
Const r uct or set s
i nj ect ed Comment Dao
i nst ance t o use
J
Fi nd
comi
f o r i !
al l
comment s
i ssue
1
Del et e al l
comment s
f or i ssue
www.it-ebooks.info
Wiring things together with Spring 27
publ i c Comment get ( Long i d) {
r et ur n c omment D a o. get ( i d) ;
}
publ i c Comment sa ve( Comment c omment ) {
r et ur n c omment D a o. sa ve( c omment ) ;
}
publ i c voi d r emove( Long i d) {
c omment D a o. r emove( i d) ;
}
1,
Get speci f i c
comment
Save comment
Del et e comment
Li ke I ssueMa na ger l mpl , Comment Ma na ger l mpl decl ares itself to be a WebSer vi c e O-
Next usi ng di e @WebSer vi c e annotati on and defi nes its endpoi nt i nter face and
servi ce name you create a defaul t no args constructor Q as wel l as one that wi l l be
used by Spri ng to i nj ect your Comment D a o You i mpl ement the methods to get the
Comment obj ects for an issue del eti ng all the Comment obj ects for an issue Q , get-
ti ng a speci fi c Comment saving a Comment Q , and del eti ng a Comment © by del egat-
i ng to di e Comment D AO.
NOTE AppFuse provi des Gener i c Ma na ger i mpl ementati on base classes j ust as
it does for DAOs, but we chose not to use them her e because certai n Web-
Ser vi c e consumers such as Fl ex have di ffi cul ty deal i ng wi th web services that
return obj ects such as Ar r a yOf AnyType, whi ch is what AppFuse wi l l return i f
we l everage the Gener i c Ma na ger s. T o wor k ar ound this issue you'l l be defi n-
i ng and i mpl ementi ng your CRUD operati ons for the web services expl i ci tl y.
We'r e now offi ci al l y done wi th the server-side obj ects and can wi re tilings together
wi th the Spri ng confi gur ati on and wor k on the web tier components.
Wi ri ng t hi ngs t oget her wi t h Spri ng
Spri ng enabl es devel oper s to easily connect obj ects whi l e keepi ng appl i cati on compo-
nents l oosel y coupl ed and testable. Noti ce how we've wi r ed di e model , DAO, and ser-
vi ce obj ects together i n di e fol l owi ng listing. The appl i cati onContext. xml is l ocated i n
the src\ main\ webapp\ WEB-INF di rectory, wi th other confi gur ati on files.
Li s t i n g 2 . 1 1 Th e a p p l i c a t i o n Co n t e x t . x m l
is
<! - - Add new D AOs her e - - >
<bea n i d=" i ssueD a o" c l a ss= 0 i ssueDao
" or g. AppFuse. da o. hi ber na t e. Gener i c D a oHi ber na t e" >
<c onst r uc t or - a r g va l ue=" or g. f oj . model . I ssue" / >
<pr oper t y na me=" sessi onFa c t or y" r ef =" sessi onFa c t or y" / >
</ bea n>
<bea n i d=" c omment D a o" c l a ss=" or g. f oj . da o. i mpl . Comment D a oI mpl " >
<pr oper t y na me=" sessi onFa c t or y" r ef =" sessi onFa c t or y" / >
</ bea n> comment Dao
1
www.it-ebooks.info
28 CHAPTER 2 Beginning with J ava
<! - - Add new Ma na ger s her e - - >
<bea n i d=" i ssueMa na ger " c l a ss=" or g. f oj . ser vi c e. i mpl . I ssueMa na ger l mpl " >
<c onst r uc t or - a r g r ef =" i ssueD a o" / >
</ bea n> i ssueManager
•1
<bea n i d=" c omment Ma na ger " c l a ss= | J 5f COmment Manager
" or g. f oj . ser vi c e. i mpl . Comment Ma na ger l mpl " >
<c onst r uc t or - a r g r ef =" c omment D a o" / >
</ bea n>
The fi rst bean you defi ne is Gener i c D a o for di e i ssueD a o Q . The c omment D a o Q is
defi ned wi di your concr ete i mpl ementati on. Next, you create Spri ng beans for i ssue-
Ma na ger Q and c omment Ma na ger Q . The c onst r uc t or - a r g el ement is used to i nj ect
di e dependenci es i nto the servi ce class constructor.
Now tiiat we've wi r ed thi ngs up wi ti i Spri ng let's construct the web ti er starting
wi th Struts 2 fr amewor k acti on classes.
2.7 Const ruct i ng t he web t i er
Struts 2 appl i cati ons i mpl ement the Model - Vi ew- Contr ol l er ( MVC) desi gn pattern,
whi ch is not to be confused wi ti i the MVP desi gn pattern used to devel op di e Fl ex
appl i cati on. The pattern encourages separati on between the data model , vi ew ele-
ments, and control l ers that sit between tiiem. The MVC pattern, wi del y adopted i n di e
J ava communi ty, has made its way i nto oti i er l anguages and frameworks, l i ke Fl ex.
2.7.1 Building Struts 2 action classes
You'l l start by bui l di ng contr ol l er or action classes first, l i ke I ssueAc t i on.
Li s t i n g 2 . 1 2 Th e I s s u e Ac t i o n . j a v a
pa c ka ge or g. f oj . a c t i on;
i mpor t or g. AppFuse. weba pp. a c t i on. Ba seAc t i on;
publ i c c l a ss I ssueAc t i on ext ends Ba seAc t i on {
pr i va t e I ssueMa na ger i ssueMa na ger ;
pr i va t e Comment Ma na ger c omment Ma na ger ;
pr i va t e Li st <I ssue> i ssues;
pr i va t e Li st <Comment > c omment s;
pr i va t e I ssue i ssue;
pr i va t e Long i d;
publ i c voi d set l ssueMa na ger ( I ssueMa na ger i ssueMa na ger ) { <1—
t hi s. i ssueMa na ger = i ssueMa na ger ;
}
publ i c voi d set Comment Ma na ger ( Comment Ma na ger c omment Ma na ger ) { <—
t hi s. c omment Ma na ger = c omment Ma na ger ;
}
IssueAct i on ext ends
AppFuse BaseAct i on
Set t ers f or A
IssueManager and
Comment Manager
www.it-ebooks.info
Constructing the web tier 29
publ i c St r i ng l i st ( ) {
i ssues = i ssueMa na ge
r et ur n SUCCESS;
i ssueMa na ger . get Al l ( ) ;
Ret urns l i st of
Issue obj ect s
publ i c St r i ng del et ed {
i ssueMa na ger . r emove( i ssue. get l d( ) ) ;
sa veMessa ge( get Text ( " i ssue. del et ed" ) ) ;
Del et es Issue
r et ur n SUCCESS;
}
publ i c St r i ng edi t ( ) {
i f ( i d != nul l ) {
Edi t s by Issuel d
i ssue = i ssueMa na ger . get ( i d) ;
} el se {
i ssue = new I s s ued;
}
c omment s = c omment Ma na ger . f i ndComment sByl ssuel d( i ssue. get l d( ) ) ;
r et ur n SUCCESS;
publ i c St r i ng s a ved t hr ows Exc ept i on {
i f ( del et e != nul l ) {
r et ur n del et e( ) ;
}
bool ea n i sNew = ( i ssue. get l d( ) == nul l ) ;
i ssue = i ssueMa na ger . sa ve( i ssue) ;
St r i ng key = i sNew ? " i ssue. a dded" : " i ssue. upda t ed" ;
sa veMessa ge( get Text ( key) ) ;
i f ( ! i sNew) {
r et ur n I NPUT;
} el se {
r et ur n SUCCESS;
I ssueAc t i on extends di e AppFuse Ba seAc t i on © that contai ns many common metl i -
ods di at acti ons rel y on. I ssueAc t i on has setters for the servi ce obj ects These set-
ters wi l l be cal l ed by Spri ng, and thei r instances wi l l be i nj ected i nto the acti on class
dur i ng runti me. I ssueAc t i on facilitates contr ol l i ng communi cati ons to the server
side f r om di e web tier. I t contai ns the methods for di e vi ew pages to list ©, del ete Q ,
edi t Q or, most i mportantl y, save I ssue obj ects ©.
The Comment Ac t i on obj ect serves the same purpose for di e Comment obj ect as the
I ssueAc t i on obj ect does for di e I ssue obj ect. Al l the methods on Comment Ac t i on are
i f ( c a nc el != nul l ) {
r et ur n CANCEL;
Saves Issue
}
}
www.it-ebooks.info
3 0 CHAPTER 2 Beginning with J ava
faci l i tati ng CRUD for the Comment POJ O by cal l i ng the commentManager service. The
CommentActi on class can be downl oaded f r om the websi te i f needed.
Now that di e acti ons are i n pl ace, l et's wor k on J SP fi l es to create a si mpl e UI for
managi ng issues.
2.7.2 Editing the issue menu item
First you have to modi fy di e menu.j sp to get to the issues list.
Li s t i n g 2 . 1 3 Th e m e n u . j s p
<menu: di spl a yMenu na me=" Ma i nMenu" / >
<menu: di spl a yMenu na me=" User Menu" / > O Addi ng IssueMenu i t em
<menu: di spl a yMenu na me=" I ssueMenu" / > <—' t o t he JSP vi ew f i l e
<menu: di spl a yMenu na me=" Admi nMenu" / >
<menu: di spl a yMenu na me=" Logout " / >
The menu J SP fi l e reads i n di e menu xml data. To add the I ssue menu i tem you
need onl y add a si ngl e l i ne O to tiiis fi l e that is l ocated i n di e fl ex- bugs- web/ src/
mai n/ webapp/ common di rectory. I n di e fol l owi ng l i sti ng you'l l pr ovi de di e xml
data for that menu i tem.
Li s t i n g 2 . 1 4 Th e m e n u -c o n f i g . xm l
<Menu na me=" I ssueMenu" t i t l e=" menu. i ssue"
desc r i pt i on=" I ssues Menu"
r ol es=" ROLE_AD MI N, ROLE_USER" pa ge=" / i ssues. ht ml " >
<I t em na me=" Vi ewl ssues" t i t l e=" menu. vi ewl ssues" pa ge=" / i ssues. ht ml " / >
</ Menu>
I A Add Issue menu i t em
f t o menu dat a xml f i l e
By addi ng to di e exi sti ng AppFuse pl umbi ng that creates menu i tems O , you qui ckl y
gai n access to new features. Let's create the IssueList.jsp that wi l l be di spl ayed when
you click di e issues menu i tem.
2.7.3 Adding JSP resources
The issueList.jsp wi l l display a list of issues and al l ow you to add or modi fy exi sti ng
issues. The issue and comment J SP fi l es wi l l resi de i n the ../ src/ mai n/ webapp/ WEB-
I NF/ pages di rectory.
Li s t i n g 2 . 1 5 Th e i s s u e Li s t . j s p
<%@ i nc l ude f i l e=" / c ommon/ t a gl i bs. j sp" %>
<hea d>
<t i t l exf mt : messa ge key=" i ssueLi st . t i t l e" / ></ t i t l e>
<met a c ont ent =" <f mt : messa ge key=
1
i ssueLi st . hea di ng
1
/ >
</ hea d>
Essent i al t ag
O l i brari es bundl e
" na me=" hea di ng" / >
www.it-ebooks.info
Constructing the web tier 31
<c : set va r =" but t ons " > <1—Q
<i nput t ype=" but t on" st yl e=" ma r gi n- r i ght : 5px"
onc l i c k=" l oc a t i on. hr ef =
1
<c : ur l va l ue=" edi t l ssue
va l ue=" <f mt : messa ge key=" but t on. a dd" / >" / >
<i nput t ype=" but t on" onc l i c k=" l oc a t i on. hr ef =
' <c : ur l va l ue=" / ma i nMenu. ht ml " / >
1
"
va l ue=" <f mt : messa ge key=" but t on. done" / >" / >
</ c : set >
<c : out va l ue=" ${but t ons}" esc a peXml =" f a l se" / >
<s: set na me=" i ssues" va l ue=" i ssues" sc ope=" r equest " / >
Vari abl e hol ds but t on dat a
ht ml " / >
1
"
Pri nt s
but t on dat a
f or di spl ay
J
Vari abl e
represent s
i ssues l i st
<di spl a y: t a bl e na me=" i ssues" c l a ss=" t a bl e" r equest URI =" " i d=" i ssueLi st " <
expor t =" f a l se" pa gesi ze=" 25 " >
<di spl a y: c ol umn pr oper t y=" i d" sor t a bl e=" t r ue" hr ef =" edi t l ssue. ht ml "
pa r a ml d=" i d" pa r a mPr oper t y=" i d" t i t l eKey=" i ssue. i d" / >
<di spl a y: c ol umn pr oper t y=" pr oj ec t " sor t a bl e=" t r ue"
t i t l eKey=" i ssue. pr o j ec t " / > Di spl ays ni cel y
<di spl a y: c ol umn pr oper t y=" desc r i pt i on " sor t a bl e=" f a l se " f or m at t ed t abl e
t i t l eKey=" i ssue. desc r i pt i on" / >
<di spl a y: set Pr oper t y na me=" pa gi ng. ba nner . i t em_na me" va l ue=" i ssue" / >
<di spl a y: set Pr oper t y na me=" pa gi ng. ba nner . i t ems_na me" va l ue=" i ssues" / >
</ di spl a y: t a bl e>
<c : out va l ue=" ${but t ons}" esc a peXml =" f a l se" / >
<sc r i pt t ype=" t ext / j a va sc r i pt " >
hi ghl i ght Ta bl eRows( " i ssueLi st " ) ;
</ sc r i pt >
JavaScri pt hi ghl i ght s
t abl e rows
To make l i fe easier, you i ncl ude a J SP that i n turn i ncl udes a bundl e of tag l i brari es O
that are useful for di e web appl i cati on. You have button data that wi l l be stored i n a
vari abl e Q and a J ava Standard Tag Li brary (J STI.) tag Q that wi l l pr i nt di e buttons.
You create a vari abl e tiiat wi l l hol d a list of issues Q f r om di e request scope and an
HTML tabl e tiiat is for matted usi ng the i ncl uded display tag l i brary Q . A little
J avaScri pt is used to hi ghl i ght rows of data ©. Now l et's have a l ook at the issue-
F or mj sp.
Li st i ng 2 .1 6 The i ssueFor m .j sp
<%@ i nc l ude f i l e=" / c ommon/ t a gl i bs. j sp" %>
<hea d>
<t i t l exf mt : messa ge key=" i ssueD et a i l . t i t l e" / ></ t i t l e>
<met a c ont ent =" <f mt : messa ge key=
1
i ssueD et a i l . hea di ng
1
/ >" / >
</ hea d>
" s " St rut s 2 A
f orm t ag i n
act i on
<s: f or m i d=" i ssueFor m" a c t i on=" sa vel ssue" met hod=" post " va l i da t e=" t r ue" >
<s: hi dden na me=" i ssue. i d" va l ue=" %{i ssue. i d}" / >
Form t ext
<s: t ext f i el d key=" i ssue. pr oj ec t " r equi r ed=
"t r ue" c ssCl a ss=" t ext medi um" / >
<s: t ext f i el d key=" i ssue. desc r i pt i on" r equi r ed=" t r ue"
c ssCl a ss=" t ext medi um" / >
f '
i nput f i el ds
www.it-ebooks.info
55 CHAPTER 2 Beginning with J ava
<s: t ext f i el d key=" i ssue. t ype" r equi r ed=" t r ue" c ssCl a ss=" t ext medi um" / >
<s: t ext f i el d key=" i ssue. sever i t y" r equi r ed=" t r ue" c ssCl a ss=" t ext medi um" / >
<s: t ext f i el d key=" i ssue. st a t us" r equi r ed=" t r ue" c ssCl a ss=" t ext medi um" / >
<s: t ext a r ea key=" i ssue. det a i l s" r equi r ed=" t r ue" c ssCl a ss=" t ext medi um" / >
<l i c l a ss=" but t onBa r bot t om" > <—I
<s: submi t c ssCl a ss=" but t on" met hod=" sa ve" A CRUD But t on bar
key=" but t on. sa ve" t heme=" si mpl e" / >
<c : i f t est =" ${not empt y i ssue. i d}" >
<s: submi t c ssCl a ss=" but t on" met hod=" del et e"
key=" but t on. del et e" onc l i c k=" r et ur n c onf i r mD el et e(
1
i ssue
1
) "
t heme=" si mpl e" / >
</ c : i f >
<s: submi t c ssCl a ss=" but t on" met hod=" c a nc el "
key=" but t on. c a nc el " t heme=" si mpl e" / >
</ 1 i >
</ s: f or m>
<c : i f t est =" ${not empt y i ssue. i d}" >
<s: f or m i d=" c omment sFor m" a c t i on=" edi t Comment
met hod=" post " va l i da t e=" t r ue" >
<s: set na me=" c omment s" va l ue=" c omment s" sc ope=" r equest " / >
<s: hi dden na me=" i ssue. i d" va l ue=" %{i ssue. i d}" / >
<di spl a y: t a bl e na me=" c omment s" c l a ss=" t a bl e"
r equest URI =" " i d=" c omment Li st " expor t =" f a l se" pa gesi ze=" 25" >
<di spl a y: c ol umn pr oper t y=" i d" sor t a bl e=" t r ue" hr ef =" edi t Comment . ht ml "
pa r a ml d=" i d" pa r a mPr oper t y=" i d" t i t l eKey=" c omment . i d" / >
<di spl a y: c ol umn pr oper t y=" a ut hor "
sor t a bl e=" t r ue" t i t l eKey=" c omment . a ut hor " / >
<di spl a y: c ol umn pr oper t y=" c omment Text "
sor t a bl e=" f a l se" t i t l eKey=" c omment . c omment Text " / >
<di spl a y: set Pr oper t y na me=" pa gi ng. ba nner . i t em_na me" va l ue=" c omment " / >
<di spl a y: set Pr oper t y na me=" pa gi ng. ba nner . i t ems_na me" va l ue=" c omment s" / >
</ di spl a y: t a bl e>
<s: submi t c ssCl a ss=" but t on" key=" but t on. a dd" t heme=" si mpl e" / >
</ s: f or m>
</ c : i f >
<sc r i pt t ype=" t ext / j a va sc r i pt " >
hi ghl i ght Ta bl eRows( " c omment Li st " ) ;
</ sc r i pt >
<sc r i pt t ype=" t ext / j a va sc r i pt " >
For m. f oc usFi r st El ement ( $( " i ssueFor m" ) ) ;
</ sc r i pt >
Obviously, tl i e issueForm.jsp wi l l al l ow a user to add or edi t an issue. I f you peek i nto
di e i ncl uded sr c/ mai n/ webapp/ common/ tagl i bs. j sp you'l l noti ce that the Struts 2 tag
l i brari es are i ncl uded and the l etter "s" was used for di e tag pr efi x Q . The Struts 2
t ext f i el d el ements Q map to an I ssue obj ect. The button bar created wi l l contai n
I Comment s
St rut s 2 f or m
JavaScri pt
assi gns f ocus
www.it-ebooks.info
Constructing the web tier 33
Save, Del ete, and Cancel buttons The Del ete button wi l l display onl y i f the issue has
an i d or al ready exists. Let's keep movi ng and bui l d the commentF or m. j sp.
Li s t i n g 2 . 1 7 Th e c o m m e n t Fo r m . j s p
<%@ i nc l ude f i l e=" / c ommon/ t a gl i bs. j sp" %>
<hea d>
<t i t l exf mt : messa ge key=" c omment D et a i l . t i t l e" / ></ t i t l e>
<met a c ont ent =" <f mt : messa ge key=
1
c omment D et a i l . hea di ng
1
/ >" / >
</ hea d>
<s: f or m i d=" c omment For m" a c t i on=" sa veComment " met hod=" post " va l i da t e=" t r ue" >
<s: hi dden na me=" c omment . i d" va l ue=" %{c omment . i d}" / >
<s: hi dden na me=" i ssue. i d" va l ue=" %{i ssue. i d}" / >
<s: t ext f i el d key=" c omment . a ut hor " r equi r ed=" t r ue" c ssCl a ss=" t ext medi um" / >
<s: t ext f i el d key=" c omment . c r ea t edD a t e" r equi r ed=" f a l se"
c ssCl a ss=" t ext medi um" / >
<s: t ext a r ea key=" c omment . c omment Text " r equi r ed=" f a l se"
c ssCl a ss=" t ext medi um" / >
<l i c l a ss=" but t onBa r bot t om" >
<s: submi t c ssCl a ss=" but t on" met hod=" sa ve"
key=" but t on. sa ve" t heme=" si mpl e" / >
<c : i f t est =" ${not empt y c omment . i d}" >
<s: submi t c ssCl a ss=" but t on" met hod=" del et e"
key=" but t on. del et e" onc l i c k=" r et ur n c onf i r mD el et e(
1
c omment
1
) "
t heme=" si mpl e" / >
</ c: i f >
<s: submi t c ssCl a ss=" but t on" met hod=" c a nc el "
key=" but t on. c a nc el " t heme=" si mpl e" / >
</ 1 i >
</ s: f or m>
As di e name suggests, di e commentFor m. j sp provi des a Struts 2 for m for updati ng
new or exi sti ng comments. When submi tted, di e for m wi l l call the comment man-
ager's sa veComment method. Now that you have the J SP fi l es i n pl ace we'l l need to add
those properti es so that they have real values.
2 .7 .4 Adding property resources
For the appl i cati on's messages to be l ocal i zed, we've l ever aged di e J ava resource bun-
dl e fr amewor k. Add the properti es shown i n the fol l owi ng listing to the Appl i cati on-
Resources.properti es fi l e l ocated i n di e fl ex- bugs- web/ src/ mai n/ resources di rectory.
Li s t i n g 2 . 1 8 Th e Ap p l i c a t i o n Re s o u r c e s . p r o p e r t i e s
# - - menu/ l i nk messa ges - -
menu. i ssue=I ssues
menu. vi ewI ssues=Vi ew I ssues
# - - i ssue f or m - -
i ssue. i d=I d
www.it-ebooks.info
3 4 CHAPTER 2 Beginning with J ava
i ssue. pr oj ec t =Pr oj ec t
i ssue. desc r i pt i on=D esc r i pt i on
i ssue. a dded=I ssue ha s been a dded suc c essf ul l y,
i ssue. upda t ed=I ssue ha s been upda t ed suc c essf ul l y,
i ssue. del et ed=I ssue ha s been del et ed suc c essf ul l y.
# - - i ssue l i st pa ge - -
i ssueLi st . t i t l e=I ssue Li st
i ssueLi st . hea di ng=I ssues
# - - i ssue det a i l pa ge - -
i ssueD et a i l . t i t l e=I ssue D et a i l
i ssueD et a i l . hea di ng=I ssue I nf or ma t i on
# - - c omment f or m - -
c omment . i d=I d
c omment . a ut hor =Aut hor
c omment . i ssuel d=l ssue I d
c omment . c r ea t edD a t e=Cr ea t ed D a t e
c omment . c omment Text =D et a i l s
c omment . a dded=Comment ha s been a dded suc c essf ul l y,
c omment . upda t ed=Comment ha s been upda t ed suc c essf ul l y,
c omment . del et ed=Comment ha s been del et ed suc c essf ul l y.
# - - i ssue l i st pa ge - -
c omment Li st . t i t l e=Comment Li st
c omment Li st . hea di ng=Comment s
# - - i ssue det a i l pa ge - -
c omment D et a i l . t i t l e=Comment D et a i l
c omment D et a i l . hea di ng=Comment I nf or ma t i on
I f mor e l anguage support is needed, add di e same pr oper ti es wi th the respecti ve
transl ati on to the appr opr i ate pr oper ti es fi l e i n the same di rectory. Now l et's wi re up
di e vi ew components wi th Struts 2.
2.7.5 Configuring the struts.xml
To wi re up the J SP vi ew components to the contr ol l er obj ects, you can use the
struts.xml l ocated i n di e src/ mai n/ resources di rectory. Thi s listing demonstrates
di e wi ri ng you need for the issues management.
Li s t i n g 2 . 1 9 Th e s t r u t s . x m l
<pa c ka ge>
<! — Add a ddi t i ona l a c t i ons her e - - >
<a c t i on na me=" i ssues"
c l a ss=" or g. f oj . a c t i on. I ssueAc t i on" met hod=" l i st " >
<r esul t >/ WEB- I NF/ pa ges/ i ssueLi st . j sp</ r esul t >
</ a c t i on>
<a c t i on na me=" edi t l ssue"
c l a ss=" or g. f oj . a c t i on. I ssueAc t i on" met hod=" edi t " >
<r esul t >/ WEB- I NF/ pa ges/ i ssueFor m. j sp</ r esul t >
i A i ssues act i on l oads
If i ssueLi st .j sp
i A edi t l ssue l oads
I f i ssueForm .j sp
www.it-ebooks.info
Constructing the web tier 35
<r esul t na me=" er r or " >/ WEB- I NF/ pa ges/ i ssueLi st . j sp</ r esul t >
</ a c t i on>
<a c t i on na me=" sa vel ssue"
savel ssue l oads
i ssueForm
c l a ss=" or g. f oj . a c t i on. I ssueAc t i on" met hod=" sa ve" > | I SSl i erorm
<r esul t na me=" i nput " >/ WEB- I NF/ pa ges/ i ssueFor m. j sp</ r esul t >
<r esul t na me=" c a nc el " t ype=" r edi r ec t - a c t i on" >i ssues</ r esul t >
<r esul t na me=" del et e" t ype=" r edi r ec t - a c t i on" >i ssues</ r esul t >
<r esul t na me=" suc c ess" t ype=" r edi r ec t - a c t i on" >
<pa r a m na me=" a c t i onNa me" >edi t l ssue</ pa r a m>
<pa r a m na me=" i d" >${i ssue. i d}</ pa r a m>
</ r esul t >
</ a c t i on>
<a c t i on na me=" c omment s" c l a ss=" or g. f oj . a c t i on. Comment Ac t i on"
met hod=" l i st " >
<r esul t >/ WEB- I NF/ pa ges/ c omment Li st . j sp</ r esul t >
</ a c t i on>
<a c t i on na me=" edi t Comment " c l a ss=" or g. f oj . a c t i on. Comment Ac t i on"
met hod=" edi t " >
<r esul t >/ WEB- I NF/ pa ges/ c omment For m. j sp</ r esul t >
<r esul t na me=" er r or " >/ WEB- I NF/ pa ges/ c omment Li st . j sp</ r esul t >
</ a c t i on>
<a c t i on na me=" sa veComment " c l a ss=" or g. f oj . a c t i on. Comment Ac t i on"
met hod=" sa ve" >
<r esul t na me=" i nput " >/ WEB- I NF/ pa ges/ c omment For m. j sp</ r esul t >
<r esul t na me=" c a nc el " t ype=" r edi r ec t - a c t i on" >
<pa r a m na me=" a c t i onNa me" >edi t l ssue</ pa r a m>
<pa r a m na me=" i d" >${i ssue. i d}</ pa r a m>
</ r esul t >
<r esul t na me=" del et e" t ype=" r edi r ec t - a c t i on" >
<pa r a m na me=" a c t i onNa me" >edi t l ssue</ pa r a m>
<pa r a m na me=" i d" >${i ssue. i d}</ pa r a m>
</ r esul t >
<r esul t na me=" suc c ess" t ype=" r edi r ec t - a c t i on" >
<pa r a m na me=" a c t i onNa me" >edi t l ssue</ pa r a m>
<pa r a m na me=" i d" >${i ssue. i d}</ pa r a m>
</ r esul t >
</ a c t i on>
</ pa c ka ge>
Struts 2 makes it si mpl e to wi re up the vi ew components qui ckl y and make changes.
As you can see, di e i ssues acti on © wi l l l oad di e i ssueLi st . j sp whenever di e
l i st ( ) medi od is i nvoked. I n di e same way, edi t l ssue © wi l l l oad the i ssue-
For m. j sp when the edi t () method is cal l ed and i f tiiat doesn't work, it wi l l go back to
the list page. The sa vel ssue acti on © wi l l persist an issue by taki ng the i nput f r om
the i ssueFor m. j sp.
The r emai nder of di e I ssueAc t i on is mor e of the same but pertai ns to issue
comments.
www.it-ebooks.info
36 CHAPTER 2 Beginning with J ava
2.7.6 Configuring Hibernate
The fi nal step is to confi gur e the POJ Os wi th the Hi ber nate session factory. That way
when the app is l oaded i nto memor y, Hi ber nate recogni zes tiiese obj ects. You do
di i s thr ough the hi ber nate. cfg. xml l ocated i n di e src/ mai n/ resources di rectory.
Li s t i n g 2 . 2 0 Th e h i b e r n a t e . c f g . x m l
<! D OCTYPE hi ber na t e- c onf i gur a t i on PUBLI C " - / / Hi ber na t e/ Hi ber na t e
Conf i gur a t i on D TD 3. 0/ / EN"
" ht t p: / / hi ber na t e. sour c ef or ge. net / hi ber na t e- c onf i gur ât i on- 3. 0. dt d" >
<hi ber na t e- c onf i gur a t i on>
<sessi on- f a c t or y>
<ma ppi ng c l a ss=" or g. AppFuse. model . User " / >
<ma ppi ng c l a ss=" or g. AppFuse. model . Rol e" / >
<ma ppi ng c l a ss=" or g. f oj . model . I ssue" / >
<ma ppi ng c l a ss=" or g. f oj . model . Comment " / >
</ sessi on- f a c t or y>
</ hi ber na t e- c onf i gur a t i on>
I n this si mpl e confi gurati on, you create a class mappi ng Q for each of di e model
obj ects, I ssue and Comment . Rebui l d the appl i cati on wi ti i the mvn j et t y: r un- wa r
command, then refresh your browser. The Issues button shoul d be avai l abl e as seen i n
fi gur e 2.7.
AppFu se
Providing integration and style to open source J ava.
Main Menu Edit Profile Issues Administration Logout
Issues
Add | Done [
No issues found.
Id Project Description
Nothing found to display.
Add | Done |
Ve rs i o n l . O -S N A P S H O T | XH T M L Va li d ! C S S Va li d | L o g g e d in a s : a d m i n © 2 0 0 8 Y o u r <
I A Addi ng i ssue
If and comment
Fi gur e 2 .7 The i ssues l i st page wi t h t he i nt egr at ed I ssues menu but t on
www.it-ebooks.info
Summary 37
2.8 Summary
I n this chapter we set up a J ava web appl i cati on usi ng the AppFuse fr amewor k. App-
Fuse si mpl i fi ed the pl umbi ng i nvol ved i n bui l di ng a typical J ava web appl i cati on by
usi ng many popul ar frameworks, for exampl e Struts 2, Spri ng, and Hi ber nate.
I n di e next chapter we'l l start bui l di ng the ri ch i nter face for the sampl e appl i ca-
ti on i n Fl ex. I n di e fol l owi ng chapters we'l l begi n to connect di e Fl ex fr ont end to the
J ava appl i cati on usi ng web services and BlazeDS.
www.it-ebooks.info
Getting rich wit
Thi s chapt er covers
• C re a t i n g a F l e x p ro j e c t u s i n g a rc h e t y p e
• C re a t i n g a F l e x f ro n t e n d f o r t h e s a m p l e
a p p l i c a t i o n
• A d d i n g a w ra p p e r f o r a n S WF
I n chapter 2 we i ntroduced you to AppFuse and created our sample issue track-
i ng application. Now it's time to begi n creating the Flex frontend for our sample
application. We'l l start by incrementally building up the view layer, introducing
you to a few of the pertinent concepts of Flex. This chapter is not meant to be a
comprehensive guide to di e Flex framework by any stretch of the imagination, so
you should be able to fol l ow al ong without much trouble. I f you want a more in-
depth l ook at the Flex framework refer to Flex 4 in Action by Tariq Ahmed, Dan
Orl ando, J ohn C. Bland II, and J oel Hooks (to be published by Manni ng in Sep-
tember 2010).
3.1 Generat i ng t he appl i cat i on st ruct ure
You need to create a Flex application. Because you'l l be using the Flex Moj os
Maven pl ugi n you'l l be creating the application in a manner similar to what you
38
www.it-ebooks.info
Generating the application structure 39
F N A (F N A i s N o t A p p F u se )
F o l k s a t A d o b e C o n s u l t i n g h a v e s t a rt e d a n e w p ro j e c t a t G o o g l e C o d e c a l l e d
F N A , w h i c h s t a n d s f o r F N A i s N o t A p p F u s e (h t t p : / / c o d e . g o o g l e . e o m / p / f n a -v 2 / ).
T h e F N A p ro j e c t h a s s i m i l a r g o a l s t o t h a t o f A p p F u s e i n t h a t t h e y a re a t t e m p t i n g
t o c re a t e a f ra m e w o rk t h a t e n a b l e s d e v e l o p e rs t o j u m p -s t a rt t h e i r R I A a p p l i c a -
t i o n s w i t h F l e x a n d J a v a . W e h a v e d e c i d e d a g a i n s t u s i n g t h i s f ra m e w o rk f o r t h i s
b o o k , b u t f e e l t h e p ro j e c t h a s p o t e n t i a l a n d w a rra n t s a l o o k a t i f y o u a re s t a rt i n g
a n e w p ro j e c t .
used for di e AppFuse por ti on of the appl i cati on. We've taken the l i berty of creat-
i ng a Maven archetype to mi ni mi ze the amount of manual wor k r equi r ed to create
the pr oj ect structure.
Let's get started. Open a command pr ompt and navi gate to di e r oot di rectory of
our appl i cati on. Enter the fol l owi ng command to create our Fl ex appl i cati on.
$ mvn a r c het ype- c r ea t e - D a r c het ypeGr oupI d=or g. f oj \
- D a r c het ypeAr t i f a c t l d=f l ex- moj os- a r c het ype \
- D a r c het ypeVer si on=l . O- SNAPSHOT \
- D gr oupI d=or g. f oj \
- D a r t i f a c t l d=f l ex- bugs- r i a \
- D r emot eReposi t or i es=ht t p: / / f l exonj a va . googl ec ode. c om/ svn/ r eposi t or y
Thi s wi l l create a Fl ex pr oj ect that slightly resembl es a standard Maven proj ect.
Because tiiis is not a J ava proj ect, the pr oj ect structure vari es slightly. The sources for
our Fl ex appl i cati on wi l l go i n the sr e/ mai n/ fl ex fol der, and di e tests i n sre/ test/ fl ex
fol der. Maven wi l l also modi fy our mai n pr oj ect pom. xml and add tiiis pr oj ect as a
modul e as shown here.
Li s t i n g 3 . 1 Pa r e n t p o m . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<pr oj ec t xml ns=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ ma ven- v4_0_0. xsd" >
<modul es>
<modul e>f l ex- bugs- r i a </ modul e>
<modul e>f l ex- bugs- web</ modul e>
</ modul es>
</ pr oj ec t >
Now tiiat the pr oj ect has been created you need to confi gur e di e Fl ex Moj os pl ugi ns
for both the Fl ex pr oj ect and di e AppFuse pr oj ect.
www.it-ebooks.info
63 CHAPTER 3 Getting rich with Flex
Conf i guri ng t he f l ex-bugs-ri a modul e
For this appl i cati on we chose to use the Fl ex Moj os pl ugi n to l everage the power ful
dependency management faci l i ti es of Maven as wel l as to avoi d wri ti ng yet another
Ant bui l d script.
Li st i ng 3 .2 The pom .xm i f or t he Fl ex appl i cat i on
<?xml ver si on=" 1. 0" ?>
<pr oj ec t >
<pa r ent >
<a r t i f a c t l d>f l ex- bugs</ a r t i f a c t l d>
<gr oupI d>or g. f oj </ gr oupI d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
</ pa r ent >
<model Ver si on>4. 0. 0</ model Ver si on>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- r i a </ a r t i f a c t l d>
<pa c ka gi ng>swf </ pa c ka gi ng>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<pr oper t i es>
<f l exmoj os. ver si on>3. 2. 0</ f l exmoj os. ver si on>
</ pr oper t i es>
»
S
Def ine par ent pom
Thi s modul e' s gr oupl d
Thi s modul e' s ar t i f act l d
© Packagi ng t ype
J
L
Thi s modul e' s
ver si on
Fl ex-Moj os
ver si on
<bui l d>
<sour c eD i r ec t or y>sr c / ma i n/ f l ex</ sour c eD i r ec t or y>
<t est Sour c eD i r ec t or y>sr c / t est / f l ex</ t est Sour c eD i r ec t or y>
<f i na l Na me>f l ex- bugs- r i a </ f i na l Na me>
<pl ugi ns>
<pl ugi n>
<gr oupI d>or g. sona t ype. f l exmoj os</ gr oupI d>
<a r t i f a c t l d>f l exmoj os- ma ven- pl ugi n</ a r t i f a c t l d>
<ver si on>${f l exmoj os. ver si on}</ ver si on>
<ext ensi ons>t r ue</ ext ensi ons>
<c onf i gur a t i on>
<t a r get Pl a yer >10. 0. 0</ t a r get Pl a yer >
<l oc a l es>
<l oc a l e>en_US</ l oc a l e>
</ l oc a l es>
</ c onf i gur a t i on>
<dependenc i es>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex</ gr oupI d>
<a r t i f a c t I d>c ompi l er </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
</ dependenc i e s >
</ pl ugi n>
</ pl ugi ns>
</ bui l d>
© Speci f y so
Y and t est s<
I di r ect or i e
' source
t source
di r ect or i es
1>
Fi nal name
f or art i f act
0 Fl ex-m oj os-pl ugi n
www.it-ebooks.info
Configuring the flex-bugs-ria module 4 1
<r eposi t or i es>
<r eposi t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent /
gr oups/ f l exgr oup/ </ ur l >
</ r eposi t or y>
</ r eposi t or i es>
<pl ugi nReposi t or i es>
<pl ugi nRepos i t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent /
gr oups/ f l exgr oup/ </ ur l >
</ pl ugi nRepos i t or y>
</ pl ugi nReposi t or i es>
<dependenc i es>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t l d>f l ex- f r a mewor k</ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t I d>pl a yer gl oba l </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<c l a ssi f i er >10</ c l a ssi f i er >
<t ype>swc </ t ype>
</ dependenc y>
<dependenc y>
<gr oupI d>or g. sona t ype. f l exmoj os</ gr oupI d>
<a r t i f a c t l d>f l exmoj os- uni t t est - suppor t </ a r t i f a c t l d>
<ver si on>${f l exmoj os. ver si on}</ ver si on>
<t ype>swc </ t ype>
<sc ope>t est </ sc ope>
</ dependenc y>
</ dependenc i e s >
</ pr oj ec t >
Li sti ng 3.2 shows the resul ti ng pom. xml for the Fl ex appl i cati on after you gener ate
the pr oj ect usi ng the mvn ar chetype : cr eat e command shown i n secti on 3.1. Because
this is part of a mul ti modul e proj ect, di e pom. xml lists the par ent modul e's POM as
the parent for this pr oj ect ©. Next you'l l see di e values you speci fi ed for di e gr oupl d
© and a r t i f a c t l d © defi ned, as wel l as the packagi ng type © of swf because this
pr oj ect is our Fl ex appl i cati on and wi l l be compi l ed to an SWF fi l e.
NOTE You may need to associate di e SWF fi l e wi th the Standal one Flash
Pl ayer or your bui l d may time out tryi ng to run the F l exUni t tests. Because
F l exUni t requi res the Flash r unti me to run its test suites, Maven wi l l try to
execute the resul ti ng SWF fi l e for your test suite usi ng the defaul t appl i ca-
ti on for SWF files. You can add a fi l e associ ati on i n Wi ndows tiirough the
Wi ndows E xpl or er Fol der Opti ons and on a Mac by usi ng di e fi l e's context
sensitive menu. See the documentati on athttps:/ / docs.sonatype.org/ di spl ay/
FLEXMOJ OS/ Runni ng+uni t+tests for mor e i nfor mati on.
Fl ex Moj os
r eposi t or y at
Sonat ype
Fl ex and uni t
t est i ng
dependenci es
www.it-ebooks.info
65 CHAPTER 3 Getting rich with Flex
Next you set the pr oj ect's ver si on whi ch is set to 1. O- SNAPSHOT. We defi ne
the fi nal name of our arti fact so that the SWF that is gener ated wi l l not have di e
versi on i nfor mati on as part of the fi l ename Q . The archetype also defi nes a com-
mon pr oper ty Q for di e Fl ex Moj os versi on so that you can be sure that the pl ugi n
Q and any dependenci es 0 defi ned for di e Fl ex Moj os are usi ng the same ver-
si on. You'r e also over r i di ng di e versi on for the Fl ex compi l er her e to compi l e it
wi th the Fl ex 4 compi l er and target versi on of Flash Player. Because this is not your
typical Maven proj ect, the pom. xml defi nes the source and test-source di r ector y
l ocati ons Q . I t also defi nes the reposi tory and pl ugi n reposi tory l ocati ons (| j) for
di e Fl ex Moj os pl ugi ns and dependenci es because they don't exist i n di e central
Maven reposi tory.
Conf i gure Maven f or t he f l ex-bugs-web modul e
Now that you've confi gur ed Maven to bui l d the Fl ex appl i cati on, you need to make
mi nor modi fi cati ons to the pom. xml for the f l ex- bu gs- web modul e i n or der to get
di e Fl ex appl i cati on to be copi ed over to di e appr opr i ate pl ace i n the web appl i ca-
tion. To accompl i sh this, you'l l use the maven- dependency- pl ugi n.
Li s t i n g 3.3 Co n f i g u r i n g t h e maven - depen den cy- pl u gi n
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<pr oj ec t xml ns=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ ma ven- v4_0_0. xsd" >
Maven-dependency-pl ugi n A
<bui l d>
<pl ugi ns>
<pl ugi n>
<a r t i f a c t l d>ma ven- dependenc y- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>unpa c k- c onf i g</ i d>
<goa l s> A Unpack -conf i g
<goa l >unpa c k- dependenc i es</ goa l > execut i on
</ goa l s>
<pha se>gener a t e- r esour c es- ; / pha se>
<c onf i gur a t i on>
<out put D i r ec t or y>
${pr oj ec t . bui l d. di r ec t or y}/ ${pr oj ec t . bui l d. f i na l Na me}/ WEB- I NF/ f l ex
</ out put D i r ec t or y>
<i nc l udeGr oupI ds>${pr oj ec t . gr oupI d}</ i nc l udeGr oupI ds>
<i nc l udeCl a ssi f i er s>r esour c es</ i nc l udeCl a ssi f i er s>
<exc l udeTr a nsi t i ve>t r ue</ exc l udeTr a nsi t i ve>
<exc l udeTypes>j a r , swf </ exc l udeTypes>
</ c onf i gur a t i on>
</ exec ut i on> Conf i gur at i on f or unpack -conf i g execut i on
www.it-ebooks.info
Configure Maven for the flex-bugs-web module 4 3
Q Copy-swf
' execut i on
<exec ut i on>
<i d>c opy- swf </ i d>
<pha se>pr oc ess- c l a sses</ pha se>
<goa l s>
<goa l >c opy- dependenc i es</ goa l >
</ goa l s>
<c onf i gur a t i on>
<st r i pVer si on>t r ue</ st r i pVer si on>
<out put Di r ec t or y>
${pr oj ec t . bui l d. di r ec t or y}/ ${pr oj ec t . bui l d. f i na l Na me}
</ out put Di r ec t or y>
<i nc l udeTypes>swf </ i nc l udeTypes>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
Conf i gurat i on f or copy-swf execut i on Q
</ pr oj ec t >
Listing 3.3 shows tlie plugin confi gurati on O needed for your web application to
properl y resolve di e dependency for di e Flex application and ensure tiiat the SWF fi l e
is placed correctly.
First defi ne an execution tiiat you'l l call unpack-conf i g © and tell Maven to exe-
cute tiiis during di e gener ate- r esour ces phase of the build, and call the unpack-
dependenci es goal on tiiis plugin. I n the confi gurati on Q you tell the plugin to limit
the scope of what is affected by tiiis execution to artifacts with the same groupl d as
your proj ect and to artifacts of type resources. This will be utilized in chapter 5 as you
create a common proj ect for all of the confi gurati on files for BlazeDS that need to be
shared between the web application and di e Flex application.
T h e M a ve n b u i ld li fe cycle
M a v e n f o l l o w s t h e c o n v e n t i o n o v e r c o n f i g u ra t i o n p a ra d i g m i n t h e b u i ld l i f e c y c l e
a s p e c t , a n d m a n y o t h e rs . T h e f o l k s w h o d e s i g n e d M a v e n re a li ze d t h a t t h e re a re
m a n y c o m m o n s t e p s i n e v e ry b u i ld a n d d e v e l o p e d t h e c o n c e p t o f t h e b u i ld li f e c y c le
a ro u n d i t. T h e d e fa u lt li f e c y c le f l o w s t h ro u g h t h e f o llo wi n g b u i ld p h a s e s (i n o rd e r):
• v a l i d a t e
• c o m p i l e
• t e s t
• p a c k a g e
• i n t e g ra t i o n -t e s t
• v e ri f y
• i n s t a ll
• d e p lo y
F o r m o re i n fo rm a t i o n o n M a v e n a n d t h e b u i ld li f e c y c le , re a d Maven: The Definitive
Guide, a fre e e b o o k b y E ri c R e d m o n d a va i la b le a t h t t p : / / w w w . s o n a t y p e . c o m / p ro d -
u c t s / m a v e n / d o c u m e n t a t i o n / b o o k -d e f g u i d e .
www.it-ebooks.info
67 CHAPTER 3 Getting rich with Flex
The second executi on that you defi ne Q is copy- swf, and it wi l l do exactl y that. You
confi gur e this executi on to run duri ng the pr oces s - cl as s es phase of di e bui l d l i fecy-
cl e and execute di e copy- dependenci es goal to copy the SWF fi l e f r om the Fl ex proj -
ect i nto the target fol der to be pl aced i n di e pr oper l ocati on befor e Maven creates the
fi nal WAR fi l e ©. Next let's take a l ook at how to create an HTML wrapper, or i n this
case a J SP wr apper for our Fl ex appl i cati on.
Addi ng a wrapper f or our SWF
Adobe provi des numer ous templ ates for creati ng HTML wr apper fi l es for your SWF,
l ocated i n di e / templ ates di rectory of your Fl ex SDK i nstal l ati on. Ther e is everythi ng
f r om the basic no fri l l s wrapper, to wrappers that i ncl ude functi onal i ty to detect
whether the cl i ent has di e correct versi on of the Flash Pl ayer installed, and whether to
support deep l i nki ng and hi story for your appl i cati on.
NOTE Nor mal l y di e HTML wr apper woul d be an HTML fi l e i n your web appl i -
cati on. Because the Si teMesh fi l ter i n AppFuse is confi gur ed to decorate any-
thi ng wi th a .html extensi on, we deci ded the easiest way to ci rcumvent this
fi l ter was to make the wr apper a J SP fi l e.
For this appl i cati on, copy the contents of the cl i ent-si de-detecti on-wi th-hi story fol der
i ncl udi ng di e i ndex.templ ate.html , AC_OETagsj s fi l e, and di e hi story fol der f r om di e
/ templ ates di rectory of your Fl ex SDK i nstal l ati on to the sr c/ mai n/ webapp di rectory
of di e f l ex- bu gs- web proj ect. Rename the i ndex. templ ate. html fi l e fl exbugs.j sp, and
repl ace di e pl acehol ders i n di e fi l e wi th the values shown i n l i sti ng 3.4.
Li s t i n g 3 . 4 HTM L w r a p p e r va l u e s
${t i t l e} - > Fl exBugs
${ver si on_ma j or } - > 9
${ver si on_mi nor } - > 0
${r equi r ed_r evi si on} - > 28
${wi dt h} - > 100%
${hei ght } - > 100%
${a ppl i c a t i on} - > f l ex- bugs- r i a
${bgc ol or } - > #869c a 7
${swf } - > f l ex- bugs- r i a . swf
We aren't goi ng i nto detai l about what is contai ned i n fl exbugs.j sp because it's l i kel y
you won't have to change anythi ng i nsi de of it i n di e future. Lear n mor e about the
HTML templ ates that Fl ex provi des i n di e Li veDocs at Adobe's websi te at http:/ / live-
docs. adobe. com/ fl ex/ 3/ html / wr apper _04. html #l 78239.
"Hel l o Worl d!" i n Fl ex
Now that you have the web appl i cati on confi gur ed to pr oper l y resol ve the Fl ex appl i -
cati on dependency, have pl aced di e resul ti ng SWF fi l e properl y, and have di e HTML
wr apper confi gur ed, l et's wri te a "Hel l o Wor l d!" appl i cati on i n Fl ex to ver i fy that
www.it-ebooks.info
"Hello World!" in Flex 45
everythi ng is wor ki ng as expected. I n di e sr c/ mai n/ fl ex fol der of the f l ex- bugs- r i a
pr oj ect create a Mai n. mxml fi l e for di e Fl ex appl i cati on.
Li s t i n g 3 . 5 He l l o Wo r l d ! i n Fl e x
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=' 950'
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
Fl ex Appl i cat i on
r oot component
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<s: Si mpl eText t ext =" Hel l o Wor l d! " / >
</ s: Appl i c a t i on>
J
J >
J ?
Set t i ng l ayout
Si mpl eText
component
Shown is a mi ni mal "Hel l o Wor l d!" appl i cati on i n Fl ex. I t consists of onl y di e r oot
Appl i c a t i on component Q , a l ayout defi ni ti on © and a si ngl e Si mpl eText compo-
nent G whi ch has its text pr oper ty set to " Hel l o Wor l d! "
M a ve n a n d h e a p sp a c e
Y o u m a y ru n i n t o h e a p s p a c e p ro b l e m s w h e n c o m p i l i n g y o u r F l e x a p p l i c a t i o n w i t h
t h e F l e x M o j o s , a n d y o u r b u i l d m a y fa i l w i t h a m e s s a g e s i m i l a r t o t h e f o l l o w i n g :
[ I NFO]
[ ERROR] FATAL ERROR
[ I NFO]
[ I NFO] J a va hea p spa c e
[ I NFO]
[ I NFO] Tr a c e
j a va . l a ng. Out Of Memor yEr r or : J a va hea p spa c e
T o fi x t h i s i s s u e , y o u n e e d o n l y d e f i n e a n e n v i ro n m e n t v a ri a b l e n a m e d MAVEN_OPTS
a n d s e t i t s v a l u e t o " - Xmx512m" a d j u s t i n g t h e m e m o ry s i z e a s n e e d e d (h t t p s : / /
d o c s , s o n a t y p e . o rg / d i s p l a y / F L E X M O J O S / F A Q ).
To bui l d di e Fl ex appl i cati on you fi rst need to run mvn i nst a l l f r om di e flex-bugs-ria
di rectory. That's it. Thi s wi l l bui l d di e f l ex- bugs- r i a proj ect, and depl oy the result-
i ng arti fact i nto your l ocal Maven reposi tory so tiiat di e f l ex- bugs- web pr oj ect can
i ncl ude it as a dependency i n its pom. xml . After it fi ni shes bui l di ng you can navi gate
to di e i l ex-bugs-web di rectory and run the appl i cati on by typi ng mvn j et t y: r un- wa r
on di e command l i ne. Thi s wi l l start up a J etty i nstance and depl oy your WAR i nsi de
this i nstance so that you can visually ver i fy everyti i i ng is worki ng. When you see the
output shown i n di e fol l owi ng listing, you know tiiat your appl i cati on is runni ng.
www.it-ebooks.info
69 CHAPTER 3 Getting rich with Flex
Li s t i n g 3.6 Co n s o l e o u t p u t f r o m t h e maven - j et t y - p l u gi n
2009- 03- 28 19: 31: 14. 206: : I NFO: St a r t ed Sel ec t Cha nnel Connec t or SO. 0. 0. 0: 8080
[ I NFO] St a r t ed J et t y Ser ver
[ I NFO] St a r t i ng sc a nner a t i nt er va l of 3 sec onds.
Open your favori te browser and navi gate to http:/ / l ocal host:8080/ fl exbugs.j sp and
you shoul d see a screen si mi l ar to fi gur e 3.1.
Thi s sanity check is not terri bl y exci ti ng, but you can see that the appl i cati on is
confi gur ed correctl y. Now that you have the obl i gatory "Hel l o Wor l d!" appl i cati on out
of the way, l et's get on wi th the task of devel opi ng di e real appl i cati on.
Devel opi ng t he Fl exBugs appl i cat i on
To begi n devel opi ng di e appl i cati on, you shoul d have an i dea of what you woul d l i ke
it to l ook l i ke. Fi gure 3.2 shows a mockup.
The appl i cati on is di vi ded i nto three mai n areas i n a modi fi ed master/ detai l vi ew
wi th a second detai l vi ew for any comments on di e sel ected issue. The appl i cati on can
also be di vi ded i nto header, footer, and mai n appl i cati on areas. Defi ni ng the appl i ca-
tion i n these terms achi eves a coupl e of obj ecti ves. By separati ng the appl i cati on i nto
these di ffer ent pi eces, you can create separate mxml fi l es to hel p keep di e code man-
ageabl e. By breaki ng up our appl i cati on i nto separate mxml fi l es, you can reuse parts
of the appl i cati on.
« n o http:/ / lot alhosrSOSO/ flexbugs.jsp
J [ +rthttp:/ / iocairiost:8080/ *iext>ugs.jsp ~c] f t y cc
Hello Wo'd!
Fi gur e 3 .1 Our " Hel l o Wor l d! " appl i cat i on
www.it-ebooks.info
Developing the FlexBugs application 47
H e a d e r S e c ti o n
Fl exBu gs Ap p l i ca t i on
Master View
C o m m e n l s V i e w
F MI W4 ' I .
b*p « - v i r- - t j w
I ]
BH
i . ' .
r
i - ' . v. **' tmw
I PHrtiVlr» [ Orjpn-rtrM j
t ^/ Ti yi ' UKr t Fl u J m
Fi gur e 3 .2 A mock up of t he Fl exBugs appl i cat i on
F o o t e r S e c t i o n
Next we'r e goi ng to decompose di e appl i cati on i nto manageabl e chunks. We'l l start
by i ntr oduci ng some of di e contai ner and navi gati on components we'l l be using to
bui l d di i s appl i cati on starting wi di di e Vi ewSt a c k navi gati on component.
3.6.1 Introducing ViewStack
Vi ewSt a c k is a navi gati on component
di at allows you to stack a col l ecti on of
views and sel ecti vel y display di em.
Unl i ke tradi ti onal web appl i cati ons,
Fl ex appl i cati ons typically don't have
many pages. A Fl ex appl i cati on typi-
cally has one appl i cati on di at will
change its vi ew state dependi ng on
whi ch part of di e appl i cati on is active.
The Vi ewSt a c k is one of di e Fl ex
components di at allows you to do
di i s by br i ngi ng di e active vi ew to di e
for egr ound and hi di ng di e i nacti ve
views i n di e backgr ound as shown i n
fi gur e 3.3.
You can contr ol di e Vi ewSt a c k
i n a number of ways, di e most com-
mon of whi ch is to uti l i ze one of di e Fi gure 3 .3 How t he Vi ewSt ack wor k s
www.it-ebooks.info
71 CHAPTER 3 Getting rich with Flex
navi gati on components such as the Li nkBa r , But t onBa r , or Toggl eBut t onBa r . For
the Fl exBugs appl i cati on we'l l l everage the Toggl eBut t onBa r to faci l i tate swi tchi ng
the vi ew state. I n the top- ri ght cor ner of the fi gur e 3.2 mockup you'l l see buttons
l abel ed Detai l s Vi ew and Gr aph Vi ew; these are the two views that we'l l use of i n
this appl i cati on. We'l l devel op di e details vi ew i n this chapter and di e gr aph vi ew i n
chapter 10 when we talk mor e about gr aphi ng components.
Li s t i n g 3 . 7 De f i n i n g t h e V i e w S t a c k s
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
mi nWi dt h=' 950'
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
<s: l a yout >
<s : Ver t i c a l La yout / > Def i ne vi ew st ack A
</ s: l a yout >
<mx: Vi ewSt a c k i d=" ma i nVi ewSt a c k" wi dt h=" 100%" hei ght =" 100%" > <1—
<mx: Ca nva s i d=" vi ewl " l a bel =" D et a i l s Vi ew" >
<mx: Text t ext =" Put t he det a i l s vi ew st uf f her e. . . " / >
</ mx: Ca nva s>
<mx: Ca nva s i d=" vi ew2" l a bel =" Gr a ph Vi ew" >
<mx: Text t ext =" Put some gr a phs her e. . . " / >
</ mx: Ca nva s>
</ mx: Vi ewSt a c k>
</ s: Appl i c a t i on>
Li sti ng 3.7 shows the Mai n. mxml after you add the Vi ewSt a c k components to the
appl i cati on. After you r emove our Hel l oWor l d code, create a Vi ewSt a c k el ement O
and gi ve it an i d of ma i nVi ewSt a c k; this wi l l become i mpor tant l ater when you defi ne
di e Toggl eBut t onBa r as the da t a Pr ovi der attribute, for the Toggl eBut t onBa r wi l l be
set to this Vi ewSt a c k component. You want this Vi ewSt a c k to use up all avai l abl e hori -
zontal and verti cal space so set its wi dth and hei ght to 100%.
Next add two Ca nva s components Q and Q to the Vi ewSt a c k gi vi ng them ids of
vi ewl and vi ew2 respecti vel y. These two Ca nva s components wi l l be the two mai n
views the Toggl eBut t onBa r wi l l control . The l a bel attri bute of these two components
wi l l be di spl ayed as di e text of the two Toggl eBut t on control s, so you set those to
Detai l s Vi ew and Gr aph Vi ew, respectively. I nsi de these two Ca nva s contai ners put
Text components as pl acehol ders, so you can see how the Toggl eBut t onBa r wi l l con-
trol di e two vi ew states i n the next secti on.
A Add f i r st vi ew
If component
A Add second vi ew
If component
www.it-ebooks.info
Developing the FlexBugs application 49
• a o rg
• U f o j
• • vi e w
3.6.2 HeaderView
Befor e you go much fur ti i er wi ti i bui l di ng up di e appl i -
cati on create the header vi ew so you can contr ol di e vi ew
states di at you j ust created. I n di e src/ mai n/ fl ex fol der cre-
ate di e di rectory structure shown i n fi gur e 3.4 to house di e
vi ew components.
Acti onScr i pt and Fl ex fol l ow a similar packagi ng struc-
ture as J ava so you wi l l l everage tiiat aspect i n or der to keep
the source fi l es or gani zed i n di e same manner you woul d i n a J ava pr oj ect. I nsi de
of di e vi ew fol der create a new fi l e cal l ed Header . mxml , wher e you wi l l put the code
for di e header for di e appl i cati on.
Fi gure 3 .4 Fol der
st r uct ur e f or vi ew
com ponent s
Li s t i n g 3 . 8 He a d e r . m xm l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
wi dt h=" 100%"
hei ght =" 60" >
<s: l a yout >
<s: Hor i zont a l La yout / >
</ s: l a yout >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t mx. c ont a i ner s. Vi ewSt a c k;
publ i c va r vi ewSt a c k: Vi ewSt a c k;
] ] >
</ f x: Sc r i pt >
<mx: Spa c er wi dt h=" 5" / >
<s: Si mpl eText t ext =" Fl exBugs Appl i c a t i on"
hei ght =" 100%"
f ont Si ze=" 32 "
f ont Wei ght =" bol d"
ver t i c a l Al i gn=" mi ddl e" / >
<mx: Spa c er wi dt h=" 100%" / >
<s: VGr oup hei ght =" 100%" >
<mx: Spa c er hei ght =" 100%" / >
<mx: Toggl eBut t onBa r da t a Pr ovi der =" vi ewSt a c k" / >
</ s: VGr oup>
<mx: Spa c er wi dt h=" 5" / >
J
J
Component
ext ends Gr oup
Def ine l ayout

I m por t and decl are
Vi ewSt ack member vari abl e
Text f i el d
f or Ti t l e
</ s : Gr oup>
Toggl eBut t onBar f or
cont r ol l i ng Vi ewSt ack
Spacers
f or l ayout
Li sti ng 3.8 shows the code for di e Header . mxml component. Ther e's not much to it.
The component itself extends the Group component Q , and defi nes its l ayout © as
bei ng Hor i zont al L ayout , meani ng tiiat all the components i nsi de it wi l l be l ai d out
hori zontal l y as opposed to verti cal l y or absolutely. Next you defi ne a publ i c member
vari abl e ©, whi ch wi l l be used to al l ow di e mai n appl i cati on to pass i n the Vi ewStack
www.it-ebooks.info
73 CHAPTER 3 Getting rich with Flex
that the Toggl eBut t onBa r Q wi l l control . To do tiiat you create a Sc r i pt bl ock and
encl ose some Acti onScr i pt i nsi de a CD ATA secti on, so that any characters that may
potenti al l y be parsed as XML are handl ed correctl y.
For the Appl i cati on Ti tl e you have a Si mpl eText component Q wi th a coupl e of
attributes defi ned on it. The fi rst one is di e t ext attri bute, whi ch sets the text to be
di spl ayed i n di e appl i cati on. Fl ex has support for CSS styles si mi l ar to those i n web
appl i cati ons. Fi nal l y there are Spa c er el ements Q , whi ch you use to make sure every-
thi ng is l ai d out properl y. The Spa c er el ements do j ust what you woul d expect; they
take up space and fi l l i n bl ank space so that you can effecti vel y lay out components i n
di e appl i cati on.
Li s t i n g 3 . 9 Ad d i n g t h e h e a d e r t o M a i n . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=' 950'
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<vi ew: Hea der vi ewSt a c k=" {ma i nVi ewSt a c k}" / >
<mx: Vi ewSt a c k i d=" ma i nVi ewSt a c k" wi dt h=" 10
<mx: Ca nva s i d=" vi ewl " l a bel =" D et a i l s Vi ew" >
<mx: Text t ext =" Put t he det a i l s vi ew st uf f her e. . . " / >
</ mx: Ca nva s>
<mx: Ca nva s i d=" vi ew2" l a bel =" Gr a ph Vi ew" >
<mx: Text t ext =" Put some gr a phs her e. . . " / >
</ mx: Ca nva s>
</ mx: Vi ewst a c k>
</ s: Appl i c a t i on>
The pr ecedi ng listing shows di e updated Mai n. mxml fi l e that i ncl udes di e Header,
mxml component you j ust created. First you defi ned a custom namespace for di e
vi ew components by addi ng di e code shown at Q . Next add the custom component
to the Mai n. mxml by usi ng this custom namespace pr efi x and pass i n a r efer ence to
di e Vi ewSt a c k component by usi ng the bi ndi ng expressi on {ma i nVi ewSt a c k} Q.
Now you shoul d be abl e to bui l d and run di e appl i cati on as outl i ned earlier, and be
presented wi th a screen that resembl es fi gur e 3.5.
When you cl i ck the Toggl eBut t ons i n the upper- ri ght corner, you shoul d see the
text i n di e mai n part of the appl i cati on change. Next let's bui l d a si mpl e footer com-
ponent for the appl i cati on.
Added namespace
f or vi ew component s
A Added header
t o appl i cat i on
' %" hei ght =" 100%" >
www.it-ebooks.info
Developing the FlexBugs application 51
^o o flexbugs.jsp
1 I +11 h!tp: / /local host 8080/ftexbugi/flexbugs ,js p* C | (Or Google
Fl exBugs Appl i cat i on
| Data s View J Graph View j
Pui tne retails siuffhare „
s View J Graph View j
Fi gur e 3 .5 The header vi ew added.
3.6.3 FooterView
I nsi de di e same fol der wher e you created the Header . mxml i n di e previ ous secti on,
create another fi l e named Footer. mxml . Though it may seem l i ke overki l l to separate
the footer i nto its own MX ML fi l e, we'l l do it anyway j ust to get you i n di e habi t of sys-
temati cal l y breaki ng your Fl ex appl i cati on i nto smaller, mor e manageabl e pi eces.
Li s t i n g 3 . 1 0 Fo o t e r . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
wi dt h=" 100%"
hei ght =" 40" >
<s: l a yout >
<s: Hor i zont a l La yout / >
</ s: l a yout >
<mx: Spa c er wi dt h=" 100%" / >
<s: Si mpl eText t ext =" Copyr i ght &#0169; 2009 Fl ex On J a va "
hei ght =" 100%"
ver t i c a l Al i gn=" mi ddl e"
t ext Al i gn=" c ent er " / >
<mx: Spa c er wi dt h=" 100%" / >
</ s: Gr oup>
The code i n the pr ecedi ng l i sti ng shows the footer fi l e. Li ke the header, the footer
extends di e Gr oup component. I t contai ns onl y a si ngl e Si mpl eText component,
whi ch contai ns di e copyri ght i nfor mati on, and sets its t ext Al i gn attri bute to c ent er .
Once agai n you l everage a coupl e of Spa c er el ements to assist i n l ayout.
Li s t i n g 3 . 1 1 M a i n . m x m l u p d a t e d w i t h f o o t e r
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
www.it-ebooks.info
52 CHAPTER 3 Getting rich with Flex
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=' 950'
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
</ mx: Vi ewSt a c k>
<vi ew: Foot er / > J ?
Added f oot er
t o Mai n.mxml
</ s: Appl i c a t i on>
Next you add the footer Q to di e appl i cati on much as you di d earl i er for di e header.
Near the end of the Main.mxml, pl ace di e tag for the footer. Next l et's move on to cre-
ati ng the vi ew component for the master view.
3.6.4 Master view
Now you'r e getti ng to the mor e i nteresti ng parts. The master vi ew i f you'l l recal l f r om
fi gur e 3.2 consists of a few components. At the top resi des a data gr i d component wi th
two buttons for addi ng and r emovi ng issues.
Li s t i n g 3 . 1 2 M a s t e r Vi e w . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Pa nel xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
l a yout =" ver t i c a l "
t i t l e=" I ssues"
wi dt h=" 100%"
hei ght =" 100%" > J
Ext endi ng
Panel
<mx: D a t a Gr i d i d=" ma st er Vi ewD a t a Gr i d" wi dt h=" 100%" hei ght =" 100%" >
<mx: c ol umns>
"i d" <mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
"I D" wi dt h=" 70" / >
pr oj ec t "
"Pr oj ec t " wi dt h=" 120" / >
desc r i pt i on"
" D esc r i pt i on" / >
i ssue- t ype"
"Type" wi dt h=" 120" / >
sever i t y"
"Sever i t y" wi dt h=" 7 0" / >
st a t us"
Dat aGri d O
hea der Text =" St a t us" wi dt h=" 100" / >
</ mx: c ol umns>
</ mx: D a t a Gr i d>
<mx: Cont r ol Ba r wi dt h=" 100%" >
<mx: But t on l a bel =" Add New I ssue" / >
J
Cont r ol Bar f or
Add/ Del et e but t ons
www.it-ebooks.info
Developing the FlexBugs application 53
<mx: But t on l a bel =" Remove Sel ec t ed I ssue" / >
</ mx: Cont r ol Ba r >
</ mx: Pa nel >
Create a fi l e i nsi de di e or g/ foj / vi ew fol der cal l ed MasterVi ew.mxml . Thi s wi l l contai n
the code to create di e master view, shown i n l i sti ng 3.12. Thi s component wi l l be
based on the Pa nel component Q , whi ch is one of the l ayout contai ners avai l abl e i n
the Fl ex fr amewor k. The Pa nel component provi des us wi ti i a title bar area wher e we
can pr ovi de di e gr oup of components contai ned wi thi n a meani ngful title much l i ke
the <l egend> tag i n HTML, or a gr oup box control , for those mor e fami l i ar wi ti i desk-
top devel opment.
D a t a Gr i d © is used to display tabular data, and is one of the fundamental con-
trols used i n data-dri ven appl i cati ons. The D a t a Gr i d and its bi g br other Adva nc ed-
D a t a Gr i d l et you edi t rows of data wi ti i i n the table cells. For di e appl i cati on, we'l l
for ego that functi onal i ty i n favor of usi ng a detai l view. A Cont r ol Ba r © at di e
bottom of the Pa nel wi l l contai n di e buttons for addi ng and r emovi ng issues f r om
the appl i cati on.
3.6.5 Detail view
Next we'r e goi ng to devel op di e detai l view, wher e you wi l l al l ow di e users of di e appl i -
cati on to modi fy the data fi el ds for di e issues di spl ayed i n di e master view. D et a i l Vi ew
has a for m contai ni ng di e fi el ds tiiat can be updated for the issues i n di e appl i cati on.
Begi n j ust as you di d earl i er for the master view, by creati ng a fi l e named Detai l -
Vi ew. mxml i n di e or g/ foj / vi ew fol der. The fol l owi ng listing shows the code we'l l be
addi ng to tiiat fi l e.
Li s t i n g 3 . 1 3 De t a i l Vi e w . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Pa nel xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l
l a yout =" ver t i c a l "
t i t l e=" D et a i l s"
wi dt h=" 100%"
hei ght =" 100%" >
<mx: For m i d=" i ssueD et a i l For m" wi dt h=" 100%" >
<mx: For mI t em l a bel =" I D : " wi dt h=" 100%" >
<mx: Text i d=" i ssuel d" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Pr oj ec t : " wi dt h=" 100%" >
<mx: Text l nput i d=" pr oj ec t Na me"
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" D esc r i pt i on : " wi dt h=" 100%" >
<mx: Text l nput i d=" i ssueD esc r i pt i on"
wi dt h=" 100%" / >
</ mx: For mI t em>
k"
J
J
Ext ends Panel
Form cont ai ner
For m l t em
component s
www.it-ebooks.info
5 4 CHAPTER 3 Getting rich with Flex
<mx: For mI t em l a bel =" Type: " wi dt h=" 100%" >
<mx: ComboBox i d=" i ssueType" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Sever i t y: " wi dt h=" 100%" >
<mx: ComboBox i d=" i ssueSever i t y" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" St a t us: " wi dt h=" 100%" >
<mx: ComboBox i d=" i ssueSt a t us" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" D et a i l s: " wi dt h=" 100%" >
<mx: Text Ar ea i d=" i ssueD et a i l s"
wi dt h=" 100%"
hei ght =" 100" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Repor t ed By: " wi dt h=" 100%" >
<mx: Text I nput i d=" i ssueRepor t edBy"
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Repor t ed On: " wi dt h=" 100%" >
<mx: D a t eFi el d i d=" i ssueRepor t edOn"
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Assi gned To: " wi dt h=" 100%" >
<mx: Text l nput i d=" i ssueAssi gnedTo"
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Est i ma t ed Hour s: " wi dt h=" 100%" >
<mx: Text l nput i d=" i ssueEst i ma t edHour s"
wi dt h=" 100%" / >
</ mx: For mI t em>
</ mx: For m>
<mx: Cont r ol Ba r >
<mx: But t on i d=" sa veCha ngesBut t on" l a bel =" Sa ve Cha nges" / >
<mx: But t on i d=" c a nc el Cha ngesBut t on" l a bel =" Ca nc el Cha nges" / >
</ mx: Cont r ol Ba r >
</ mx: Pa nel >
Si mi l ar to tl i e master view, the details vi ew component wi l l be based off of di e Pa ne 1 l ayout
contai ner Q . Add a For m© contai ner to hel p or gani ze di e i nput fi el ds that wi l l be used
to ul ti matel y update di e issues i n the appl i cati on. Unl i ke i n HTML , the For mcontai ner
i n the Fl ex fr amewor k serves no other purpose than to gr oup for m control s on the page.
You do not need to wrap fi el ds i n a For mtag to submi t data to the backend; it's there for
aesthetics. I nsi de di e For mwrap each i nput fi el d i nsi de of a F or ml t em©component that
provi des styling, a l abel , and l ayout for each of the f or m fi el ds. A Cont r ol Ba r © contai ns
di e buttons that contr ol saving the data and cancel i ng di e edits.
3.6.6 Comments view
The fi nal secti on of di e appl i cati on we'l l lay out is the comments vi ew, whi ch wi l l list
any comments added to di e issues. First create the CommentsVi ew. mxml fi l e i n the
or g/ foj / vi ew fol der j ust as you di d for all of di e other vi ew components. For this L i s t
Cont r ol Bar
www.it-ebooks.info
Laying out the components 55
component we'r e goi ng to display di e comment text; you coul d easily create a custom
I temRender er for di e Li st i tems si mi l ar to what we'l l do i n chapter 8 for di e custom
chart that we'l l create.
Li s t i n g 3 . 1 4 Co m m e n t s Vi e w . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Pa nel xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
l a yout =" ver t i c a l "
t i t l e=" Comment s"
wi dt h=" 100%"
hei ght =" 100%" >
<mx: Li st i d=" c omment sLi st "
wi dt h=" 100%"
hei ght =" 100%"
l a bel Fi el d=" c omment Text " >
</ mx: Li st >
<mx: Cont r ol Ba r >
<mx: But t on i d=" a ddBut t on"
l a bel =" Add New Comment " / >
<mx: But t on i d=" edi t But t on"
l a bel =" Edi t Comment " / >
<mx: But t on i d=" del et eBut t on"
l a bel =" D el et e Comment " / >
</ mx: Cont r ol Ba r >
</ mx: Pa nel >
The code for di e comments vi ew is based on di e Pa nel component O - Next add a
Li st component Q , whi ch you'l l use to contai n a list of di e comments. At the bottom
of the Pa nel add a Cont r ol Ba r © to hol d di e three But t on components Q we'l l
defi ne to oper ate on the comments.
Layi ng out t he component s
Now di at you've got all of di e components defi ned, l et's add them to di e Mai n. mxml
and defi ne di e overal l appl i cati on l ayout. I n Fl ex, all components can be l ai d out
wi di i n odi er contai ners general l y i n one of tiiree ways—hori zontal l y, vertically, or
absolutely. I n most cases it's best to go wi ti i ei ti i er hori zontal or verti cal layouts, espe-
cially i f you want your appl i cati on to resi ze appropri atel y. To achi eve the l ayout you
want you'l l need to nest l ayout contai ners as illustrated i n fi gur e 3.6.
Fi gure 3.6 shows di e nesti ng of l ayout contai ners that was necessary to dupl i cate
what was shown i n di e mockup shown i n fi gur e 3.1. Li sti ng 3.15 shows the updated
Mai n. mxml wi th all of di e l ayout components necessary.
J

1>
Ext endi ng Panel
Li st f or comment s
Cont r ol Bar f or but t ons
But t ons f or
oper at i ons on
comment s
www.it-ebooks.info
79 CHAPTER 3 Getting rich with Flex
Canvas
HDi vi dedBox
VDi vi dedBox
Mast erVi ew
Comment s Vi ew
Det ai l Vi ew
Foot er
Fi gur e 3 .6
Layout f or t he appl i cat i on
Li st i ng 3 .1 5 Layi ng out t he appl i cat i on
?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
s: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=' 950'
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<vi ew: Hea der vi ewSt a c k=" {ma i nVi ewSt a c k}" / >
0 Canvas
<mx: Vi ewSt a c k i d=" ma i nVi ewSt a c k" wi dt h=" 100%" hei ght =" 100%" >
<mx: Ca nva s i d=" vi ewl " l a bel =" D et a i l s Vi ew" > <1—
<mx: HD i vi dedBox wi dt h=" 100%" hei ght =" 100%" > © HDi vi dedBox
<mx: VD i vi dedBox wi dt h=" 70%" hei ght =" 100%" > < —© VDi vi dedBox
<vi ew: Ma st er Vi ew i d=" ma st er Vi ew" hei ght =" 60%" / > < —, Mast er Vi ew
<vi ew: Comment sVi ew i d=" c omment sVi ew" hei ght =" 40%"/ ><1— Q com ponent
</ mx: VD i vi dedBox>
<vi ew: D et a i l Vi ew i d=" det a i l sVi ew" wi dt h=" 30%" / >
</ mx: HD i vi dedBox>
</ mx: Ca nva s>
Com m ent sVi ew com ponent © I Det ai l Vi ew
com ponent
www.it-ebooks.info
Creating a pop-up component 57
<mx: Ca nva s i d=" vi ew2" l a bel =" Gr a ph Vi ew" >
<mx: Pa nel t i t l e=" Gr a ph Vi ew" wi dt h=" 100%" hei ght =" 100%" >
<mx: Text t ext =" Put some gr a phs her e. . . " / >
</ mx: Pa nel >
</ mx: Ca nva s>
</ mx: Vi ewSt a c k>
<vi ew: Foot er / >
</ s: Appl i c a t i on>
As illustrated i n fi gure 3.6, you start out wi th a Ca nva s © contai ner to hol d all di e
nested l ayout contai ners for di e mai n Vi ewSt a c k. I nsi de of tiiis you create an
HD i vi dedBox, © setti ng its wi dt h and hei ght to 100%, so it wi l l take up all avai l abl e
space. Wi di i n tiiat you pl ace a VD i vi dedBox ©, whi ch will contai n di e Ma st er Vi ew ©
and di e Comment sVi ew ©. Lasdy you add di e D et a i l Vi ew ©, whi ch wi l l occupy di e
ri ght side of di e HD i vi dedBox. The appl i cati on is al most compl ete. Next l et's create a
component to use as a modal popup to edi t di e comments i n di e Li st vi ew of di e
Comment sVi ew component.
Creat i ng a pop-up component
The fi nal component you'l l devel op i n tiiis chapter is a modal pop- up for m tiiat
you'l l wi re i nto the appl i cati on i n the next chapter to add new comments and edi t
exi sti ng ones.
Fi gure 3.7 is a screenshot of the pop up. Li sti ng 3.16 shows the code for the
pop up.
Add/ Edit Comment
Au in o r:
D a te:
C o m m e n t:
Save Comment \ j Cancel
E
Fi gur e 3 .7 Pop up f or edi t i ng com m ent s
www.it-ebooks.info
81 CHAPTER 3 Getting rich with Flex
Li s t i n g 3 . 1 6 Ed i t Co m m e n t Fo r m . m x m l
<?xml ver si on=" 1. 0" ?>
<mx: Ti t l eWi ndow
xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
t i t l e=" Add/ Edi t Comment "
hei ght =" 400"
wi dt h=" 500" >
<mx: For m wi dt h=" 100%" >
<mx: For mI t em l a bel =" Aut hor : " wi dt h=" 100%" >
<mx: Text l nput i d=" a ut hor "
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" D a t e: " wi dt h=" 100%" >
<mx: D a t eFi el d i d=" c omment D a t e"
wi dt h=" 100%"
f or ma t St r i ng=" MM/ D D / YYYY" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Comment : " wi dt h=" 100%" >
<mx: Text Ar ea i d=" c omment Text "
wi dt h=" 100%"
hei ght =" 200" / >
</ mx: For mI t em>
</ mx: For m>
<mx: Cont r ol Ba r >
<mx: But t on i d=" sa veBut t on" l a bel =" Sa ve Comm
<mx: But t on i d=" c a nc el But t on" l a bel =" Ca nc el "
</ mx: Cont r ol Ba r >
</ mx: Ti t l eWi ndow>
The pop- up wi ndow is fai rl y si mpl e. You defi ne di e component to extend di e
Ti t l eWi ndow component ©, whi ch you'l l typically use for pop ups. Next you add a
For mand a number of For mI terns ©j u s t as you di d earl i er for the D et a i l Vi ew. The
Cont r ol Ba r © added to the wi ndow hol ds di e But t on components for contr ol l i ng di e
pop up.
The f i ni shed appl i cat i on
The fi nal desi gn is far f r om fi ni shed, but we'r e done for now. Thi s is as good a time as
any to bui l d di e appl i cati on and see di e progress you've made. The appl i cati on won't
be functi onal unti l the end of di e next chapter, but it's always reassuring to see what
di e fi ni shed pr oduct wi l l l ook l i ke anyway.
F r om di e r oot of di e f l ex- bugs- r i a pr oj ect run di e command mvn i nst a l l . The
bui l d shoul d compl ete successfully. I f not doubl e- check di e code to ensure tiiat it
matches the code shown i n di e listings. Next, i nsi de the r oot of di e f l ex- bugs- web
pr oj ect run di e mvn j et t y: r un- wa r command to start up di e embedded J etty web con-
tainer and depl oy di e war file. When di e contai ner is up and runni ng, navigate to http:/ /
l ocal host:8080/ fl exbugs.j sp and you shoul d see someti i i ng that resembl es fi gur e 3.8.
© En
< - J Ti.
1>
Ext ends
Ti t l eWi ndow
Add Form
J
Cont r ol Bar
. ent" / >
/ >
www.it-ebooks.info
Summary 59
+ • h!tp:/.i local host:6080,
r
flexbugs /flexbugs jsp# C ] Q, * Go o gl e
Fl exBugs Appl i cat i on
j Refresh List |
| Details \Aew | Graph View
10:
Project
Description:
T>i>e:
Sever i t y-
Status:
Details:
Reported By:
Report«»On:
Assigned To:
Estimated Hours:
«n
H3
[ Aoa Issue J [ Cancel Changes |
Copyright$ 2009 Flex On Java
a
Fi gur e 3 .8 The f i ni shed appl i cat i on
3.10 Summary
Thi s chapter moved qui ckl y and onl y bri efl y i ntr oduced many of di e components
avai l abl e to you i n di e Fl ex fr amewor k. You started wi ti i an i dea of what you wanted
the appl i cati on to l ook l i ke and decomposed tiiat i nto several smal l er components. By
doi ng that you made di e code mor e manageabl e, and as you'l l see i n di e next chapter,
you made the presentati on model s and event handl i ng easier to handl e. When you
had all di e pi eces bui l t up, you coul d illustrate basics of l ayout contai ners i n Fl ex and
put di e appl i cati on together. We'r e hopeful tiiat you wer e abl e to fol l ow al ong; i f you
feel l i ke you need mor e i nfor mati on about layouts and di e components of the Fl ex
fr amewor k, a good pl ace to start woul d be the Li veDocs at http:/ / hel p.adobe.com/
en_US / flex/ using/ index.html.
Now that you've bui l t up the Fl ex appl i cati on and l ai d out di e components, wher e
do you go f r om here? I n di e next chapter you'r e goi ng to begi n connecti ng the Fl ex
appl i cati on to the J ava backend you devel oped i n chapter 2 usi ng the WebSer vi ce
component. I n chapter 5 you'l l r efactor tiiis to use the BlazeDS fr amewor k to talk
di recti y to the J ava appl i cati on.
www.it-ebooks.info
Thi s chapt er covers
• M o d e l V i e w P re s e n t e r
• E v e n t d i s p a t c h i n g a n d h a n d l i n g
• C a l l i n g a w e b s e rv i c e
• I n t e rf a c e s a n d v i e w s
I n chapter 3 you designed di e UI for the Flex application, but it won't be useful
until it can communicate with a server-side component. I n tiiis chapter you're
goi ng to continue building up the client-side application. Many Flex books attempt
to hi de complexity when dealing witii client-side code and ActionScript, usually by
having you create all your WebServi ce components and event handling code in
your MXML files. Thi s solution, as many developers agree, does not scale well and
quickly shows its warts in any but di e most trivial application.
We've deci ded instead to architect di e client-side code in such a manner as
to not only scale well, but also isolate your Vi ew fr om Presentation and fr om
external services. This allows the application to be fl exi bl e enough to easily
refactor and replace one i mpl ementati on of external service with another with
minimal code changes. You could, tiierefore, painlessly change your application
60
www.it-ebooks.info
Model View Presenter 61
fr om cal l i ng web services to l everagi ng BlazeDS as you'l l see i n chapter 5. You'l l do
this by using MVP.
Because a good por ti on of the i nteracti on between the Fl ex fr amewor k and the
server-side occurs as asynchronous calls, we'l l go over events and event handl i ng.
We'l l cover how to uti l i ze events to faci l i tate communi cati on between separate sec-
tions of the appl i cati on. We'l l also l earn how to create the WebSer vi c e component
and call the web services you defi ned i n the appl i cati on i n chapter 2. By the end of
this chapter you shoul d have a functi oni ng appl i cati on that communi cates wi th the
J ava server side.
Model Vi ew Present er
To bui l d the backend for the Fl ex appl i cati on, we'r e goi ng to make use of a popul ar
GUI archi tectural pattern cal l ed Model Vi ew Presenter, and mor e speci fi cal l y a varia-
ti on of that pattern cal l ed Passive Vi ew. As you may have guessed already, the MVP pat-
tern consists of three mai n components: a Model , a Vi ew, and a Presenter, as shown i n
fi gur e 4.1. By l everagi ng the Passive Vi ew archi tecture you are abl e to create what
Mi chael Feathers descri bes as a "Humbl e Di al og Box" (http:/ / www.obj ectmentor.
com/ r esour ces/ ar ti cl es/ TheHumbl eDi al ogBox. pdf). The pri mary reason to fol l ow
this style of devel opment is that you are abl e to r emove as much l ogi c f r om the UI
as possi bl e
Fi gure 4.1 shows the rel ati onshi p among the three components of the MVP pat-
tern. The first el ement of the MVP tri ad is the Presenter. As the di agram shows, all
i nfor mati on fl ows fr om the Presenter to ei ther the Model or Vi ew. The Model and
Vi ew are i sol ated fr om each other and shoul d have no knowl edge of each other or of
the Presenter.
Al l communi cati on wi th the Presenter shoul d be done thr ough events. The Pre-
senter is then responsi bl e for mai ntai ni ng the state of the appl i cati on, maki ng calls to
P re se n te r
Fi gure 4 .1
The rel at i onshi p bet ween t he Model , Vi ew,
and Pr esent er
www.it-ebooks.info
85 CHAPTER 4 Connecting to web services
Wh a t a b o u t d a ta b i n d i n g ?
F o r t h o s e o f y o u w h o a re fa m i li a r w i t h F l e x , y o u 'l l n o t i c e s o o n e r o r la t e r t h a t w e ' v e
d e c i d e d n o t t o u s e t h e b u i lt -i n d a t a b i n d i n g f u n c t i o n a l i t y t h a t F le x p ro v i d e s .
B e c a u s e w e 're f o llo wi n g t h e P a s s i v e Vi e w p a t t e rn fo r t h i s a p p l i c a t i o n , w e 're re lyi n g
o n t h e P re s e n t e r t o p u s h a n y c h a n g e s t o t h e d a t a b e i n g d i s p l a y e d t o t h e v i e w . T h e
m a i n re a s o n i s fo r t e s t a b i l i t y . I t 's m u c h e a s i e r t o u n i t t e s t t h e p re s e n t a t i o n b e h a v-
i o r i f i t i s i n t h e P re s e n t e r t h a n i n t h e V i e w .
the Model and updating the Vi ew when necessary. Read more about the MVP pattern
and the Passive Vi ew pattern at Martin Fowler's bl og at (http:/ / martinfowler.com/
eaaDev/ PassiveScreen.html).
Web servi ces i n Fl ex
I t is fairly common to use web services for application integration, especially when
there are disparate platforms involved. Because of di e availability of XML parsers for
most every common programmi ng language in use today, web services are a pri me
candidate for applications to share i nformati on with each otiier.
There are two maj or styles of web services:
• SOAP-based, which are primarily service-oriented
• RESTful, which are primarily resource-oriented
For this application you'l l use the WebServi ce component to talk to the SOAP-based
web services you created in chapter 1. I n di e exampl e we won't use di e HTTP-
Ser vi ce component to connect to RESTful web services, but it's similar enough to
using the WebServi ce component you should be able to modi fy di e code witiiout
too much effort.
Exposing your business functionality via web services has the least impact on your
server-side code, as it doesn't couple di e application to the clients that will be consum-
i ng the service. As you'l l see in chapter 5, when we expose a service for consumption
using BlazeDS, the remote service is coupl ed only to clients who can communicate
using di e AMF binary protocol that BlazeDS uses.
Web services are commonl y used to integrate applications especially if they run on
di fferent platforms. As it happens, Flex falls into this category because it needs to
communicate witii the server side, which is most likely not written in ActionScript.
Wi th that in mind, di e fi ne folks at Adobe have made integrating a Flex application
with a back end using web services a fairly trivial endeavor. Most Flex books show you
how to call your web services by creating the service components directly in di e MXML
files, but because we're striving for reusability, maintainability, and clean code, we're
goi ng to encapsulate the WebServi ce objects in our model .
www.it-ebooks.info
Dispatching and handling ez>ents 63
4.3 Di spat chi ng and handl i ng event s
Di spatchi ng and handl i ng events is fundamental to Fl ex devel opment, and also to
devel opment usi ng di e Passive Vi ew pattern descri bed previously. Al l i nteracti on wi th
the Presenter is done thr ough di spatchi ng events. I n this secti on we'l l discuss how to
enabl e communi cati on between the parts of the appl i cati on via events.
4.3.1 Creating a custom event
Many components i n Fl ex have thei r own bui l t- i n events, such as the cl i ck event on
a button. I f you want to send any data al ong wi ti i your event, such as whi ch r ow i n a
DataGr i d was sel ected, you'l l need to create your own custom event class tiiat extends
the f l as h , event s . Event class.
NOTE Li ke J ava, Acti onScr i pt uses packages to l ogi cal l y gr oup rel ated classes
and avoi d nami ng confl i cts. T o decl are that a class bel ongs to a parti cul ar
package, use the package keyword, fol l owed by di e package name wi th a set
of braces contai ni ng di e code bel ongi ng to that package. Then pl ace di e class
fi l e i n a fol der structure cor r espondi ng to the package name you defi ned. I f
your package name is com. exampl e, di e class must be l ocated i n a com/ exam-
pl e fol der of your source tree.
To di ffer enti ate between events, you can ei ther create a separate subclass for each
event tiiat you wish to react to, or create fewer events and use the type attri bute to fil-
ter out onl y di e events you want to add event listeners for.
Li s t i n g 4 . 1 Ul Ev e n t . a s
pa c ka ge or g. f oj . event {
i mpor t f l a sh. event s. Event ;
publ i c c l a ss UI Event ext ends Event { <•
publ i c st a t i c va r SELECTED _I SSUE_CHANGED : St r i ng =
" sel ec t edl ssueCha nged" ;
publ i c st a t i c va r REFRESH_I SSUES_BUTTON_CLI CKED : St r i ng
" r ef r eshBut t onCl i c ked" ;
publ i c st a t i c va r REMOVE_I SSUE_BUTTON_CLI CKED : St r i ng =
" r emoveBut t onCl i c ked" ;
publ i c st a t i c va r SAVE_I SSUE_BUTTON_CLI CKED : St r i ng =
" sa veI ssue" ;
publ i c st a t i c va r SELECTED _I SSUE_SAVED : St r i ng =
" sel ec t edl ssueSa ved" ;
publ i c st a t i c va r CANCELLED _I SSUE_ED I T: St r i ng =
" c a nc el l edl ssueEdi t " ;
publ i c st a t i c va r SELECTED _COMMENT_CHANGED : St r i ng =
" sel ec t edComment Cha nged" ;
publ i c st a t i c va r AD D _NEW_COMMENT_BUTTON_PRESSED : St r i ng =
" a ddNewComment " ;
S
Ext endi ng
Event
Const ant s f or
event t ype
www.it-ebooks.info
64 CHAPTER 4 Connecting to web services
publ i c st a t i c va r ED I T_COMMENT_BUTTON_PRESSED : St r i ng =
" edi t Comment " ;
publ i c st a t i c va r D ELETE_COMMENT_BUTTON_PRESSED : St r i ng =
" del et eComment " ;
publ i c st a t i c va r SAVE_COMMENT_BUTTON_PRESSED : St r i ng =
" sa veComment " ;
publ i c st a t i c va r CANCEL_ED I T_COMMENT_BUTTON_PRESSED : St r i ng =
" c a nc el Edi t Comment " ;
publ i c st a t i c va r COMMENTS_UPD ATED : St r i ng =
" c omment sUpda t ed" ;
publ i c va r da t a : *;
publ i c f unc t i on UI Event ( t ype : St r i ng,
bubbl es : Bool ea n = t r ue,
c a nc el a bl e : Bool ea n = f a l se)
J
{
Const ant s f or
event t ype
Vari abl e f or
1
Vari abl e f
sendi ng
i nf or m at i on
wi t h event
super ( t ype, bubbl es, c a nc el a bl e) ;
Q Const r uct or
I n listing 4.1 you've created a custom event class cal l ed UI Event O
a n
d defi ned con-
stants for di e di ffer ent types of events that wi l l be di spatched ©. Ther e's also a
defi ned fi el d cal l ed da t a © tiiat wi l l accept any type of vari abl e. Thi s wi l l hol d any
ki nd of payl oad you pass wi ti i di e event. As a last step over l oad di e constructor Q and
speci fy defaul t values for wheti i er or not di e events shoul d bubbl e up the chai n and
be cancel abl e. Next you'l l l ook at how to di spatch tiiese events.
4.3.2 Event dispatching
For the appl i cati on to react to events, you fi rst have to di spatch di em. Because every
component i n Fl ex is an ancestor of Ul Component , you have di e ability to di spatch
an event by si mpl y cal l i ng di e di spa t c hEvent method wi ti i i n your MXML ; event bub-
bl i ng onl y travels upward toward a component's parent. For the appl i cati on to wor k
as you expect, you need a mechani sm to al l ow si bl i ng components to i ntercept events
bei ng di spatched to noti fy you of a button bei ng cl i cked, or di e sel ected i tem i n a
D a t a Gr i d bei ng changed. To accompl i sh this you wi l l create an Event D i spa t c her -
Fa c t or y so tiiat all event di spatchi ng and subscri bi ng happens wi th di e same Event -
D i spa t c her obj ect.
Li s t i n g 4 . 2 Ev e n t Di s p a t c h e r Fa c t o r y . a s
pa c ka ge or g. f oj . event {
i mpor t f l a sh. event s. Event D i spa t c her ;
publ i c c l a ss Event D i spa t c her Fa c t or y{ O Si ngl et on i nst ance
pr i va t e st a t i c va r „i nst a nc e: Event D i spa t c her ; <1—* of Event Di spat cher
www.it-ebooks.info
Creating Issue and Comment transfer objects 65
publ i c st a t i c f unc t i on get Event D i spa t c her ( ) : Event D i spa t c her {
i f ( _i nst a nc e == nul l ) {
. i nst a nc e = new Event D i spa t c her () ; Fact or y met hod
} get Event Di spat cher
r et ur n . i nst a nc e;
}
1er O
Li sti ng 4.2 shows the code for the Event D i spa t c her Fa c t or y. Ther e's not much to it. I t
consists of a factory meti i od get Event D i spa t c her Q , whi ch returns a si ngl eton
i nstance of an Event D i spa t c her You'l l use tiiis i nstance of Event D i spa t c her to
di spatch and subscribe to events. That way any part of di e appl i cati on can di spatch
and react to events regardl ess of wher e it exists i n di e appl i cati on's hi erarchy of com-
ponents and classes. Now that you have di e custom events and a way to di spatch di em,
l et's move on to enhanci ng di e appl i cati on to make it mor e i nteracti ve and useful .
Creat i ng Issue and Comment t ransf er obj ect s
To ease handl i ng di e responses f r om cal l i ng web services, you need to dupl i cate di e
data obj ects defi ned i n chapter 1 i n Acti onScr i pt so that you can effecti vel y deal wi ti i
the data on di e cl i ent side.
Li s t i n g 4 . 3 I s s u e . a s
pa c ka ge or g. f oj . dt o {
publ i c c l a ss I ssue {
publ i c va r i d: i nt ;
publ i c va r pr oj ec t : St r i ng;
publ i c va r desc r i pt i on: St r i ng;
publ i c va r t ype: St r i ng;
publ i c va r sever i t y: St r i ng;
publ i c va r st a t us : St r i ng;
publ i c va r det a i l s : St r i ng;
publ i c va r r epor t edBy: St r i ng;
publ i c va r r epor t edOn: D a t e ;
publ i c va r a ssi gnedTo: St r i ng;
publ i c va r est i ma t edHour s: Number ;
publ i c f unc t i on I ssue( i ssue : * = nul l ) {
i f ( i ssue != nul l ) {
t hi s. i d = i ssue. i d;
t hi s. pr oj ec t = i ssue. pr oj ec t ;
t hi s. desc r i pt i on = i ssue. desc r i pt i on;
t hi s. t ype = i ssue. t ype;
t hi s. sever i t y = i ssue. sever i t y;
t hi s. st a t us = i ssue. st a t us ;
t hi s. r epor t edBy = i ssue. r epor t edBy;
t hi s. r epor t edOn = i ssue. r epor t edOn;
t hi s. a ssi gnedTo = i ssue. a ssi gnedTo;
Publ i c member
vari abl es
Conveni ence
const r uct or
www.it-ebooks.info
89 CHAPTER 4 Connecting to web services
t hi s. est i ma t edHour s = i ssue. est i ma t edHour s;
t hi s. det a i l s = i ssue. det a i l s;
}
Li sti ng 4.3 shows the I ssue data obj ect. Ther e's not much to it. I t contai ns several
publ i c member vari abl es Q , whi ch match the pr oper ti es i n its J ava counterpart. Then
you defi ne a conveni ence constructor Q for constructi ng an I ssue because the Web-
Ser vi c e wi l l not return actual I ssue obj ects, but rather construct an Obj ec t Pr oxy,
whi ch is an anonymous dynami c obj ect that contai ns the same properti es as the I ssue
obj ect. You defi ne a constructor that allows you to create an I ssue obj ect f r om tiiis
Obj ec t Pr oxy.
Li s t i n g 4 . 4 Co m m e n t . a s
pa c ka ge or g. f oj . dt o {
publ i c c l a ss Comment {
publ i c va r i d: i nt ;
publ i c va r i ssue: I ssue;
publ i c va r a ut hor : St r i ng;
publ i c va r c r ea t edD a t e: D a t e;
publ i c va r c omment Text : St r i ng;
publ i c f unc t i on Comment ( c omment : * = nul l ) {
i f ( c omment != nul l ) {
t hi s. i d = c omment . i d;
t hi s. a ut hor = c omment . a ut hor ;
t hi s. c r ea t edD a t e = c omment . c r ea t edD a t e;
t hi s. c omment Text = c omment . c omment Text ;
t hi s. i ssue = new I ssue( c omment . i ssue) ;
}
Li sti ng 4.4 shows the Comment data obj ect, whi ch l ooks si mi l ar to di e I ssue data
obj ect. I t contai ns a few member vari abl es O and a conveni ence constructor ©.
Next l et's get down to di e task of enhanci ng di e UI by appl yi ng di e MVP pattern to
di e appl i cati on.
Enhanci ng t he mast er vi ew
The fi rst part of the appl i cati on that you'l l be enhanci ng is the master vi ew. You'l l
start by creati ng the Presenter for the master view. Then you'l l create the Issues
model , whi ch wi l l encapsul ate di e i nteracti on wi ti i the web services you created i n
chapter 1. When you'r e done, update di e vi ew to di spatch the necessary events to
functi on properl y.
Publ i c member
vari abl es
Conveni ence
const r uct or
www.it-ebooks.info
Enhancing the comments view 67
4.5.1 Creating a Presenter for the master view
Because the Presenter is responsi bl e for most of what goes on i n the appl i cati on, it wi l l
be the first part of the MVP tri ad that you'l l be creati ng. The Presenter for the master
vi ew part of the appl i cati on needs onl y a coupl e of di ffer ent events to react to.
Because the appl i cati on is stateful by nature, you need to refresh di e list of I ssues
whenever any of the issues are changed, tiiat is, an issue is created or r emoved, when-
ever an i ndi vi dual issue is updated, or when di e user clicks the Refr esh Issues button.
The Presenter also needs to react when di e user clicks di e Remove Issue button. The
fol l owi ng l i sti ng shows the code for the Ma st er Pr esent er class.
Li s t i n g 4 . 5 M a s t e r Pr e s e n t e r . a s
pa c ka ge or g. f oj . pr esent er {
publ i c c l a ss Ma st er Pr esent er { __
Vi ew
pr i va t e va r _vi ew: Ma st er Vi ewComponent ; <- l O Model
pr i va t e va r _i ssueModel : Soa pI ssueModel ;
J
publ i c f unc t i on Ma st er Pr esent er ( vi ew: Ma st er Vi ewComponent = nul l ) {
t hi s. _i ssueModel = new Soa pI ssueModel ( ) ;
t hi s . _vi ew = vi ew; Const r uct or
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . REFRE SH_I S SUE S_BUTTON_C LI CKED , <
get l ssues) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SELECTED _I SSUE_SAVED , <1
get l ssues) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . CANCELLED _I SSUE_ED I T, <1
get l ssues) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . REMOVE_I SSUE_BUTTON_CLI CKED , <1
r emoveI ssue) ;
i Subscri bi ng t o event s
Get t i ng
pr i va t e f unc t i on get l ssues( event : UI Event = nul l ) : voi d {
Cur sor Ma na ger . set BusyCur sor () ; A t he i ssues
_i ssueModel . get l ssues( new Async Responder ( get l ssuesResul t ,
ha ndl eEr r or ) ) ;
}
pr i va t e f unc t i on r emovel ssue( event : UI Event ) : voi d {
Cur sor Ma na ger . set BusyCur sor ( ) ;
va r sel ec t edl ssue: I ssue = event . da t a ;
_i ssueModel . r emovel ssue( sel ec t edl ssue. i d,
new Async Responder ( r emovel ssueResul t , ha ndl eEr r or ) ) ;
}
pr i va t e f unc t i on get l ssuesResul t ( event : Resul t Event ,
t oken: Async Token = nul l ) : vo
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
1>
Removi ng
an i ssue
Respondi ng t o A
get l ssues r esul t I
i i d { <1—1
www.it-ebooks.info
91 CHAPTER 4 Connecting to web services
va r i ssues = new Ar r a yCol l ec t i on( ) ;
f or ea c h( va r i t em: Obj ec t i n event . r esul t ) {
va r i ssue: I ssue = new I ssue( i t em) ;
i ssues. a ddl t em( i ssue) ;
}
_vi ew. ma st er Vi ewD a t a Gr i d. da t a Pr ovi der = i ssues;
pr i va t e f unc t i on r emovel ssueResul t ( event : Resul t Event ,
t oken: Async Token = nul "'
new UI Event ( UI Event . SELECTED _I SSUE_CHANGED ) ;
i t emCha ngedEvent . da t a = new I s s ued;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( i t emCha ngedEvent ) ;
get l ssues( ) ;
The Ma st er Pr esent er contai ns r efer ences to the other two pi eces of the MVP triad,
di e vi ew O and di e model ©. The constructor © takes as an ar gument its vi ew.
These acti ons are necessary because you'l l be constructi ng the Presenters i n the vi ew
components as they're created. The vi ew wi l l tiien pass i n a r efer ence to itself when
creati ng the Presenter. You then create an i nstance of the Model you'l l be cal l i ng and
regi ster a few event listeners for di e events tiiat the Presenter needs to react to Q .
Meti i ods are cal l ed as a result of di e events bei ng fi r ed by the Vi ew. The fi rst
method get l ssues Q is cal l ed to react to events that r equi r e di e appl i cati on to
r efr esh the D a t a Gr i d. I t fi rst calls the Cur s or Ma na ger to change the mouse cursor
to the busy cursor. Then it calls the Model 's get l ssues meti i od, passing i n an Async -
Responder , whi ch is a way to pr ovi de cal l back meti i ods to the Model to call when a
result is returned.
When a Resul t Event is fi r ed by di e Model , it calls the get l ssuesResul t O call-
back meti i od, whi ch changes di e mouse cursor back to di e nor mal cursor and
updates the D a t a Gr i d by setti ng its da t a Pr ovi der pr oper ty to the col l ecti on of
I ssues r etur ned f r om the Model . As stated earlier, di e web servi ce returns a col l ec-
tion of Obj ec t Pr oxy obj ects you need to i terate tiirough to create actual I ssue
obj ects for the view.
Ther e are also meti i ods to handl e when di e user clicks on di e Remove Issue but-
ton © and its cal l back for a successful return A si mpl e and gener i c er r or han-
dl i ng functi on © returns the cursor to the nor mal state, and pops up an Al er t box
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
_vi ew. ma st er Vi ewD a t a Gr i d. sel ec t edl ndex = - 1;
va r i t emCha ngedEvent : UI Event =
pr i va t e f unc t i on ha ndl eEr r or ( event : Fa ul t Event ,
t oken: Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
Al er t . show( event . messa ge. t oSt r i ng( ) ) ;
www.it-ebooks.info
Enhancing the master view 69
We b S e rvi c e s, A syn c T o k e n , a n d I R e sp o n d e r
I n F l e x , c a l l s t o re m o t e s e rv i c e s h a p p e n a s y n c h ro n o u s l y , a n d re t u rn a n Async -
Token o b j e c t t h a t y o u c a n u s e t o a d d c a l l b a c k s t o b e e x e c u t e d w h e n e i t h e r a
Resul t Event o r Fa ul t Event re t u rn s a s a re s u l t o f t h e re m o t e s e rv i c e c a l l . O n e
w a y t o b i n d t h e s e e v e n t h a n d l e rs t o a n Async Token i s t o a d d a n o b j e c t t h a t c o n -
f o rm s t o t h e i Responder i n t e rf a c e , s u c h a s a n Async Responder , w h i c h t a k e s i n a
c a l l b a c k t o c a l l o n a Resul t Event a n d o n e t o c a l l i f i t re t u rn s a Fa ul t Event
i n s t e a d i n i t s c o n s t ru c t o r.
contai ni ng the er r or message r etur ned f r om di e r emote call. Obvi ousl y you'l l want to
repl ace tiiis simplistic er r or handl i ng when devel opi ng real appl i cati ons, but for the
si mpl e exampl e, tiiis wi l l suffi ce. Now l et's create the Model component.
4.5.2 Creating an Issue Model
The next component i n di e MVP triad that you'l l i mpl ement is di e Model . The Model
i n MVP, someti mes r efer r ed to as di e Domai n Model , represents di e cor e of the busi-
ness domai n and is often responsi bl e for mani pul ati ng data i n a rel ati onal database,
or i n tiiis case cal l i ng an external servi ce that wi l l handl e persi sti ng the data.
Li s t i n g 4 . 6 I s s u e M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . I Responder ;
i mpor t mx. r pc . soa p. WebSer vi c e;
i mpor t or g. f oj . dt o. I ssue;
publ i c c l a ss I ssueModel {
pr i va t e va r _i ssueSer vi c e: WebSer vi c e;
J
Creat e new
WebSer vi ce
publ i c f unc t i on I ssueModel ( ) {
_i ssueSer vi c e = new WebSer vi c e( ) ;
_i ssueSer vi c e. wsdl =
" ht t p: / / l oc a l host : 8080/ ser vi c es/ I ssueSer vi c e?wsdl
i f ( _i ssueSer vi c e. c a nLoa dWSD L( ) ) {
_i ssueSer vi c e. l oa dWSD L( ) ;
}
publ i c f unc t i on get l ssues( r esponder : I Responder ) : voi d {
va r t oken: Async Token = _i ssueSer vi c e. get Al l ( ) ;
t oken. a ddResponder ( r esponder ) ;
}
J
" i
Set i t s wsdl
pr oper t y
Load t he wsdl
1>
get l ssues
publ i c f unc t i on r emovel ssue( i d: Number , r esponder : I Responder ) : voi d {
va r t oken: Async Token = _i ssueSer vi c e. r emove( i d) ;
t oken. a ddResponder ( r esponder ) ;
}
removel ssues
n
www.it-ebooks.info
70 CHAPTER 4 Connecting to web services
Listing 4.6 shows the code for di e I ssueModel so far. I n the constructor, you create a
WebSer vi c e obj ect © and set its wsdl property to http:/ / localhost:8080/ services/
IssueServicePwsdl
U si n g We b S e rvi c e d e sti n a ti o n s
I f y o u p re fe r n o t t o h a rd c o d e t h e WebSer vi c e U R L i n s i d e y o u r M o d e l c l a s s e s , y o u
c a n s e t u p t h e WebSer vi c e d e s t i n a t i o n m e t a d a t a i n t h e s e rv i c e s -c o n f i g . x m l c o n f i g -
u ra t i o n fi le . U s i n g t h i s a p p ro a c h e n a b l e s y o u t o re fe r t o t h e WebSer vi c e b y i t s
dest i na t i onl D i n o rd e r t o lo a d t h e WS D L ra t h e r t h a n u s i n g a U R L t o t h e WS D L .
T o u s e t h i s a p p ro a c h y o u 'l l n e e d t o re p la c e t h e s e c t i o n s o f c o d e w h e re y o u s e t t h e
wsdl p ro p e rt y o n y o u r WebSer vi c e o b j e c t s li k e _i ssueSer vi c e. wsdl w i t h c o d e
t h a t s e t s t h e dest i na t i on p ro p e rt y t o t h e d e s t i n a t i o n n a m e y o u c o n f i g u re d i n t h e
ser vi c es- c onf i g. xml . B y l e v e ra g i n g M a v e n p ro fi le s a lo n g w i t h i t s re s o u rc e fi lte r-
i n g y o u c a n p u t p ro p e rt y p l a c e h o l d e rs i n y o u r ser vi c es- c onf i g. xml a n d d e fi n e d i f-
f e re n t d e s t i n a t i o n s fo r y o u r w e b s e rv i c e s i n t h e M a v e n p ro fi le s fo r t h e d i ffe re n t
e n v i ro n m e n t s . F o r m o re i n fo rm a t i o n o n u s i n g M a v e n p ro fi le s a n d re s o u rc e f i lt e ri n g ,
re fe r t o t h e M a v e n re f e re n c e a t h t t p : / / w w w . s o n a t y p e . c o m / b o o k s / m v n re f -b o o k /
re f e re n c e / p u b l i c -b o o k . h t m l . We 'l l c o v e r w o rk i n g w i t h d e s t i n a t i o n s i n c h a p t e r 5
w h e n d i s c u s s i n g B l a ze D S re m o t i n g .
Next you need to call the l oa dWSD L method Q on di e WebSer vi c e so tiiat di e Web-
Ser vi c e will downl oad di e WSD L and be able to make calls against di e web service.
This is a necessary step when defi ni ng your WebSer vi c e in ActionScript as opposed to
using di e WebSer vi c e MXML tag. As di e final steps, you defi ne di e two business metii-
ods get l ssues © and r emovel ssue ©. which call di e web service and add di e
responder callback you passed in fr om the Presenter as a responder to the Async -
Token. Let's wrap up tiiis MVP triad by refactori ng di e Ma st er Vi ew.
4.5.3 Updating the master view
Now tiiat we've got the Presenter and Model in place, let's update di e Ma st er Vi ew to
add functionality.
Li st i ng 4 . 7 Ma st e r Vi e w. m xm l
<?xml ver si on="1. 0" enc odi ng="ut f - 8"?>
<mx: Pa nel xml ns: f x="ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s="l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx="l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
l a yout ="ver t i c a l "
t i t l e="I ssues"
wi dt h="100%"
hei ght ="100%" f l
c r ea t i onCompl et e=" i ni t () " > <1—I
<f x: Sc r i pt >
<! [ CDATA[
creat ionComplet e
event
www.it-ebooks.info
Enhancing the comments view 71
i mpor t mx. event s. Li st Event ;
i mpor t or g. f oj . dt o. I ssue;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
i mpor t or g. f oj . pr esent er . Ma st er Pr esent er ;
pr i va t e va r pr esent er : Ma st er Pr esent er ;
pr i va t e f unc t i on i ni t ( ) : voi d {
pr esent er = new Ma st er Pr esent er ( t hi s) ;
r ef r eshLi st ( ) ;
}
{
J
J
Boot st r appi ng
Pr esent er
r ef r eshLi st
pr i va t e f unc t i on r ef r eshLi st ( ) : voi d
va r r ef r eshEvent : UI Event =
new UI Event ( UI Event . REFRESH_I SSUES_BUTTON_CLI CKED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( r ef r eshEvent ) ;
} sel ect edl t em Changed Q
pr i va t e f unc t i on sel ec t edl t emCha nged( event : Li st Event ) : voi d {
va r i t emCha ngedEvent : UI Event =
new UI Event ( UI Event . SELECTED _I SSUE_CHANGED ) ;
i t emCha ngedEvent . da t a = ma st er Vi ewD a t a Gr i d. sel ec t edl t em a s I ssue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( i t emCha ngedEvent ) ;
pr i va t e f unc t i on r emoveSel ec t edl ssue( ) : voi d {
va r sel ec t edl ssue: I ssue =
ma st er Vi ewD a t a Gr i d. sel ec t edl t em a s I ssue;
va r r emoveEvent : UI Event =
new UI Event ( UI Event . REMOVE_I SSUE_BUTTON_CLI CKED ) ;
r emoveEvent . da t a = sel ec t edl ssue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( r emoveEvent ) ;
}
] ]>
</ f x: Sc r i pt >
<mx: D a t a Gr i d i d=" ma st er Vi ewD a t a Gr i d"
wi dt h=" 100%"
hei ght =" 100%"
i t emCl i c k=" sel ec t edl t emCha nged( event ) ;
<mx: c ol umns>
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
hea der Text
<mx: D a t a Gr i dCol umn da t a Fi el d=
rem oveSel ect edl ssue
J
dat agr i d
i t em Cl i ck event
"i d"
=" I D" wi dt h=" 50" / >
" pr oj ec t "
=" Pr oj ec t " wi dt h=" 120" / >
" desc r i pt i on" wi dt h=" 200"
=" D esc r i pt i on" / >
"t ype"
=" Type" wi dt h=" 120" / >
" sever i t y"
=" Sever i t y" wi dt h=" 70" / >
" st a t us"
hea der Text =" St a t us" wi dt h=" 100" / >
Dat aGr i dCol um n
bi ndi ngs
www.it-ebooks.info
72 CHAPTER 4 Connecting to web services
</ mx: c ol umns>
</ mx: D a t a Gr i d>
<mx: Cont r ol Ba r wi dt h=
11
100%
11
> © Ref resh Li st
<mx: But t on l a bel =" Ref r esh Li st " c l i c k=" r ef r eshLi st () "/ > <—I d i ck event
<mx: But t on l a bel =" Remove Sel ec t ed I ssue"
c l i c k=" r emoveSel ec t edl ssue( ) "
ena bl ed=" {ma st er Vi ewD a t a Gr i d. sel ec t edl t em != nul l }" / >
</ mx: Cont r ol Ba r >
, 1
: ©
Remove Sel ect ed
</ mx: Pa nel > Issue cl i ck event
Li sti ng 4.7 shows the updated MasterVi ew.mxml . The first change is the addi ti on of
a handl er for the c r ea t i onCompl et e event of di e component Q . You use tiiis event
to hel p bootstrap the Presenter © and make a call to di e r ef r eshLi st © meti i od to
popul ate the D a t a Gr i d automati cal l y on startup. The r ef r eshLi st met hod is used
to r espond to the cl i ck event on the Refr esh Li st button as wel l ©. Next you defi ne
an event handl er meti i od cal l ed sel ec t edl t emCha nged ©• whi ch responds to any
clicks wi thi n di e D a t a Gr i d ©.
You also defi ne an event handl er method cal l ed r emoveSel ec t edl ssue © to
r espond to any clicks of di e Remove Sel ected Issue button ©. To ensure tiiat this but-
ton is enabl ed onl y when we have an actively sel ected r ow i n the D a t a Gr i d, we've
bound the enabl ed pr oper ty of di e button to the sel ec t edl t em pr oper ty of di e
D a t a Gr i d. We've bound di e D a t a Gr i dCol umn i tems © i n di e D a t a Gr i d to di e pr oper -
ties defi ned on di e I ssue data obj ect earlier. Thi s wi l l al l ow di e D a t a Gr i d to bi nd the
col umn values to di e obj ects i n its data provi der.
4.6 Enhanci ng t he det ai l vi ew
The next MVP tri ad you'l l create is for di e detai l view. J ust as you di d i n di e previ ous
secti on, you'l l begi n by creati ng the Presenter, tiien add the necessary meti i ods to the
I ssueModel , and fi ni sh by enhanci ng di e Vi ew.
4.6.1 Creating a DetailPresenter
The D et a i l Pr esent er must mai ntai n mor e state tiian the Ma st er Pr esent er . Because
the code necessary for the D et a i l Pr esent er is mor e compl ex, we'l l break it up i nto
smal l er chunks, starting wi th listing 4.8.
Li s t i n g 4 . 8 De t a i l Pr e s e n t e r . a s
pa c ka ge or g. f oj . pr esent er {
publ i c c l a ss D et a i l Pr esent er { __
Sel ect ed issue
J pr i va t e va r _i ssue: I ssue; <]—I B Vi ew
pr i va t e va r _vi ew: D et a i l Vi ew; <1—I B Model
pr i va t e va r _i ssueModel : I ssueModel ; <1—I
publ i c f unc t i on D et a i l Pr esent er ( vi ew: D et a i l Vi ew) {
www.it-ebooks.info
Enhancing the detail view 73
t hi s. _i ssueModel = new Soa pI ssueModel ( ) ;
t hi s. _vi ew = vi ew;
t hi s. _i ssue = new I s s ued;
vi ew. i ssueTypes = new Ar r a yCol l ec t i on(
[ "Bug", " Fea t ur e Request " , " Enha nc ement " ]
) ;
vi ew. sever i t yTypes = new Ar r a yCol l ec t i on!
[ "Mi nor ", " Ma j or " , " Sever e" ]
) ;
vi ew. st a t usTypes = new Ar r a yCol l ec t i on!
[ "Open", "I n Pr ogr ess" , "On Hol d" , " Fi ni shed" ]
) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SELECTED _I SSUE_CHANGED ,
c ha ngedl ssue) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SAVE_I SSUE_BUTTON_CLI CKED ,
sa vel ssue) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . CANCELLED _I SSUE_ED I T,
c a nc el Cha nges) ;
6
Ini t i al i ze
component s
Popul at e
combo boxes
A Add event
l i st eners
The D et a i l Pr esent er not onl y hol ds r efer ences to di e Vi ew Q and Model Q , it also
needs to hol d a r efer ence to di e currendy sel ected issue O f r om di e D a t a Gr i d i n di e
Ma st er Vi ew. I n di e constructor you i ni ti al i ze the Model , set the Vi ew to what is bei ng
passed in, and create an empty I ssue obj ect Q . Next di e Presenter sets di e possi bl e
values i n di e combo boxes for di e issue types, severity, and status Q by creati ng Ar r a y-
Col l ec t i ons wi th the possi bl e values and setti ng the da t a Pr ovi der pr oper ty of the cor-
r espondi ng ComboBox. Then you add event listeners Q to r espond to di e events tiiat
the D et a i l Vi ew wi l l fi re, as wel l as the changed issue event that di e Ma st er Vi ew fi res
when di e sel ected i tem i n the D a t a Gr i d changes. The fol l owi ng listing shows di e rest of
the code for di e D et a i l Pr esent er .
Li s t i n g 4 . 9 De t a i l Pr e s e n t e r . a s ( c o n t i n u e d )
pr i va t e f"
r et ur :
}
pr i va t e
t hi s. .
_vi ew
_vi ew
_vi ew
_vi ew
_vi ew
_vi ew
J
Get pr oper t y f or
unc t i on get sel ec t edl ssue ( ) : I ssue { <1—I sel ect ed i ssue
n t hi s. _i ssue;
sel ect ed i ssue
f unc t i on set sel ec t edl ssue( i ssue : I ssue) : voi d {
_i ssue = i ssue;
. i ssuel d = i ssue. i d == 0 ? "" : i ssue. i d. t oSt r i ng( ) ;
. pr oj ec t = i ssue. pr oj ec t ;
. desc r i pt i on = i ssue. desc r i pt i on;
•t ype = i ssue. t ype;
. sever i t y = i ssue. sever i t y;
. st a t us = i ssue. st a t us;
^ ^ p Set pr oper t y f or
www.it-ebooks.info
97 CHAPTER 4 Connecting to web services
_vi ew. det a i l s = i ssue. det a i l s ;
_vi ew. r epor t edBy = i ssue. r epor t edBy;
_vi ew. r epor t edOn = i ssue. r epor t edOn;
_vi ew. a ssi gnedTo = i ssue. a ssi gnedTo;
_vi ew. est i ma t edHour s = i sNa N( i ssue. est i ma t edHour s) ?
"" : i ssue. est i ma t edHour s. t oSt r i ng( ) ;
_vi ew. a ddEdi t La bel = i ssue. i d == 0 ?
"Add I ssue" : "Sa ve I ssue" ;
pr i va t e f unc t i on sa vel ssue ( event : UI Event = nul l ) : voi d { <1—,
_i ssue. pr oj ec t = _vi ew. pr oj ec t ; A Save i ssue
_i ssue. desc r i pt i on = _vi ew. desc r i pt i on;
_i ssue. t ype = _vi ew. t ype;
_i ssue. sever i t y = _vi ew. sever i t y;
_i ssue. st a t us = _vi ew. st a t us ;
_i ssue. det a i l s = _vi ew. det a i l s ;
_i ssue. r epor t edOn = _vi ew. r epor t edOn;
_i s sue. r epor t edBy = _vi ew. r epor t edBy;
_i ssue. a ssi gnedTo = _vi ew. a ssi gnedTo;
_i ssue. est i ma t edHour s = ! i sNa N( Number ( _vi ew. est i ma t edHour s) ) ?
Number ( _vi ew. est i ma t edHour s) : nul l ;
_i ssueModel . sa vel ssue( _i ssue,
new Async Responder ( sa vel ssueResul t , ha ndl eEr r or ) ) ;
'' Q Cancel
pr i va t e f unc t i on c a nc el Cha nges( event : UI Event = nul l ) : voi d { <—' changes
sel ec t edl ssue = new I s s ued;
A Sel ect ed Issue
pr i va t e f unc t i on c ha ngedl ssue( event : UI Event ) : voi d { <—' changed
sel ec t edl ssue = event . da t a ;
' Save i ssue r esul t O
pr i va t e f unc t i on sa vel ssueResul t ( r esul t Event : Resul t Event ,
t oken : Async Token = nul l ) : voi d { <1—'
sel ec t edl ssue = new I ssue( r esul t Event . r esul t ) ;
va r event : UI Event = new UI Event ( UI Event . SELECTED _I SSUE_SAVED ) ;
event . da t a = _i ssue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( event ) ;
}
pr i va t e f unc t i on ha ndl eEr r or ( event : Fa ul t Event ,
t oken : Async Token = nul l ) : voi d { <—,
Al er t . show( event . messa ge. t oSt r i ng( ) ) ;
j Er r or handl er Q
You then create get and set pr oper ti es Q , Q for tl i e currentl y sel ected issue. The get
pr oper ty wi l l return the current issue; the set pr oper ty wi l l update all di e for m fi el ds
i n the vi ew so tiiat they match di e currendy sel ected issue.
Next you've defi ned a method to handl e saving di e I ssue Q , whi ch gets di e values
f r om the vi ew and updates di e currentl y sel ected I ssue befor e cal l i ng di e savel ssue
www.it-ebooks.info
Enhancing the comments view 75
P ro p e rti e s in A c ti o n S c ri p t
A c t i o n S c ri p t , u n li k e J a v a , h a s f i rs t -c l a s s s u p p o rt fo r p ro p e rt i e s s i m i la r t o o t h e r la n -
g u a g e s s u c h a s C # , R u b y , a n d G ro o v y . T h i s g i v e s y o u t h e a b i li t y t o g e t a n d s e t va l-
u e s o n a v a ri a b le a s i f i t w e re a p u b li c m e m b e r v a ri a b le o n t h e c l a s s , i n s t e a d o f
h a vi n g t o d o get xxx () a n d set xxx () m e t h o d s a s y o u w o u l d i n J a v a .
T h e s y n t a x fo r d e fi n i n g g e t / s e t p ro p e rt i e s i s a s f o l l o w s :
publ i c f unc t i on get na me( ) : St r i ng {
r et ur n _na me;
}
publ i c f unc t i on set na me( va l ue: St r i ng) : voi d {
_na me = va l ue;
M a n y d e v e l o p e rs u s e t h e c o n v e n t i o n o f p re f i xi n g t h e p ri v a t e m e m b e r v a ri a b l e s w i t h
a n u n d e rs c o re (_) so t h a t t h e c o m p i l e r c a n fi g u re o u t i f y o u a re t ry i n g t o re f e re n c e
t h e p ri v a t e m e m b e r v a ri a b le o r t h e g e t / s e t p ro p e rt y i n t h e c l a s s . O n e o f t h e a d va n -
t a g e s o f u s i n g g e t / s e t p ro p e rt i e s i s t h a t i t re m o v e s t h e n e e d t o d e fi n e a lo t o f
get xxx/ set xxx m e t h o d s t h a t d o n o t h i n g b e y o n d g e t t i n g a n d s e t t i n g t h e p ri v a t e
v a ri a b l e . U s i n g p ro p e rt i e s a l l o w s y o u t o d e fi n e y o u r m e m b e r v a ri a b l e s a s p u b li c . I f
y o u n e e d t o e n c a p s u l a t e lo g i c w h e n m e m b e r v a ri a b l e s a re a c c e s s e d , y o u c a n e a s i ly
re f a c t o r y o u r c l a s s t o u s e a g e t / s e t p ro p e rt y , a n d n o n e o f t h e c l a s s e s t h a t u s e i t
wi ll h a ve t o c h a n g e a s a re s u lt .
method on di e model . The method tiiat responds to di e Cancel Changes button
bei ng clicked Q sets the selected issue to a brand new I ssue object. Whenever di e
SELECTED_ISSUE_CHANGED event is fi red, di e changedl ssue 0 meti i od is called and
sets di e selected I ssue by using the set property you defi ned earlier. You create di e
handlers for di e savel ssueResul t Q and di e error handler Q to handle di e result
fr om calling di e I ssueModel .
4.6.2 Updating the IssueModel
Now diat you've i mpl emented di e Presenter for di e details view, let's do di e same for
the new methods in the I ssueModel to support the updated functionality.
Li st i n g 4 . 1 0 I ssu eMo d el . a s
pa c ka ge or g. f oj . model {
publ i c f unc t i on get l ssue( i d: Number , r esponder : I Responder ) : voi d {
va r t oken: Async Token = _i ssueSer vi c e. get ( i d) ;
t oken. a ddResponder ( r esponder ) ;
}
get l ssue
savelssue
publ i c f unc t i on sa vel ssue( i ssue: I ssue, r esponder : I Responder ) : voi d {
va r t oken: Async Token = _i ssueSer vi c e. sa ve( i ssue) ;
' J
www.it-ebooks.info
76 CHAPTER 4 Connecting to web services
t oken. a ddResponder ( r esponder ) ;
}
}
}
J ust as befor e, the methods i n the I ssueModel are fai rl y si mpl e. The get l s s u e O
method takes an i d par ameter to find a speci fi c I ssue as wel l as an I Responder to add
a r esponder to the token r etur ned f r om di e call to the WebSer vi ce. The savel ssue ©
method takes i n an I ssue obj ect to pass al ong to di e WebSer vi ce to persist, as wel l as
an I Responder .
4.6.3 Updating the detail view
The last part of di e MVP triad tiiat needs to be updated now is di e Det ai l Vi ew. List-
i ng 4.11 shows di e updated versi on of di e Detai l Vi ew. mxml after you add di e neces-
sary methods to di spatch the events to save an I ssue or cancel di e changes.
Li s t i n g 4 . 1 1 De t a i l Vi e w . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Pa nel xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
l a yout =" ver t i c a l "
t i t l e=" D et a i l s"
wi dt h=" 100%"
hei ght =" 100%"
c r ea t i onCompl et e=" i ni t ( ) " >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t mx. c ol l ec t i ons. Ar r a yCol l ec t i on;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
i mpor t or g. f oj . pr esent er . D et a i l Pr esent er ;
pr i va t e va r _pr esent er : D et a i l Pr esent er ;
pr i va t e f unc t i on i ni t ( ) : voi d {
_i ssueType. sel ec t edl ndex = - 1;
_i ssueSever i t y. sel ec t edl ndex = - 1;
_i ssueSt a t us. sel ec t edl ndex = - 1;
_pr esent er = new D et a i l Pr esent er ( t hi s) ;
}
J
creat i onCompl et e
J
i ni t i al i zat i on
J
saveChanges
pr i va t e f unc t i on sa veCha nges( ) : voi d {
va r sa veEvent : UI Event = new UI Event ( UI Event . SAVE_I SSUE_BUTTON_CLI CKED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( sa veEvent ) ;
}
cancel Changes
pr i va t e f unc t i on c a nc el Cha nges( ) : voi d {
va r c a nc el Event : UI Event = new UI Event ( UI Event . CANCELLED _I SSUE_ED I T) ;
www.it-ebooks.info
Enhancing the comments view 77
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( c a nc el Event ) ;
}
] ]>
</ f x: Sc r i pt >
<mx: For m i d=" _i ssueD et a i l For m" wi dt h=" 100%" >
</ mx: For m>
<mx: Cont r ol Ba r >
<mx: But t on i d=" _sa veCha ngesBut t on"
l a bel =" Add I ssue"
c l i c k=" sa veCha nges( ) " / >
<mx: But t on i d=" _c a nc el Cha ngesBut t on"
l a bel =" Ca nc el Cha nges" c l i c k
</ mx: Cont r ol Ba r >
</ mx: Pa nel >
You tel l tl i e component to call the i n i t © method to i ni ti al i ze tl i e component when
the cr eat i onCompl et e O event is fi r ed. I nsi de di e i n i t method, you bootstrap di e
Presenter j ust as you di d earl i er i n the MasterVi ew. You also set di e s el ect edl t em
pr oper ty on the tiiree combo boxes to - 1, so they don't have a val ue sel ected when
the component is fi rst created. Then you add an event handl er for di e cl i ck event
on di e saveChangesButton 0 cal l ed saveChanges 0 . I nsi de the saveChanges
met hod you di spatch an event si gnal i ng that di e button has been cl i cked. As a fi nal
step, you add an event handl er cancel Changes 0 for di e click event on di e cancel -
ChangesButton 0 and it dispatches an event noti fyi ng di e appl i cati on that tl i e but-
ton had been cl i cked.
4.7 Enhanci ng t he comment s vi ew
You've al most fi ni shed enhanci ng di e sampl e appl i cati on. The last part that needs to
be updated is di e comments view. You'l l start by creati ng an MVP tri ad j ust as befor e.
Later you'l l add a modal pop up to add new comments and edi t exi sti ng comments.
Let's get started.
4.7.1 Creating a comments presenter
Creati ng tl i e Presenter for the comments vi ew of tl i e appl i cati on wi l l be j ust l i ke cre-
ati ng the last two Presenters. The CommentsL i stPr esenter wi l l be r esponsi bl e f or
mai ntai ni ng mor e state than the pr evi ous Presenters. I t wi l l need to mai ntai n a
r efer ence to not onl y the cur r endy sel ected issue, but al so the currentl y sel ected
comment, to properl y persist di e Comment objects. Because di e code for di e Comments-
L i s t P r es en t er is rather l engti i y, we'l l break it up. The fol l owi ng l i sti ng shows tl i e
fi rst secti on i n whi ch you defi ne whi ch events this Pr esenter wi l l l i sten for and a
coupl e of get/ set properti es.
0 cl i ck event on
^ T saveChangesBut t on
=" c a nc el Cha nges () " / > <1—i
d i ck event on I
cancel ChangesBut t on 0
www.it-ebooks.info
101 CHAPTER 4 Connecting to web services
Li st i ng 4 .1 2 Com m ent sLi st Pr esent er .as
pa c ka ge or g. f oj . pr esent er {
publ i c c l a ss Comment sLi st Pr esent er {
pr i va t e va r _sel ec t edl ssue: I ssue;
Mai nt ai ni ng
pr i va t e va r _sel ec t edComment : Comment ; « State
pr i va t e va r _c omment Model : Comment Model ;
pr i va t e va r _vi ew: Comment sVi ew;
pr i va t e va r _popl : Edi t Comment For m;
publ i c f unc t i on Comment sLi st Pr esent er ( vi ew: Comment sVi ew = nul l ) {
t hi s. _c omment Model = new Comment Model ( ) ;
t hi s. _vi ew = vi ew; Const r uct or •I
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SELECTED _I SSUE_CHANGED , <—i £ Vent
c ha ngeSel ec t edl ssue) ; Q l i st eners
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . D ELETE_COMMENT_BUTTON_PRESSED ,
r emoveComment ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SELECTED _COMMENT_CHANGED ,
c ha ngeSel ec t edComment ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . COMMENTS_UPD ATED ,
r ef r eshComment s) ;
pr i va t e f unc t i on get sel ec t edl ssue( ) : I ssue {
r et ur n t hi s. _sel ec t edl ssue;
pr i va t e f unc t i on set sel ec t edl ssue ( i ssue: I ssue) : voi d { sel ect edl ssue
t hi s. _sel ec t edl ssue = i ssue;
_vi ew. a ddComment But t on. ena bl ed = i ssue. i d > 0;
pr i va t e f unc t i on get sel ec t edComment ( ) : Comment {
r et ur n t hi s. _sel ec t edComment ;
}
Q get pr oper t y f or
^ J sel ect edl ssue
set pr oper t y f or
J
get pr oper t y f or
sel ect edComment
pr i va t e f unc t i on set sel ec t edComment ( c omment : Comment ) : voi d {
t hi s. _sel ec t edComment = c omment ;
_vi ew. edi t Comment But t on. ena bl ed = c omment != nul l ;
set pr oper t y f or
_vi ew. del et eComment But t on. ena bl ed = c omment != nul l ; sel ect edComment
a
: ©
}
First you defi ne vari abl es to mai ntai n di e state ©. Then you defi ne a constructor ©
di at takes i n a r efer ence to di e Vi ew tiiat tiiis Presenter is created for. Next you initial-
i ze the Model , and add a few event listeners © for di e Presenter so it can react prop-
erly to speci fi c events.
www.it-ebooks.info
Enhancing the comments view 79
Once agai n you'r e l everagi ng get and set pr oper ti es i n this Presenter, usi ng di e set
pr oper ty to tri gger whether or not certai n el ements of the vi ew shoul d be enabl ed.
You start by creati ng a get pr oper ty for the currendy sel ected issue Q , and i n its corre-
spondi ng set pr oper ty you deter mi ne wheti i er or not to enabl e the Add Com-
ments button based on wheti i er or not the currentl y sel ected issue's i d pr oper ty is
gr eater tiian zero, i ndi cati ng it has been saved. You do tiiis to make sure that the user
can't save a comment for an I ssue tiiat has not been persi sted to di e backend previ -
ously. You create a get pr oper ty for di e currendy sel ected comment Q as wel l as a set
pr oper ty for the sel ected comment Q . Si mi l ar to the last set property, you use tiiis
opportuni ty to enabl e or di sabl e di e Edi t Comment and Del ete Comment buttons
based on whether or not tiiere is a comment sel ected i n di e Li st component contai n-
i ng di e comments.
Li s t i n g 4 . 1 3 Co m m e n t s L i s t Pr e s e n t e r . a s ( c o n t i n u e d )
pr i va t e f unc t i on c ha ngeSel ec t edl ssue( event : UI Event ) : voi d { <
sel ec t edl ssue = event . da t a ;
sel ec t edComment = nul l ; Handl er f or
- , , , sel ect edl ssue changi ng V
r ef r eshComment s( ) ;
6 6
}
F
°
R
JH
;ing O
pr i va t e f unc t i on c ha ngeSel ec t edComment ( event : UI Event ) : voi d {
sel ec t edComment = event . da t a ;
j Handl er
sel ect edComment changi ng
pr i va t e f unc t i on r emoveComment ( event : * = nul l ) : voi d { <—.
Cur sor Ma na ger . set BusyCur sor () ; Q removeComment
_c omment Model . r emoveComment ( sel ec t edComment . i d,
new Async Responder ( r emoveComment Resul t , ha ndl eEr r or ) ) ;
}
pr i va t e f unc t i on r ef r eshComment s( event : * = nul l ) : voi d {
Cur sor Ma na ger . set BusyCur sor ( ) ;
_c omment Model . get Comment sFor l ssuel d( sel ec t edl ssue. i d,
new Async Responder ( l oa dComment sResul t , ha ndl eEr r or ) ) ;
}
1>
ref resh
comment s l i st
pr i va t e f unc t i on r emoveComment Resul t ( event : Resul t Event ,
t oken: Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
.1
r ef r eshComment s ( ) ; removeComment Resul t
}
pr i va t e f unc t i on l oa dComment sResul t ( event : Resul t Event ,
t oken: Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
va r c omment s: Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on( ) ;
f or ea c h ( va r r esul t : * i n event . r esul t ) {
M
^
l oadComment sResul t 0
c omment s. a ddl t em( new Comment ( r esul t ) ) ; * *
}
_vi ew. c omment sLi st . da t a Pr ovi der = c omment s;
www.it-ebooks.info
80 CHAPTER 4 Connecting to web services
_vi ew. c omment sLi st . sel ec t edl ndex = - 1;
sel ec t edComment = nul l ;
}
pr i va t e f unc t i on ha ndl eEr r or ( event : Fa ul t Event ,
t oken: Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
Al er t . show( " Er r or oc c ur ed: " + event . messa ge) ;
}
}
}
Li sti ng 4.13 shows the rest of the code for the Comment sLi st Pr esent er . First you
defi ne a medi od to handl e changes to the sel ected issue ©, wher e you set di e sel ected
issue f r om di e data passed al ong i n di e event. You tiien set the sel ected comment to
nul l , and refresh di e list of comments to be di spl ayed. When someone clicks on a
comment i n di e Li st vi ew of the Comment sVi ew, di e sel ec t edComment Cha nged ©
method wi l l be cal l ed, wher e you set di e sel ected comment to di e comment i n di e
i ncomi ng event.
The next medi od you defi ne handl es di e user cl i cki ng di e Remove Comment
button ©. You first tel l di e Cur sor Ma na ger to set di e busy cursor, as you di d earl i er
i n di e odi er Presenters. Then you make a call to di e Comment Model to r emove di e
sel ected comment. When the result comes back © f r om di e call to the Comment -
Model you r emove the busy cursor and tel l di e Presenter to refresh di e list of com-
ments for di e view.
To refresh di e list of comments you created a functi on cal l ed r ef r eshComment s ©,
whi ch makes a call to the Comment Model to retri eve a list of comments for a gi ven issue
i d. When di e result comes back f r om this call ©, you i terate tiirough the list of
Obj ec t Pr oxy instances that come back f r om the WebSer vi c e and use di e conveni ence
constructor you defi ned at di e begi nni ng of tiiis chapter to create a list of Comment
obj ects. You then set the da t a Pr ovi der pr oper ty of the Li st component i n the vi ew to
this list of Comment obj ects and r emove di e busy cursor. Last you create a si mpl e er r or
handl er © as you di d for di e two Presenters you created earlier.
4.7.2 Creating a comment model
Odi er than the method names, di e Comment Model wi l l l ook si mi l ar to the I ssueModel
you created earlier.
Li s t i n g 4 . 1 4 Co m m e n t M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . I Responder ;
i mpor t mx. r pc . soa p. WebSer vi c e;
publ i c c l a ss Comment Model {
pr i va t e va r _c omment Ser vi c e: WebSer vi c e;
handl eEr r or
www.it-ebooks.info
Enhancing the comments view 81
publ i c f unc t i on Soa pComment Model () { <1—.
_c omment Ser vi c e = new WebSer vi c e () ; A Const r uct or
_c omment Ser vi c e. wsdl =
" ht t p: / / l oc a l host : 8080/ ser vi c es/ Comment Ser vi c e?wsdl " ;
i f ( _c omment Ser vi c e. c a nLoa dWSD L( ) ) {
_c omment Ser vi c e. l oa dWSD L( ) ;
get Com m ent sFor l ssuel d Q
publ i c f unc t i on get Comment sFor l ssuel d ( i ssuel d: Number , <1—
r esponder : I Responder ) : voi d {
va r t oken: Async Token = _c omment Ser vi c e. f i ndComment sByl ssuel d( i ssuel d) ;
t oken. a ddResponder ( r esponder ) ;
* * * removeComment
J
publ i c f unc t i on r emoveComment ( i d: Number ,
r esponder : I Responder ) : voi d {
va r t oken : Async Token = _c omment Ser vi c e. r emove( i d) ;
t oken. a ddResponder ( r esponder ) ;
}
}
}
I n the constructor O you create a new WebSer vi c e component and set its wsdl prop-
erty to di e WS D L for di e web servi ce. Then j ust as you di d earlier, you tell di e Web-
Ser vi c e to l oad di e WS D L so you can make calls to it. Next you defi ne di e two
medi ods needed for di e appl i cati on to functi on, the get Comment sFor l ssuel d Q and
the r emoveComment Q methods.
4.7.3 CommentView
Now that you have di e meti i ods i mpl emented i n di e Comment Model , you can update di e
Comment sLi st Vi ew component to enabl e it to r espond to user i nteracti on. Li sti ng 4.15
shows the updated CommentsLi stVi ew. mxml file. For now, you'r e goi ng to r espond
onl y to clicks i n di e Li st component contai ni ng di e comments and the Remove Com-
ment button. I n di e next secti on you'l l start i mpl ementi ng the modal pop up that wi l l
al l ow you to add and edi t comments.
Li s t i n g 4 . 1 5 Co m m e n t s L i s t Vi e w . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Pa nel xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
l a yout =" ver t i c a l "
t i t l e=" Comment s"
wi dt h=" 100%"
hei ght =" 100%" O creat i onCompl et e
c r ea t i onCompl et e=" i ni t () " > <1—I
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
i mpor t or g. f oj . pr esent er . Comment sLi st Pr esent er ;
www.it-ebooks.info
105 CHAPTER 4 Connecting to web services
pr i va t e va r _pr esent er : Comment sLi st Pr esent er ;
pr i va t e f unc t i on i ni t ( ) : voi d { © i ni t
_pr esent er = new Comment sLi st Pr esent er ( t hi s) ;
}
J »
removeComment
pr i va t e f unc t i on r emoveComment ( ) : voi d {
c omment sLi st . sel ec t edl ndex = - 1;
va r r emoveComment Event : UI Event =
new UI Event ( UI Event . D ELETE_COMMENT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
pr i va t e f unc t i on sel ec t edl t emCha nged( event : Event ) : voi d { <—I
va r c omment Cha ngedEvent : UI Event =
new UI Event ( UI Event . SELECTED _COMMENT_CHANGED ) ;
c omment Cha ngedEvent . da t a = c omment sLi st . sel ec t edl t em;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent
( c omment Cha ngedEvent ) ;
}
</ f x: Sc r i pt >
<mx: Li st i d=" _c omment sLi st "
wi dt h=" 100%"
hei ght =
11
100%
11
© i t emCl i ck event
i t emCl i c k=" sel ec t edl t emCha nged( event ) " <—I
l a bel Fi el d=" c omment Text " >
</ mx: Li st >
<mx: Cont r ol Ba r >
<s: But t on i d=" _a ddComment But t on"
l a bel =" Add New Comment "
ena bl ed=" f a l se" / >
<s: But t on i d=" _edi t Comment But t on"
l a bel =" Edi t Comment "
ena bl ed=" f a l se" / >
<s: But t on i d=" _del et eComment But t on"
l a bel =" D el et e Comment " © d i ck event
c l i c k=" r emoveComment () " <—I
ena bl ed=" f a l se" / >
</ mx: Cont r ol Ba r >
</ mx: Pa nel >
Agai n, you use the c r ea t i onCompl et e event © to call the i ni t method © wher e you
bootstrap the Presenter. You tiien create an event handl er named r emoveComment ©
to handl e di e user cl i cki ng di e Del ete Comment button ©. I nsi de this meti i od you set
di e sel ec t edl ndex to -1 so no i tems are sel ected i n di e Li st and di spatch an event
noti fyi ng the rest of the appl i cati on that the button has been cl i cked. Next you defi ne
an event handl er method sel ec t edl t emCha nged © to handl e di e user sel ecti ng an
i tem i n the Li st component ©.
www.it-ebooks.info
Adding a pop-up form for editing comments 83
Add/Edit Comment
Author :
1
G
Dote: / /
Comment;
Sove Comment I Cancel |
Fi gur e 4 .2 Wi ref rame of pop up f or edi t i ng com m ent s
4.8 Addi ng a pop-up f orm f or edi t i ng comment s
Al l that's l eft to compl ete the sampl e appl i cati on is creati ng a pop up for addi ng and
edi ti ng comments. Fi gure 4.2 shows a wi r efr ame mockup of the pop up. I t's a fai rl y
si mpl e pop- up di al og tiiat consists of a text i nput for the auti i or's name, the date the
comment was created, and a text area for enter i ng di e comment details.
Now tiiat you see what you want to bui l d, let's get started. The fol l owi ng secti on
illustrates how you bui l d di e pop up, starting wi th updati ng the Comment Presenter.
4.8.1 Updating the CommentPresenter
First l et's add di e methods you need to di e CommentPresenter for di e pop- up di al og.
Li s t i n g 4 . 1 6 Ad d i n g a p o p u p t o Co m m e n t L i s t Pr e s e n t e r . a s
pr i va t e va r _popl : Edi t Comment For m; <1—© Pop up com ponent
publ i c f unc t i on Comment sLi st Pr esent er ( vi ew: Comment sVi ew = nul l ) { <—
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . AD D _NEW_COMMENT_BUTTON_PRESSED ,
a ddNewComment ) ; Add more
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) event l i st eners ©
. a ddEvent Li st ener ( UI Event . ED I T_COMMENT_BUTTON_PRESSED ,
edi t Comment ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . SAVE_COMMENT_BUTTON_PRESSED ,
sa veComment ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . CANCEL_ED I T_COMMENT_BUTTON_PRESSED ,
c a nc el Edi t ) ;
www.it-ebooks.info
107 CHAPTER 4 Connecting to web services
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . COMMENTS_UPD ATED ,
r ef r eshComment s) ;
}
S
addNewComment
pr i va t e f unc t i on a ddNewComment ( event : * = nul l ) : voi d {
sel ec t edComment = new Comment ( ) ;
sel ec t edComment . i ssue = sel ec t edl ssue;
_popl = PopUpMa na ger . c r ea t ePopUp( ( _vi ew a s Ul Component ) . r oot ,
Edi t Comment For m, t r ue) a s Edi t Comment For m;
PopUpMa na ger . c ent er PopUp( _popl a s Ul Component ) ;
pr i va t e f unc t i on edi t Comment ( event : * = nul l ) : voi d {
_popl = PopUpMa na ger . c r ea t ePopUp( ( _vi ew a s Ul Component ) . r oot ,
Edi t Comment For m, t r ue) a s Edi t Comment For m;
PopUpMa na ger . c ent er PopUp( _popl a s Ul Component ) ;
_popl . a ut hor . t ext = sel ec t edComment . a ut hor ;
_popl . c omment D a t e. sel ec t edD a t e = sel ec t edComment . c r ea t edD a t e;
_popl . c omment Text . t ext = sel ec t edComment . c omment Text ;
}
edi t Comment
pr i va t e f unc t i on sa veComment ( event : * = nul l ) : voi d {
Cur sor Ma na ger . set BusyCur sor ( ) ;
sel ec t edComment . a ut hor = _popl . a ut hor . t ext ;
sel ec t edComment . c r ea t edD a t e = _popl . c omment D a t e. sel ec t edD a t e;
sel ec t edComment . c omment Text = _popl . c omment Text . t ext ;
J
saveComment
_c omment Model . sa veComment ( sel ec t edComment ,
new Async Responder ( sa veComment Resul t , ha ndl eEr r or ) ) ;
G cancel Edi t
pr i va t e f unc t i on c a nc el Edi t ( event : * = nul l ) : voi d { <—I
r emovePopUp( ) ;
}
pr i va t e f unc t i on sa veComment Resul t ( event : Resul t Event ,
t oken: Async Token = nul l ) : voi d { <1—i
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
sel ec t edComment = event . r esul t a s c or ment ; saveComment Resul t handl er O
va r c omment sCha ngedEvent : UI Event =
new UI Event ( UI Event . COMMENTS_UPD ATED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( c omment sCha ngedEvent ) ;
r emovePopUp( ) ;
}
pr i va t e f unc t i on r emovePopUp( ) : voi d {
PopUpMa na ger . r emovePopUp( _popl a s Ul Component ) ;
}
removePopUp
Change the CommentPresenter to decl are a member vari abl e for di e pop up itself
Next add event listeners Q to r espond to user clicks on di e buttons on di e Comments-
Vi ew and di e pop up you'r e goi ng to create.
www.it-ebooks.info
Adding a pop-up form for editing comments 85
Defi ne an event handl er for di e Add New Comment Q button, set di e selected
comment to a brand new comment and create the pop up using di e PopupMa na ger .
The call to c r ea t ePopUp takes three parameters: di e component that will be di e par-
ent of di e pop up, pop up class, and wheti i er or not di e pop up should be modal . Set
the parent for di e pop up to be di e root application component so that when you call
c ent er PopUp on the PopUpMa na ger in di e next line it will center relative to the whol e
application instead of to di e Comment Vi ew.
The next event handler, edi t Comment © starts out in a manner similar to di e
a ddNewComment handler. You create a pop up using the PopUpMa na ger and center it,
then update the fields in di e pop up with the values fr om di e currendy selected com-
ment. When di e user clicks the Save Comment button in di e pop up, the sa veComment
© handl er is called. You tiien take all the values fr om di e pop up and update the cur-
rendy selected comment and make a call to di e Comment Model to save di e comment.
When the user clicks di e Cancel Changes button on di e pop up, di e c a nc el Edi t Q
meti i od is called, where you remove the pop up.
When di e result comes back fr om the call to save the comment, di e sa veComment -
Resul t handler Q is called. There you update di e selected comment with di e result
fr om di e web service call, then trigger the Li st to update by dispatching an event sig-
naling diat the comments have changed and remove di e pop up Q .
4.8.2 Updating the CommentModel
Next you add another meti i od to the Comment Model to call the web service and save
a comment.
Li st i n g 4 . 1 7 Co m m en t Mo d el . a s
publ i c f unc t i on sa veComment ( c omment : Comment ,
r esponder : I Responder ) : voi d {
va r t oken: Async Token = _c omment Ser vi c e. sa ve( c omment ) ;
t oken. a ddResponder ( r esponder ) ;
}
Listing 4.17 shows the method you add to the Comment Model to save comments. This
meti i od is just like every other call we've made to di e WebSer vi c e. I t delegates di e call
to the web service and adds a responder to di e token so di e application can react
when the result comes back fr om the asynchronous call to the web service.
4.8.3 Creating the pop-up component
Now you can create di e actual pop up component tiiat you'l l use to create new com-
ments as well as edit existing ones. Even though you're instantiating the pop up in
ActionScript by making calls to the PopUpMa na ger , it's easiest to defi ne this actual com-
ponent in MXML just as with all di e otiier Vi ew components. Listing 4.18 shows the
contents of the Edi tCommentForm.mxml file defi ni ng the pop up.
www.it-ebooks.info
109 CHAPTER 4 Connecting to web services
Li st i ng 4 .1 8 Edi t Com m ent For m .m xm l
<?xml ver si on=" 1. 0" ?>
<mx: Ti t l eWi ndow
xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
t i t l e=" Add/ Edi t Comment "
hei ght =" 400"
wi dt h=" 500" >
1>
Ext ends
Ti t l eWi n d ow
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
pr i va t e f unc t i on sa veComment ( ) : voi d {
va r sa veEvent : UI Event =
new UI Event ( UI Event . SAVE_COMMENT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( sa veEvent ) ;
}
J
J
saveCom m ent
event Handl er
pr i va t e f unc t i on c a nc el Cha nges( ) : voi d {
va r c a nc el Event : UI Event =
new UI Event ( UI Event . CANCEL_ED I T_COMMENT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( c a nc el Event ) ;
}
cancel Changes
event Handl er
] ]>
</ f x: Sc r i pt >
<mx: For m wi dt h=" 100%" >
<mx: For mI t em l a bel =" Aut hor : "
wi dt h=" 100%" >
<mx: Text l nput i d=" _a ut hor "
wi dt h=" 100%" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" D a t e: "
wi dt h=" 100%" >
<mx: D a t eFi el d i d=" _c omment D a t e"
wi dt h=" 100%"
f or ma t St r i ng=" MM/ D D / YYYY" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Comment : "
wi dt h=" 100%" >
<mx: Text Ar ea i d=" _c omment Text "
wi dt h=" 100%"
hei ght =" 200" / >
</ mx: For mI t em>
</ mx: For m>
<mx: Cont r ol Ba r >
<mx: But t on i d=" _sa veBut t on"
l a bel =" Sa ve Comment "
c l i c k=" sa veComment ( ) " / >
J
For m
1>
Cont r ol Bar
www.it-ebooks.info
Adding a pop-up form for editing comments 87
<mx: But t on i d=" _c a nc el But t on"
l a bel =" Ca nc el "
c l i c k=" c a nc el Cha nges( ) " / >
</ mx: Cont r ol Ba r >
</ mx: Ti t l eWi ndow>
The code for di e pop up l ooks si mi l ar to di e D et a i l sVi ewfor the issues. The mai n di f-
fer ence is this component extends di e Ti t l eWi ndow O component i nstead of the
Pa nel component. Most of di e pop up wi ndows you'l l create wi l l extend tiiis compo-
nent. You di en defi ne a coupl e of methods ©, © to react to di e button clicks of the pop
up to di spatch UI Event s for di e appl i cati on to listen for. J ust as wi th the D et a i l Vi ew,
you use di e For mcomponent © for conveni ent layout of the for m fi el ds and labels for di e
pop up. You di en create a Cont r ol Ba r © to hol d di e Save Comment and Cancel buttons.
4.8.4 Updating CommentsListView
The onl y tiling l eft is to update the Comment sLi st Vi ew to di spatch the necessary
events for di e Add Comment and Edi t Comment buttons.
Li s t i n g 4 . 1 9 Up d a t e d Co m m e n t L i s t Vi e w . m x m l
pr i va t e f unc t i on a ddNewComment ( ) : voi d {
va r a ddNewComment Event : UI Event =
new UI Event ( UI Event . AD D _NEW_COMMENT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( a ddNewComment Event ) ;
}
pr i va t e f unc t i on edi t Comment ( ) : voi d {
va r edi t Comment Event : UI Event =
new UI Event ( UI Event . ED I T_COMMENT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( edi t Comment Event ) ;
}
addNewComment
edi t Comment
<mx: Cont r ol Ba r >
<s: But t on i d=" a ddComment But t on"
l a bel =" Add New Comment "
c l i c k=" a ddNewComment ( ) "
ena bl ed=" f a l se" / >
<s: But t on i d=" edi t Comment But t on"
l a bel =" Edi t Comment "
c l i c k=" edi t Comment ( ) "
ena bl ed=" f a l se" / >
<s: But t on i d=" del et eComment But t on"
l a bel =" D el et e Comment "
c l i c k=" r emoveComment ( ) "
ena bl ed=" f a l se" / >
</ mx: Cont r ol Ba r >
© di ck handl ers
on t he but t ons
The fi rst two changes to di e Comment sLi st Vi ew are addi ng methods ©, © to be
cal l ed when di e Add New Comment and Edi t Comment buttons are cl i cked. These
www.it-ebooks.info
111 CHAPTER 4 Connecting to web services
wi l l create and di spatch UI Events l i ke every oti i er vi ew you've defi ned so far. Then you
update di e buttons tiiemselves Q so that they wi l l call di e meti i ods you defi ned when
di ey are cl i cked.
Summary
I n di i s chapter you expl or ed di e archi tectural el ements tiiat make up a wel l - desi gned,
flexible, and mai ntai nabl e RI A. You l ear ned how to appl y the MVP pattern to di e code
and how fol l owi ng di at pattern, you effecti vel y separate di e areas of concer n i nto tiieir
i sol ated parts. After you abstracted the calls to external services i n the Model , you dis-
cover ed how easy it woul d be to potenti al l y repl ace this por ti on of di e code wi ti i out
affecti ng any odi er part of di e code.
I n the next chapter you'l l bui l d upon what you've assembl ed i n di i s chapter and
i ntr oduce di e Spri ng BlazeDS I ntegrati on fr amewor k and BlazeDS r emoti ng.
www.it-ebooks.info
Part 2
BlazeDS remoting
n the tlie first of two chapters in part 2, you'l l dive i nto BlazeDS remoti ng,
l earni ng the basics of BlazeDS and refactori ng di e exampl e appl i cati on to take
advantage of it. I n a nutshell, BlazeDS is a col l ecti on of J ava components that
you can depl oy witii your web appl i cati on for AMF/ HTTP communi cati on
between Flex and J ava. BlazeDS also supports messaging. BlazeDS is basically a
subset of the commerci al Flex Data Services offer i ng fr om Adobe, and al though
you can do many tilings with BlazeDS, certain functi ons like clustering and
advanced bi ndi ng techniques can only be accompl i shed witii the full-blown Flex
Data Services.
I n chapter 6, you'l l take di e next step in evol vi ng our Flex and J ava communi -
cations and take advantage of real-time messaging between the two using
BlazeDS messaging. The chapter exploits the use of the Flex Messaging API and
si mpl e pol l i ng to recei ve updates fr om di e server when changes in di e model
have occurred.
You will learn how to set up BlazeDS l oggi ng, per for mance benchmarki ng,
and Flex Messaging.
www.it-ebooks.info
www.it-ebooks.info
BlazeDS remoti
and loggi
Thi s chapt er covers
• B u i l d i n g a B l a z e D S C o n f i g u ra t i o n M o d u l e
• F l e x a n d J a v a c o m m u n i c a t i o n w i t h B l a z e D S
• S p ri n g B l a z e D S I n t e g ra t i o n f ra m e w o rk
• L o g g i n g e v e n t s a n d p e rf o rm a n c e s t a t i s t i c s
I n previous chapters you built a Flex client application using the MVP design pat-
tern and connected it to J ava through web services. Now you're goi ng to move fr om
XML/ HTTP web services and try remoti ng.
For Acti on Message Format communication, or AMF, Flex provides di e
RemoteObject component tiiat uses Adobe's own AMF binary protocol to com-
municate with di e server. This means you'l l need a process running on di e
server side, such as BlazeDS, tiiat understands how to serialize and deserialize
the AMF protocol .
I n the next section we introduce you to BlazeDS and begi n integrating with
our sample application. We'l l be using the FlexBugs sample application but it
woul d be equally useful to wire up your own slice of functionality to see it work for
your own purposes.
91
www.it-ebooks.info
115 CHAPTER 5 BlazeDS remoting and logging
Int roduci ng Bl azeDS
A Flex client typically runs in a web browser or through the AI R desktop application
platform. BlazeDS comes into the technol ogy stack for use when the client needs to
communicate witii a J ava application on the server that is commonl y powered by a
service-oriented architecture (SOA). Figure 5.1 shows di e basic anatomy of a BlazeDS
application framework.
I n a nutshell, BlazeDS is a collection of J ava components that you can depl oy witii
your web application for AMF/ HTTP communication between Flex and J ava. BlazeDS
also supports messaging. BlazeDS is basically a subset of di e commercial Flex Data Ser-
vices offeri ng fr om Adobe, and although you can do many tilings with BlazeDS, cer-
tain functions like clustering and advanced bi ndi ng techniques can only be
accomplished witii the full-blown Flex Data Services.
NOTE I n Adobe's words, BlazeDS is di e server-based J ava remoti ng and
web messaging technol ogy tiiat enables developers to easily connect to
back-end distributed data and push data in real-time to Adobe® Flex® and
Adobe AI R™ applications for more responsive rich I nternet application
(RI A) experiences.
You may be asking, "Why woul d I use BlazeDS instead of web services?" One of the
biggest advantages to using di e AMF protocol for communi cati on is performance.
Adobe's J ames Ward put together a ni ce appl i cati on called Bl azeBench (http:/ / www.
jamesward.com / wordpress/ 2007/ 12/ 12/ blazebench-why-you-want-amf-and-blazeds/ ),
which benchmarks metiiods of communicating to di e server side fr om a web applica-
tion, including Flex, and displays the di fferent aspects of di e transaction. Figure 5.2
shows a sample output fr om BlazeBench.
I t may be difficult to see in di e screenshot, but di e total execution time for an
operati on using Flex AMF3 is by far quicker for round-trip time to di e server, and
F la sh P la ye r o r Ai r P la tform
F le x C lie n t (S WF )
B la ze D S co m p o n e n ts
R e m o te O b je ct
H TTP S e rvi ce /We b S e rvi se
P ro d u ce r/C o n su m e r
Fi gure 5.1 The BlazeDS archi t ect ure
M e ssa g e B ro k e rS e rvle t
M e ssa g e B ro k e r
S e rvi ce
D e stin a tio n
Ad a p te r
www.it-ebooks.info
Getting BlazeDS 93
R<KW WOO * C2lp * E*»cut#
Ajai HTML 5ervef built HTML tabic
A|a>HTML
Aja* SOAP SOAPW HTML tsHe
AjwSOAP
I j uXX.
A| flj J SON
XML to HTML t»bte
J SON to HTML tttte
Ajax J SON
Octo J SON to Dqo FlltcilngTaWe
UHto XML
Flex SOAP AS
Fta SOAPE4X
Ftot XML AS
LwdbXHL
Flex SOAP AS
Fl»»SOAP E4X
XML to grid
SOAP » A5 itjecti
SOAP to 6 « Ot*«ti
UHto XML
Flex SOAP AS
Fta SOAPE4X
Ftot XML AS
Flex XML AS XML to AS CtfKts
Flex xml E4X
Fie* XML E4X XML to E4X ttfKts
Flex AHF3
FlexAMFi
Flex Paged
S«rv*r t««<Tim
O. Omi I D s
• Data Bandwidth
Ajan HTML
Ajax SOAP
Lsuto XML
Flex SOAP AS
Flex SOAPE4X
Flex XML E4X •
Flex AMF3 •
Fi gur e 5 .2 Com par i ng perf ormances of var i ous met hods of t r ansf er r i ng dat a f rom t he ser ver si de t o
t he cl i ent
it has the smallest data bandwi dti i for di e transmission as wel l as the shortest
parse time.
Get t i ng Bl azeDS
You'r e i n l uck i f you are usi ng Maven to bui l d your web appl i cati on. After much
persi stence f r om the devel opment communi ty, tiiere are now BlazeDS J ARs i n the
mai n Maven repository. Add di e dependenci es shown i n listing 5.1 i n your pom. xml
to i ncl ude the Bl azeDS l i brari es i n your appl i cati on and they are downl oaded
f or you.
Li s t i n g 5 . 1 Ad d i n g Bl a ze DS t o yo u r p o m . xm l
<dependenc y>
<gr oupI d>c om. a dobe. bl a zeds</ gr oupI d>
<a r t i f a c t I d>bl a zeds- c or e</ a r t i f a c t l d>
<ver si on>3. 2. 0. 3978</ ver si on>
</ dependenc y>
<dependenc y>
<gr oupI d>c om. a dobe. bl a zeds</ gr oupI d>
<a r t i f a c t I d>bl a zeds- c ommon</ a r t i f a c t l d>
<ver si on>3. 2. 0. 3978</ ver si on>
</ dependenc y>
<dependenc y>
<gr oupI d>c om. a dobe. bl a zeds</ gr oupI d>
<a r t i f a c t I d>bl a zeds- pr oxy</ a r t i f a c t l d>
<ver si on>3. 2. 0. 3978</ ver si on>
</ dependenc y>
www.it-ebooks.info
117 CHAPTER 5 BlazeDS remoting and logging
<dependenc y>
<gr oupI d>c om. a dobe. bl a zeds</ gr oupI d>
<a r t i f a c t I d>bl a zeds- r emot i ng</ a r t i f a c t l d>
<ver si on>3. 2. 0. 3978</ ver si on>
</ dependenc y>
<dependenc y>
<gr oupI d>or g. spr i ngf r a mewor k. f l ex</ gr oupI d>
<a r t i f a c t l d>spr i ng- f l ex</ a r t i f a c t l d>
<ver si on>l . 0. 0. RELEASE</ ver si on>
</ dependenc y>
We've also i ncl uded di e Spri ng- Fl ex arti fact because you'r e goi ng to use this frame-
wor k for communi cati ng wi th server-side desti nati ons. The Spri ng BlazeDS I ntegr ati on
reduces the compl exi ty i n confi gur i ng BlazeDS.
For di ose not usi ng Maven, you have to j u mp
thr ough a coupl e of hoops to get the pr oper
l i brari es i n your appl i cati on. Adobe doesn't pro-
vi de di e J AR fi l es di recdy on the BlazeDS down-
loads page (http:/ / opensource.adobe.com/ wi ki /
di spl ay/ bl azeds/ Rel ease+Bui l ds); it provi des onl y
di e bi nary di stri buti on as a WAR fi l e, a turnkey
sol uti on whi ch contai ns a ready-to-use Tomcat
i nstance wi th sampl e appl i cati ons, and a source
downl oad. The easiest way to get the J AR is to
get di e WAR di stri buti on and extract them out
of the WEB- I NF/ l i b di rectory. Thankful l y every-
thi ng you need to add to your web appl i cati on
is di er e i ncl udi ng all di e dependenci es. Fi gure 5.3
shows the l i brari es contai ned i n the WEB- I NF/
l i b di rectory.
Now l et's get BlazeDS connected up i n a mor e modul ar way wi ti i Maven.
Bui l di ng a Bl azeDS conf i gurat i on Maven modul e
To share confi gur ati on dependenci es between di e J ava
web appl i cati on and di e Fl ex cl i ent you'r e goi ng to cre-
ate a BlazeDS confi gur ati on modul e. The di rectory struc-
ture wi l l l ook l i ke di e one i n fi gur e 5.4. You can create
this modul e at the same l evel as di e f l ex- bu gs- web mod-
ul e and the f l ex- bu gs - r i a modul e.
As you can see di e onl y tiling needed is the resources
di rectory for di e BlazeDS confi gur ati on fi l es and di e
POM descri ptor and a Maven assembly. Remember that
di e pr oj ect structure can be gener ated much as was dem-
onstrated i n chapters 2 and 3. I f you don't gener ate
di em wi th di e Maven archetype you must speci fy i n di e
I n g o n H | © | <H
r r
f tackport-util-com went.jar
2 (fgatevtayadapier.jar
f <ommons-co<lec-1.3.jar
11
(ommons-tittpcl«nt-3.0.1.jar
2 (ommons-logging.jar
J (OiKurrenl.jaf
2 flex-meisaging-tortirrajnjar
g flex-messaging-tore.jar
f flex-messaging-opl.jar
±flex-messagirtg-proxy jar
2 flen-mss sagi ng-remoti ng.jar
2 xalan.jar
Fi gure 5 .3 Bl azeDS l i brari es and
t hei r dependenci es
3 Q flex-bugs
• flex-bugs-blaze-conftg
El src
0 Ù main
assembly
resources
Flex-bugs-ria
j flex-bugs-web
Fi gur e 5 .4 Bl azeDS
conf i gur at i on modul e pr oj ect
st r uct ur e
www.it-ebooks.info
Building a BlazeDS configuration Marien module 95
top- l evel POM (fl ex- bugs) a new modul e, and you must associate di e BlazeDS confi gu-
rati on as a dependency for di e other proj ects.
Next modi fy di e modul e's POM descri ptor file.
Li s t i n g 5 . 2 Bl a ze DS c o n f i g u r a t i o n m o d u l e P OM
<?xml ver si on=" 1. 0" ?>
<pr oj ec t >
<pa r ent >
<a r t i f a c t l d>f l ex- bugs</ a r t i f a c t l d>
<gr oupI d>or g. f oj </ gr oupI d>
<ver si on>l . C) - SNAPSHOT</ ver si on>
</ pa r ent >
<model Ver si on>4. 0. 0</ model Ver si on>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- bl a ze- c onf i g</ a r t i f a c t l d> © Coordi nat es i ndi cat e
<pa c ka gi ng>pom</ pa c ka gi ng> <1—* pack agi ng
<ver si on>l . C) - SNAPSHOT</ ver si on>
<bui l d>
<pl ugi ns>
<pl ugi n>
<gr oupI d>or g. a pa c he. ma ven. pl ugi ns</ gr oupI d>
<a r t i f a c t l d>ma ven- a ssembl y- pl ugi n</ a r t i f a c t l d>
<1—
1 Usi ng Maven
<exec ut i ons> Q assembl y pl ugi n
<exec ut i on>
<i d>Pa c ka ge Bl a zeD S c onf i gur a t i on</ i d>
<goa l s>
<goa l >si ngl e</ goa l >
</ goa l s> © Assembl y happens
<pha se>pa c ka ge</ pha se> <h-T dur i ng package phase
<c onf i gur a t i on>
<desc r i pt or s>
<desc r i pt or >sr c / ma i n/ a ssembl y/ r esour c es. xml </ desc r i pt or >
</ desc r i pt or s>
</ c onf i gur a t i on> Pat h t o assembl y
, . . i nst r uct i ons
</ exec ut i on>
' 1
nbl y I
i ons ©
</ exec ut i ons>
</ pl ugi n>
</ pl ugi ns>
</ bui l d>
</ dependenc i e s >
</ pr oj ec t >
Because you created di i s modul e onl y to share its resources between di e cl i ent and
server modul es you can speci fy di e packagi ng type of pom © and speci fy tiiat you've
chosen to use the maven- assembl y- pl ugi n © to zi p up resources © dur i ng the pack-
age phase ©. Thi s POM basically instructs Maven to col l ect i nto a zi p file the resources
you need to share.
Li sti ng 5.3 shows the contents of di e resources.xml descri ptor file found i n di e
src/ mai n/ assembl y fol der of di e f l ex- bu gs- bl aze- conf i g modul e.
www.it-ebooks.info
9 6 CHAPTER 5 BlazeDS remoting and logging
M a ve n a sse m b ly i n sta ll a n d d e p lo y
T h e M a v e n f ra m e w o rk a u t o m a t i c a l l y i n s t a l l s a n d d e p l o y s a n y t h i n g b u i l t t h ro u g h t h e
c o n t e x t o f a n a s s e m b l y . F o r i n s t a l l a t i o n , M a v e n i n s t a l l s t h e a rt i f a c t (s ) i n t o y o u r
l o c a l re p o s i t o ry l o c a t e d t y p i c a l l y i n t h e . m 2 d i re c t o ry , w h i c h i s u s u a l l y f o u n d i n y o u r
h o m e d i re c t o ry . M a v e n d e p l o y s a rt i f a c t s i f t h e d i s t ri b u t i o n m a n a g e m e n t i s s p e c i -
f i e d w i t h s n a p s h o t o r re l e a s e re p o s i t o ri e s d e f i n e d . F o r d e p l o y m e n t , a v a l i d M a v e n
re p o s i t o ry , l i k e S o n a t y p e ' s o w n Nexus re p o s i t o ry , i s re q u i re d .
Li s t i n g 5 . 3 r e s o u r c e s . x m l
<a ssembl y>
<i d>r esour c es</ i d>
<f or ma t s>
<f or ma t >zi p</ f or ma t >
</ f or ma t s>
<i nc l udeBa seD i r ec t or y>f a l se</ i nc l udeBa seD i r ec t or y>
<f i l eSet s>
<f i l eSet >
<di r ec t or y>sr c / ma i n/ r esour c es«/ di r ec t or y>
<out put D i r ec t or yx/ out put D i r ec t or y>
</ f i l eSet >
</ f i l eSet s>
</ a ssembl y>
J
1>
Assembl y f or m at
To i ncl ude i n assembl y
Thi s assembly instructs Maven to create a zi p fi l e O wi th the fi l es listed i n di e f i l es et
Q . That is wher e you'l l be addi ng our two BlazeDS confi gur ati on fi l es that need to be
shared across modul es.
5.3.1 Configuring BlazeDS
BlazeDS uses a coupl e of key confi gur ati on fi l es that by conventi on are put i n a fl ex
fol der under WEB-INF. You coul d put them wher ever you like, but by pl aci ng di em
under di e WEB-INF fol der, you make di em accessible onl y to your web appl i cati on,
and you can feel safe knowi ng any sensitive i nfor mati on, such as passwords i n your
proxy- confi g.xml , are safe f r om pr yi ng eyes.
The first fi l e we'l l l ook at is servi ces- confi g.xml .
Li s t i n g 5 . 4 s e r v i c e s -c o n f i g . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<ser vi c es- c onf i g>
<ser vi c es>
<ser vi c e- i nc l ude f i l e- pa t h=" pr oxy- c onf i g. xml " / >
<def a ul t - c ha nnel s>
<c ha nnel r ef =" my- a mf " / >
</ def a ul t - c ha nnel s>
J
I m por t t he
pr oxy-conf i g.xm l
</ ser vi c es>
www.it-ebooks.info
Building a BlazeDS configuration Marien module 97
<c ha nnel s> O Channel def i ni t i on
<c ha nnel - def i ni t i on i d=" my- a mf " c l a ss=" mx. messa gi ng. c ha nnel s. AMFCha nnel " >
<endpoi nt
ur l =" ht t p: / / {ser ver . na me}: {ser ver . por t }/ messa gebr oker / a mf "
c l a ss=" f l ex. messa gi ng. endpoi nt s. AMFEndpoi nt " / >
</ c ha nnel - def i ni t i on>
E n d
P
o i n t Ur l wi t h
pr oper t y names
</ c ha nnel s>
</ ser vi c es- c onf i g>
S O
Thi s is how the basic servi ces- confi g.xml fi l e shoul d l ook for BlazeDS. Ther e are a cou-
pl e of secti ons to note her e. First you tel l the servi ces- confi g.xml fi l e to i mpor t di e
pr oxy- confi g. xml O and wher e to fi nd it. Next i n di e channel s defi ni ti on Q you
defi ne an AMF channel and poi nt it at a servl et tiiat you'l l defi ne i n di e web. xml later.
I t's also possi bl e to use pr oper ti es for the channel defi ni ti on that transform i nto
thei r real values when di e appl i cati on starts. I t's common to do tiiis for the endpoi nt
u r l attri bute Usi ng the {ser ver . name} and {s er ver . por t } properti es allows the
appl i cati on to be por ted wi ti i out havi ng to hard code di ffer ent static values each time it
needs to be depl oyed i n a di ffer ent envi r onment. Refer to di e BlazeDS documentati on
at http:/ / opensour ce. adobe. com/ wi ki / di spl ay/ bl azeds/ Devel oper +Documentati on i f
you need mor e i nfor mati on on how to tweak the confi gur ati on.
F la sh P la ye r S e c u ri ty a n d R P C
Wh e n e v e r y o u a t t e m p t t o re c e i v e d a t a f ro m a re m o t e s e rv i c e , F l a s h P l a y e r c h e c k s
t h e d o m a i n n a m e o f t h e re m o t e s e rv i c e l o c a t i o n a n d c o m p a re s i t t o t h e d o m a i n
n a m e o f y o u r F l e x a p p l i c a t i o n ' s l o c a t i o n . I f t h e t w o d o n o t m a t c h , t h e d a t a c a n n o t
b e l o a d e d f ro m t h e re m o t e s e rv i c e . T h e e a s i e s t w a y t o re m e d y t h i s s i t u a t i o n i s t o
h o s t y o u r F l e x a p p l i c a t i o n o n t h e s a m e d o m a i n a s y o u r re m o t e s e rv i c e s . I f t h i s i s
n o t p o s s i b l e y o u h a v e a f e w o p t i o n s . Y o u c a n c re a t e a c ro s s d o m a i n . x m l f i le t o a l l o w
F l a s h a p p l i c a t i o n s o u t s i d e o f y o u r d o m a i n t o u s e t h e re m o t e s e rv i c e s . Y o u c a n c re -
a t e a s e rv l e t i n y o u r w e b a p p l i c a t i o n t o a c t a s a p ro x y f o r t h e F l a s h a p p l i c a t i o n , o r
y o u c a n c o n f i g u re B l a z e D S t o d o t h i s b y u s i n g t h e p ro x y -c o n f i g . x m l .
Th e last confi gur ati on fi l e we'l l exami ne f or now is pr oxy- confi g. xml .
Li s t i n g 5 . 5 p r o x y -c o n f i g . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<ser vi c e i d=" pr oxy- ser vi c e"
c l a ss=" f l ex. messa gi ng. ser vi c es. HTTPPr oxySer vi c e" >
<pr oper t i es>
<c onnec t i on- ma na ger >
<ma x- t ot a l - c onnec t i ons>100</ ma x- t ot a l - c onnec t i ons>
<def a ul t - ma x- c onnec t i ons- per - host >2</ def a ul t - ma x- c onnec t i ons- per - host >
</ c onnec t i on- ma na ger >
www.it-ebooks.info
121 CHAPTER 5 BlazeDS remoting and logging
<a l l ow- l a x- ssl >t r ue</ a l l ow- l a x- ssl >
</ pr oper t i es>
<a da pt er s>
<a da pt er - def i ni t i on i d="ht t p- pr oxy"
c l a ss="f l ex. messa gi ng. ser vi c es. ht t p. HTTPPr oxyAda pt er "
def a ul t ="t r ue"/ >
<a da pt er - def i ni t i on i d="soa p- pr oxy"
c l a ss="f l ex. messa gi ng. ser vi c es. ht t p. SOAPPr oxyAda pt er "/ >
</ a da pt er s>
<def a ul t - c ha nnel s>
<c ha nnel r ef ="my- a mf "/ >
</ def a ul t - c ha nnel s>
<dest i na t i on i d="Def a ul t HTTP">
</ dest i na t i on>
</ ser vi c e>
I n tlie proxy-config.xml fi l e you can confi gure any server-side proxies you need to
leverage, if, for instance, you're communicating with web services outside your
domai n and have no control over placing a crossdomain.xml fi l e on di e server.
Wi di BlazeDS confi gured and ready to go, you can now get on with di e tasks of
modi fyi ng some of your services to communicate via AMF.
Wh e re 's th e re m o ti n g -co n fi g . xm l?
G re a t q u e s t i o n ! T h e B l a ze D S e x a m p l e s i n t h i s b o o k t a k e a d v a n t a g e o f a b ra n d n e w
S p ri n g B l a ze D S I n t e g ra t i o n f ra m e wo rk b ro u g h t t o u s b y S p ri n g S o u rc e . S p ri n g
B l a ze D S I n t e g ra t i o n a l l o w s y o u t o s e t u p re m o t i n g d e s t i n a t i o n s b y a n n o t a t i n g a
J a v a c l a s s a n d s p e c i f i c m e t h o d s t h a t n e e d t o b e e x p o s e d t o F le x t h ro u g h re m o t i n g .
Yo u c a n sti ll c h o o s e t o h a n d -wi re t h e X M L i n s t e a d o f u s i n g t h e a n n o t a t i o n s b u t w e
re c o m m e n d t h e u s e o f t h e S p ri n g B l a ze D S I n t e g ra t i o n a n n o t a t i o n s a n d wi ll d e m o n -
s t ra t e t h e m i n t h i s c h a p t e r.
Vi s i t t h e B l a ze D S d e v e l o p e r d o c u m e n t a t i o n i f y o u r p ro j e c t re q u i re s t h e re m o t i n g -
c o n f i g . x m l a t h t t p : / / o p e n s o u rc e . a d o b e . c o m / w i k i / d i s p l a y / b l a z e d s / D e v e l o p e r+
D o c u m e n t a t i o n
I n di e next sections we're goi ng to start off simple by showing you how to connect to a
POJ O on the server side and get more complicated and leverage di e powerful Spring
Framework to communicate with a fully i nj ected Spring bean.
ADD THE BLAZEDS CONFIG MODULE TO THE TOP-LEVEL P OM
To confi gure di e top-level POM, open and edit di e pom.xml fi l e in di e flex-bugs direc-
tory and add di e f l ex- bugs- bl aze- conf i g modul e.
Li st i ng 5 . 6 Ad d i n g Bl a zeDS con f i g m odul e t o t h e t op-l evel p om . xm l
<modul es>
<modul e>f l ex- bugs- bl a ze- c onf i g</ modul e>
www.it-ebooks.info
Building a BlazeDS configuration Marien module 99
<modul e>f l ex- bugs- r i a </ modul e>
<modul e>f l ex- bugs- web</ modul e>
</ modul es>
Next associate the dependency wi th di e f l ex- bu gs- web modul e and f l ex- bu gs -
r i a modul e.
UPDATE THE FLEX AND JAVA WEB MODULES
Now you can add di e confi gurati on modul e to di e oti i er proj ects as a dependency by
edi ti ng thei r respecti ve POM fi l es for the fl ex- bugs- web/ pom.xml .
Li s t i n g 5 . 7 Ad d i n g t h e Bl a ze DS c o n f i g d e p e n d e n c y t o t h e Ja va w e b m o d u l e
<dependenc i es>
<dependenc y>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- bl a ze- c onf i g</ a r t i f a c t l d>
<ver si on>l . C) - SNAPSHOT</ ver si on>
<c l a ssi f i er >r esour c es</ c l a ssi f i er >
<sc ope>pr ovi ded</ sc ope>
<t ype>zi p</ t ype> <
</ dependenc y>
1
r
BlazeDS conf i gur at i on
modul e dependency
decl arat i on
Use resources cl assi f i er
and pr ovi ded scope
</ dependenc i es>
Type el ement is t ype
of art i f act pr oduced
by assembl y
As you can see, you add di e new dependency to di e dependenci es el ement © i n
each modul e's pom and you are done. Because di e scope is pr ovi ded, it wi l l not add
the resources © to the WAR. You had to speci fy the type © because it's a zi p and
not di e defaul t type. You'l l be getti ng them f r om the Fl ex modul e by edi ti ng di e
POM descri ptor i n di e f l ex- bu gs - r i a modul e.
Li s t i n g 5 . 8 Ad d i n g t h e Bl a ze DS c o n f i g d e p e n d e n c y t o t h e Fl e x m o d u l e
1,
Maven-dependency-
pl ugi n def i ni t i on
Invok e unpack -
dependenci es goal
J
Execut e goal dur i ng
gener at e-r esour ces phase
<pl ugi n>
<gr oupI d>or g. a pa c he. ma ven. pl ugi ns</ gr oupI d>
<a r t i f a c t l d>ma ven- dependenc y- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>unpa c k- c onf i g</ i d>
<goa l s>
<goa l >unpa c k- dependenc i es</ goa l > <
</ goa l s>
<pha se>gener a t e- r esour c es- ; / pha se>
<c onf i gur a t i on>
<out put D i r ec t or y>${pr oj ec t . bui l d. di r ec t or y}/
gener a t ed- r esour c es- ; / out put D i r ec t or y>
<i nc l udeAr t i f a c t l ds>f l ex- bugs- bl a ze- c onf i g</ i nc l udeAr t i f a c t l ds>
<i nc l udeGr oupI ds>${pr oj ec t . gr oupI d}</ i nc l udeGr oupI ds>
<exc l udeTr a nsi t i ve>t r ue</ exc l udeTr a nsi t i ve>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
r
Out put di r ect or y
t o unpack zi p f i l e
Incl ude f l ex-bugs-
bl aze-conf i g art i f act
www.it-ebooks.info
1 0 0 CHAPTER 5 BlazeDS remoting and logging
Ther e are many ways to share confi gurati ons, and as you see, you can use the maven-
dependency- pl ugi n ©. You execute the unpack- dependenci es goal © duri ng di e
gener at e- r esou r ces phase © and must choose an output di rectory © i n or der to
unzi p di e fi l e wher e you want. You may have noti ced that you used di e built-in maven
pr oper ty $ {pr oj ect . bu i l d, di r ec t or y}, whi ch equates to di e l ocati on of the target
di rectory. Now you must i ndi cate what to unpack. Thi s is wher e you speci fy di e f l ex-
bu gs- bl aze- conf i g arti fact ©.
After the confi gur ati on is compl eted for di e shared confi gur ati on approach, you
can start i ntegrati ng Fl ex wi th J ava thr ough the use of BlazeDS AMF r emoti ng!
5.4 Exposi ng Java servi ces t o Fl ex remot i ng
I n this secti on you'l l demonstrate how to confi gur e and expose J ava services to Fl ex
thr ough the use of BlazeDS and Spri ng annotati ons. First you'l l modi fy di e web mod-
ul e confi gurati on, then modi fy di e J ava code. For demonstr ati on purposes you'l l use
the Fl exBugs sampl e appl i cati on.
5.4.1 Web module configuration updates
First you'l l modi fy di e f l ex- bu gs- web modul e's confi gur ati on to enabl e it for remot-
i ng. You'l l start wi th the appl i cati onContext. xml fi l e l ocated i n di e / fl ex- bugs- web/
src/ mai n/ webapp/ WEB- I NF di rectory.
Li s t i n g 5 . 9 Ap p l i c a t i o n Co n t e x t . x m l
<?xml ver si on="1. 0" enc odi ng="UTF- 8 " ?> Updat e schema namespace A
<bea ns xml ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns" <1—'
xml ns: sec ur i t y=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y"
xml ns : xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xml ns: c ont ext =" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / c ont ext "
xsi : sc hema Loc a t i on="
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns/ spr i ng- bea ns- 2. 5. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y/ spr i ng- sec ur i t y-
2. 0. 4. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / c ont ext
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / c ont ext / spr i ng- c ont ext -
2. 5. xsd"
def a ul t - l a zy- i ni t =
11
t r ue
11
> © Enabl e annot at i ons
<c ont ext : a nnot a t i on- c onf i g / > <_l © Usecom ponent
<c ont ext : c omponent - sc a n ba se- pa c ka ge=" or g. f oj " / > <—I scanner
<! - - Add new D AOs her e - - >
<bea n i d=" i ssueD a o" c l a ss=" or g. a ppf use. da o. hi ber na t e. Gener i c D a oHi ber na t e" >
<c onst r uc t or - a r g va l ue=" or g. f oj . model . I ssue" / >
<pr oper t y na me=" sessi onFa c t or y" r ef =" sessi onFa c t or y" / >
</ bea n>
<bea n i d=" c omment D a o" c l a ss=" or g. f oj . da o. i mpl . Comment D a oI mpl " >
<pr oper t y na me=" sessi onFa c t or y" r ef =" sessi onFa c t or y" / >
</ bea n>
www.it-ebooks.info
Exposingjava services to Flex remoting 1 0 1
<! — Add new Ma na ger s her e - - >
<bea n i d=" i ssueSer vi c e" c l a ss=" or g. f oj . ser vi c e. i mpl . I ssueMa na ger l mpl " >
<c onst r uc t or - a r g r ef =" i ssueD a o" / >
<c onst r uc t or - a r g r ef =" c omment Ser vi c e" / >
</ bea n>
<bea n i d=" c omment Ser vi c e" c l a ss=" or g. f oj . ser vi c e. i mpl . Comment Ma na ger l mpl " >
<c onst r uc t or - a r g r ef =" c omment D a o" / >
</ bea n>
<! — Add new Ac t i ons her e - - >
</ bea ns>
To take advantage of the Spri ng BlazeDS I ntegrati on you must add di e appr opr i ate
schema changes and namespace el ements O - Because you'l l be usi ng annotati ons to
expose your services to BlazeDS r emoti ng destinations, you must enabl e annotati ons
© and use the component scanner © to hel p Spri ng fi nd the annotati ons you'r e
goi ng to defi ne.
Next, by conventi on, you must create a fl ex- spri ng- servl et.xml confi gur ati on fi l e, as
seen i n listing 5.10, because the fr amewor k depends on it.
NOTE The nami ng of di e fl ex- spri ng- servl et.xml fi l e is i mpor tant because di e
fr amewor k scans for it by conventi on, and di e appl i cati on wi l l fai l to start up
pr oper l y wi thout it.
Later, you'l l use the fl ex- spri ng- servl et.xml fi l e to hel p confi gur e the messagi ng service.
Li s t i n g 5 . 1 0 f l e x -s p r i n g -s e r v l e t . x m l p l u m b i n g
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<bea ns xml ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns"
xml ns: f l ex=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on="
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns/ spr i ng- bea ns- 2. 5. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex/ spr i ng- f l ex- 1. 0. xsd" >
</ bea ns>
Last, you need to add a new servl et defi ni ti on to the web. xml so that your Fl ex appl i ca-
ti on can communi cate wi th the server-side appl i cati on. Li sti ng 5.11 shows the changes
that need to be made to di e web. xml of our web appl i cati on modul e.
Li s t i n g 5 . 1 1 w e b . x m l
<ser vl et >
<ser vl et - na me>f l ex- spr i ng</ ser vl et - na me> <—© Servl et name
<ser vi et - c l a ss>
or g. spr i ngf r a mewor k. web. ser vl et . D i spa t c her Ser vl et <1—,
</ ser vi et - c l a ss> Q Servl et class
<l oa d- on- st a r t up>l </ l oa d- on- st a r t up>
</ ser vl et >
www.it-ebooks.info
102 CHAPTER 5 BlazeDS remoting and logging
<ser vi et - ma ppi ng>
<ser vi et - na me>f l ex- spr i ng</ ser vi et - na me>
<ur l - pa t t er n>/ messa gebr oker / *</ ur l - pa t t er n> A defi ni ti on
</ ser vl et - ma ppi ng>
Servl et mappi ng
Thi s is a typical J ava web appl i cati on servl et mappi ng wher e you defi ne a servlet name O
and a servl et class Q to di spatch acti ons to whenever a URL pattern © match is found.
Now l et's begi n wor ki ng wi ti i code by modi fyi ng the server-side classes.
5.4.2 Expose AMF remoting destinations
Connecti ng to POJ Os on the server side is trivial after you've got BlazeDS confi gur ed
properl y. To illustrate connecti ng to a POJ O f r om Fl ex, we'r e goi ng to use the Fl ex-
Bugs appl i cati on by exposi ng the I ssueManager i nter face to Fl ex r emoti ng usi ng the
Spri ng BlazeDS I ntegr ati on fr amewor k.
UPDATES TO ISSUE CODE
Thi s is the code for di e I ssueManager I mpl that we'l l be connecti ng to.
Li s t i n g 5 . 1 2 I s s u e M a n a g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . I ssue;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngD est i na t i on; <
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngl nc l ude;
i mpor t j a va x. j ws . WebSer vi c e; I m por t Spri ng BlazeDS __
I nt egr at i on classes O
@WebSer vi c e
Remot i ngDest i nat i on exposes
© i ssueServi ce t o Fl ex remot i ng
à
Remot el ncl ude
annot at i on
@Remot i ngD est i na t i on( c ha nnel s = {" my- a mf " })
publ i c i nt er f a c e I ssueMa na ger {
@Remot i ngI nc l ude
j a va . ut i l . Li st <I ssue> get AHO;
@Remot i ngI nc l ude
I ssue get ( Long i d) ;
@Remot i ngI nc l ude
I ssue sa ve( I ssue i ssue) ;
@Remot i ngI nc l ude
voi d r emove( Long i d) ;
As you can see, not much had to change to expose di e I ssu eSer vi ce meti i ods to
Fl ex. The fi rst step was to i mpor t di e Spri ng BlazeDS I ntegrati on classes needed Q .
The Spri ng classes hel p by suppl yi ng di e ©Remot i ngDest i nat i on and ©Remoti ng-
l ncl ude annotati ons.
Next, you added the ©Remot i ngDest i nat i on "my- amf' The ©Remoti ng-
Dest i nat i on must match di e one defi ned i n di e servi ces- confi g.xml BlazeDS confi gu-
rati on fi l e. Thi s annotati on exposes this class as a desti nati on for any J ava class that
i mpl ements di e I ssueManager i nterface. Thi s means tiiat the I ssueManager I mpl J ava
www.it-ebooks.info
Exposingjava services to Flex remoting 1 0 3
class, the class that i mpl ements the I ssueManager, wi l l be exposed as an AMF r emote
servi ce and not j ust XML/ HTTP.
The Spri ng BlazeDS I ntegr ati on fr amewor k r emoved the need for havi ng to defi ne
this metadata thr ough the r emoti ng- confi g. xml confi gur ati on fi l e. You don't use a
r emoti ng- confi g. xml fi l e wi th the BlazeDS I ntegrati on fr amewor k.
You can now annotate each method tiiat you need to expose wi th di e ORemot i ng-
I nc l ude Q annotati on and you are done! The @Remo t i ng I nc l ude annotati on exposes
the method over di e ©Remot i ngD es t i na t i on.
I f needed, di e Spri ng BlazeDS I ntegrati on fr amewor k's r emoti ng package also
provi des a ORemot i ngExc l ude annotati on for i ntenti onal l y excl udi ng methods. Now
l et's move on to maki ng changes to di e Fl ex cl i ent to take advantage of di e exposed
AMF servi ce.
UPDATES TO COMMENTS CODE
Now that you have everyti i i ng i n pl ace for the issue code, you'l l need to make the same
types of changes to di e Comment Ma na ger i nterface. The fol l owi ng listing shows the
Comment Ma na ger . j a va class changes.
Li s t i n g 5 . 1 3 Co m m e n t M a n a g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . Comment ;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngD est i na t i on;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngl nc l ude;
i mpor t j a va x. j ws. WebSer vi c e;
i mpor t j a va . ut i l . Li st ;
@WebSer vi c e
@Remot i ngD est i na t i on( c ha nnel s = {" my- a mf " })
publ i c i nt er f a c e Comment Ma na ger {
@Remot i ngI nc l ude
Li st <Comment > f i ndComment sByl ssuel d( Long i ssuel d) ;
@Remot i ngI nc l ude
voi d del et eAHComment sFor l ssuel d( Long i ssuel d) ;
@Remot i ngI nc l ude
Comment get ( Long i d) ;
@Remot i ngI nc l ude
Comment sa ve( Comment c omment ) ;
@Remot i ngI nc l ude
voi d r emove( Long i d) ;
As you can see you di dn't need to change any of the appl i cati on code to expose di e
Comment Ma na ger to r emoti ng. Al l you had to do was add di e necessary i mports,
i ncl ude di e ©Remot i ngD es t i na t i on, and add di e appr opr i ate ©Remot i ngl nc l ude
annotati ons for the methods you need exposed.
www.it-ebooks.info
1 0 4 CHAPTER 5 BlazeDS remoting and logging
Now you have a J ava server side tiiat is set up for BlazeDS r emoti ng. You tackl ed
much of the J ava confi gur ati on thr ough Spri ng's robust Fl ex BlazeDS I ntegr ati on
fr amewor k and its extr emel y useful annotati ons.
5.5 Connect i ng t o Java wi t h Bl azeDS
Wi th the J ava r emoti ng services ready to go you can begi n di e wor k on the Fl ex cli-
ent to connect to the exposed servi ce obj ects and meti i ods. Let's start wi th di e
I ssue obj ect.
Li s t i n g 5 . 1 4 I s s u e . a s
pa c ka ge or g. f oj . dt o {
[ Remot eCl a ss( a l i a s=" or g. f oj . model . I ssue" ) ]
publ i c c l a ss I ssue {
That wasn't compl i cated. You onl y had to associate this obj ect wi th the server side
equi val ent by usi ng di e RemoteCl ass annotati on © whi ch you need because it allows
you to map domai n obj ects between Fl ex and J ava by speci fyi ng the J ava package and
class name.
TI P Wi thout correctl y speci fyi ng di e RemoteCl ass, any attempts at persi sti ng
I ssue obj ects wi l l fai l because BlazeDS wi l l not know what server-side obj ect
di e Fl ex obj ect is bound to.
Next you need to modi fy the I ssueModel class to call di e POJ O.
Li s t i n g 5 . 1 5 I s s u e M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . I Responder ;
i mpor t mx. r pc . event s. Fa ul t Event ;
i mpor t mx. r pc . event s. Resul t Event ;
i mpor t mx. r pc . r emot i ng. Remot eObj ec t ;
i mpor t or g. f oj . dt o. I ssue ;
publ i c c l a ss I ssueModel {
pr i va t e va r _i ssueSer vi c e: Remot eObj ec t ;
publ i c f unc t i on I ssueModel ( ) {
_i ssueSer vi c e = new Remot eObj ec t ( ) ;
_i ssueSer vi c e. dest i na t i on = " i ssueSer vi c e" ;
}
publ i c f unc t i on get l ssues( r esponder : I Responder ) : voi d {
va r a sync Token: Async Token = _i ssueSer vi c e. get Al l ( ) ;
a sync Token. a ddResponder ( r esponder ) ;
}
A Remot eClass
< 1 _ J annot at i on
^ C y Creat e Remot eObj ect
^ ^ p Set dest i nat i on
}
www.it-ebooks.info
Logging 1 0 5
Agai n a few ti l i ngs have to change, and yet onl y mi nor ones are r equi r ed to take advan-
tage of the per for mance increases of BlazeDS r emoti ng. I n di e I ssueModel you are now
usi ng di e Fl ex Remot eObj ec t O for communi cati on to di e i ssueSer vi c e i nstead of the
WebSer vi c e obj ect. When you construct a new I ssueModel you set di e Remot eObj ec t
desti nati on © as di e i ssueSer vi c e you defi ned earl i er i n our appl i cati onConfi g. xml .
That's it. Real l y!
NOTE Names of the Remot eObj ec t i nstance vari abl es map to di e bean name
i n di e Spri ng appl i cati onContext. xml fi l e. Be sure these names are correct!
Wi th all of di at out of the way you shoul d be abl e to run your appl i cati on and see tiiat
it's now popul ati ng the D a t a Gr i d wi th data f r om our i ssueSer vi c e thr ough BlazeDS
rather than the web services you created i n chapter 4.
5.6 Loggi ng
Si nce the i ncepti on of pr ogr ammi ng, devel oper s have always found ways to enabl e
appl i cati ons to communi cate what they are doi ng. Thi s comes i n all di ffer ent forms,
f r om l oggi ng basic i nfor mati on to fatal excepti ons duri ng the appl i cati on runti me.
Wi th di e Fl exBugs sampl e appl i cati on, you need to l og the J ava server-side events and
the Bl azeDS-speci fi c events, and gather per for mance statistics.
Bui l di ng the Fl exBugs appl i cati on wi th AppFuse si mpl i fi ed this task by confi gur i ng
the popul ar l og4j fr amewor k for l oggi ng J ava appl i cati on messages. Now you must
i nfor m the l og4j fr amewor k that you want to l og even mor e for BlazeDS.
5.6.1 BlazeDS logging
Addi ng BlazeDS i nto the mi x was benefi ci al . But addi ng any l i brary or fr amewor k to
benefi t di e appl i cati on presents new chal l enges; you must col l ect i nfor mati on f r om
the l i brary to better understand what is happeni ng when you use it.
Thankful l y, Spri ngSource r ecogni zed tiiis wi th the Spri ng BlazeDS I ntegr ati on
fr amewor k and added a new l oggi ng obj ect to its cor e package. The CommonsLoggi ng-
Ta r get class allows for automati c l oggi ng of events f r om BlazeDS i nto the appl i cati on's
exi sti ng l oggi ng confi gur ati on.
CONFI GURE LOG4 J FOR BLAZEDS FILE LOGGING
You have to confi gur e an appl i cati on to pri nt messages to the consol e or even a l og
fi l e i n a coupl e of places. The fi rst pl ace, as seen i n listing 5.16, is the l og4j . xml confi g-
urati on fi l e found i n di e f l ex- bugs- web modul e, whi ch can be found i n the fl ex-bugs-
web/ src/ mai n/ resources di rectory.
Li s t i n g 5 . 1 6 l o g 4 j . xm l
<a ppender na me=" FI LE" c l a ss=" or g. a pa c he. l og4j . Rol l i ngFi l eAppender " > <1—
<pa r a m na me=" Fi l e" va l ue=" f l exbugs. l og" / >
< I
—| l og4j
<l a yout c l a ss=" or g. a pa c he. l og4j . Pa t t er nLa yout " > <1—i Log f i l e 1 r ol l i ng f i l e
Log f i l e l ayout def i ni t i on Q name © appender O
www.it-ebooks.info
1 0 6 CHAPTER 5 BlazeDS remoting and logging
<pa r a m na me=" Conver si onPa t t er n"
va l ue=" %d [ f l ex- bugs- web] %p [ %t ] %c {l }. %M( %L) | %m%n" / > <—i
</ l a yout > Conver si onPat t er n I
</ a ppender > conf i gur at i on O
<a ppender na me=" CONSOLE" c l a ss=" or g. a pa c he. l og4j . Consol eAppender " > <1—i
<l a yout c l a ss=" or g. a pa c he. l og4j . Pa t t er nLa yout " > Consol eAppender 1
<pa r a m na me=" Conver si onPa t t er n" conf i guat i on w
va l ue=" %d [ f l ex- bugs- web] %p [ %t ] %c {l }. %M( %L) | %m%n" / >
</ l a yout >
</ a ppender > A bl azeds l ogger
<l ogger na me=" f l exbugs" > <—I def i ni t i on A | _0ggj ng | eVel
<l evel va l ue="DEBUG" / > <1- J
<a ppender - r ef r ef =" FI LE" / >
<1—
L
<a ppender - r ef r ef =" CONSOLE" / > < —, © Fi l e appender
</ l ogger > Q Consol e appender
As seen i n listing 5.16 tl i e l og4j confi gur ati on can be trivial and yet extremel y robust.
Log4j itself allows for outputti ng to boti i di e consol e and to a fi l e. I n di e exampl e you
speci fi ed a Rol l i ngFi l eAppender © so you can keep l og messages and conti nue to
add to that fi l e as you use di e appl i cati on.
You must speci fy di e l og fi l e name as fl exbugs. l og ©. Log4j requi res the fi l e
par ameter and doesn't pr ovi de a defaul t. I t's also possi bl e to speci fy a pati i to di e
fi l e i n di i s parameter. I t wi l l pl ace di e flexbugs.log file at the r oot of di e flex-bugs-
web di rectory.
L og4j also enabl es vari ous l ayout styles. By choosi ng to use di e Pa t t er nLa yout ©
you can speci fy what you want your messages to l ook l i ke and what i nfor mati on shoul d
be i n the l og message. You do this by defi ni ng di e Conver si onPa t t er n par ameter ©.
Ther e are oti i er patterns to choose f r om but we chose this one to gi ve us addi ti onal
flexibility. The first tiling to noti ce about the l og message pattern is that it wi l l pr efi x
each message wi ti i [ f l ex- bugs- web] . I t then assigns other parameters for pri nti ng the
message. For mor e on l og4j confi gur ati on go tdi ttp:/ / www.scri bd.com/ doc/ 7679107/
Log4j - Qui ck- Refer ence.
You also i ncl ude an appender for di e consol e ©. Consol e appendi ng is especi al l y
hel pful dur i ng software devel opment. Wr i ti ng the l ogs to a file is val uabl e not j ust for
devel opment but also for pr oducti on envi ronments.
Fi nal l y you need to create di e l ogger itself. Her e you created a l ogger named
bl a zeds ©. You confi gur e di e l ogger to output at di e D EBUG l evel © and append the
messages to both our Rol l i ngFi l eAppender and di e Consol eAppender by tiieir
respecti ve r efer ence names FI LE © and CONSOLE ©. L og4j is ready to create a l og file
for your appl i cati on.
CONFI GURE BLAZEDS TO OUTPUT TO LOG4 J
Setti ng up the l oggi ng of BlazeDS is a two-step process. Now that you have a l og-
ger avai l abl e speci fi cal l y for BlazeDS you can confi gur e BlazeDS to wor k wi th l og4j .
Li sti ng 5.17 shows the necessary changes to di e servi ces- confi g.xml file, l ocated i n
di e di rectory.
www.it-ebooks.info
Logging 1 0 7
Li st i n g 5 . 1 7 ser vi ces-co n f i g. xm l
<l oggi ng>
<t a r get c l a ss="or g. spr i ngf r a mewor k. f l ex. c or e. CommonsLoggi ngTa r get "
l evel ="Al l ">
<pr oper t i es>
<c a t egor yPr ef i x>f l exbugs</ c a t egor yPr ef i x>
</ pr oper t i es>
</ t a r get >
</ l oggi ng>
J Cat egory pref i x
Logging
level
Logger
class , O
The BlazeDS confi gurati on is simple. You specify the Spring framework's Commons-
Loggi ngTar get class O , the l oggi ng level you desire Q, and di e categor yPr ef i x
which points to the l og4j .xml l ogger named f l exbugs ©. The CommonsLoggingTarget
can be confi gured to output mor e—or less—information fr om BlazeDS events through
its properties and l oggi ng categories by using filters.
B la ze D S / L C D S lo g g i n g c a te g o ri e s
S e v e ra l c a t e g o ri e s a re a va i la b le fo r h e lp i n g t o fi lt e r o u t s p e c i f i c l o g g i n g m e s s a g e s .
L o g g i n g c a n b e p e rf o rm a n c e -i n t e n s i v e so i t 's w i s e t o lo g o n ly w h a t y o u a b s o l u t e l y
n e e d t o p ro vi d e t h e b e s t s u p p o rt fo r t h e a p p l i c a t i o n . F o r m o re o n t h e c a t e g o ri e s
a v a i la b le o r t o k n o w w h a t y o u c a n fi lt e r o u t o f t h e lo g s , s e e t h e A P I d o c u m e n t a t i o n
fo r t h e CommonsLoggi ngTa r get a t h t t p : / / s t a t i c . s p ri n g s o u rc e . o rg / s p ri n g -f l e x / d o c s /
l . O . x / j a v a d o c -a p i / o rg / s p ri n g f ra m e w o rk / f l e x / c o re / C o m m o n s L o g g i n g T a rg e t . h t m l .
Now diat l oggi ng has been confi gured for BlazeDS it's time to see di e results.
VI EW THE FLEXBUGS LOG FILE
I f you fi re up your sample application you'l l fi nd a l og fi l e available. I f you're using di e
FlexBugs samples and run di e command mvn cl ean j etty: r un- war on di e f l ex-
bugs-web modul e, after performi ng an mvn cl ean i n s t al l on di e f l ex- bugs- conf i g
modul e, you'l l fi nd the l og fi l e in di e flex-bugs-web directory.
Figure 5.5 shows di e l oggi ng messages goi ng to di e console.
Toward di e bottom of fi gure 5.5 you'l l fi nd an AMF l og event showing an issue com-
pl eted for addi ng di e BlazeDS l oggi ng to di e log4j configuration. I n that event you can
see that the issue was serialized through AMF/ HTTP with all the issue details. I f you
open the l og fi l e you'l l fi nd di e same results and l oggi ng of di e BlazeDS events.
5.6.2 Built-in BlazeDS benchmarking
One ni ce feature of BlazeDS is its built-in ability to acquire performance results on
its processing of messages. I n tiiis exampl e you'l l confi gure the BlazeDS services-
confi g.xml to retrieve the message times and size. These measurements are great for
devel opment but shouldn't be enabled for producti on because they cause perfor-
mance degradation. This may seem counterproductive but it's not. It's good to assure
www.it-ebooks.info
131 CHAPTER 5 BlazeDS remoting and logging
Fi gure 5.5 Consol e l og of Bl azeDS event s
that you have the best performance possible for your producti on environments at all
times to keep the users delighted.
To enable BlazeDS performance collection, open up the services-config.xml for
editing. Listing 5.18 shows the changes to the my-amf configuration.
L o g g i n g a ffe cts p e rfo rm a n ce
A d e v e l o p e r m u s t c h o o s e w i s e l y t h e m e s s a g e s t h a t a re l o g g e d i n a p ro d u c t i o n e n vi -
ro n m e n t . Yo u s h o u l d n 't k e e p lo g m e s s a g e s i n a n a p p l i c a t i o n t h a t w e re o n ly tro u -
b l e s h o o t i n g m e s s a g e s o r s lo p p y i n lo o p c o u n t l o g g i n g t h a t s p i t s o u t a b u n c h o f
u n i m p o rt a n t t h i n g s fo r e v e ry e l e m e n t i n a c o l l e c t i o n o f o b j e c t s . T o p u t i t s i m p ly,
lo g g i n g a f f e c t s p e rf o rm a n c e , e s p e c i a l l y w h e n w ri t i n g o u t t o fi le 1 0 . M a k e s u re t h a t
d e b u g g i n g i s n o t e n a b le d i n p ro d u c t i o n u n l e s s i t 's a b s o l u t e l y n e c e s s a ry . A l s o b e
s u re t o o n ly lo g I N F O t y p e m e s s a g e s w h e n t h e y a re h e lp fu l o r re q u i re d .
www.it-ebooks.info
Logging 1 0 9
L i s t i n g 5 . 1 8 s e r v i c e s - c o n f i g . x m l
<c ha nnel - def i ni t i on i d=" my- a mf " c l a s s =" mx. mes s a gi ng. c ha nnel s . AMFCha nnel " >
<endpoi nt ur l =" ht t p: / / {s er ver . na me}: {s er ver . por t }/
{c ont ext . r oot }/ mes s a gebr oker / a mf "
c l a s s =" f l ex. mes s a gi ng. endpoi nt s . AMFEndpoi nt " / >
<pr oper t i es >
<r ec or d- mes s a ge- t i mes >t r ue</ r ec or d- mes s a ge- t i mes >
<r ec or d- mes s a ge- s i z es >t r ue</ r ec or d- mes s a ge- s i z es >
</ pr oper t i es >
</ c ha nnel - def i ni t i on>
I n l i st i ng 5. 18 you en ab l ed t h e p er f o r ma n c e t r ack i n g pr oper t i es f or r ec or d i n g bot i i
mes s age t i mes a n d si zes. I t's a s i mpl e B o o l ea n tiiat can b e set t o f al se f or p r od u c t i on
en vi r on men t c on f i gu r at i on . A d d i n g di es e pr oper t i es al l ows f o r t h e au t omat i c l oggi n g
o f thi s i n f or mat i on . T h i s i s a gr eat way t o gai n i n s i gh t i n t o t h e obj ect s you ' r e s en d i n g
bac k a n d f or t i i b et ween t h e cl i en t a n d ser ver . I f you wer e t o cr eat e a n ew i ssue i n F l ex-
B u gs you wo u l d s ee s omet h i n g l i k e t h e di s pl ay i n f i gu r e 5. 6.
A Me ssa g e t i m e s
^ T c o n f i g u r a t i o n
Me ssa g e si ze s
© c o n f i g u r a t i o n
- i a| , x| ca C:\ WINOQW5\ system32\ emd.eHe - mvn clean | Ptty:run-w.ir
ser u er Post f l dapt er E xt er nal Ti me - 0*0
r ecei u eTi me <=
messageSi ze - 0*0
over head!i r oe
a
0. 0
r ecor dMessageSi ees • f a l s e
ser ver Post f l dapt er Ti me - 0. 0
1.25535258483SE12
<Byte Ar r ay »7, L ength 16>
<Byte Ar r ay «8, L ength 16>
<Byte Ar r ay t»9. L ength 16>
S er i a l i z i n g AMF/ HTTP r esponse
Uer s i on: 3
<Message 80 t ar get URI =/ 6/ onBesul t, responsel J RI =>
<E xt er n al i zabl e Obj ect H0
1
DSK ' )
(E xt er n al i zabl e Obj ect HI ' f l ex . mes s agi n g. i o. A r r ayC ol l ec t i on ' >
(Ar r ay tt2>
10 ]
a
(Typed Obj ect W3 ' or g_ f oj . r i od el . I s s u e' >
i d " 2. 0
pr oj ec t • "P l exB u gs "
r epor tedOn = 2009- 10- 12 00: 00: 00. 0
d et a i l s » "Need per for mance met r i cs i n pl ace f or Bl azeDS messages s i
;:e and any ot her i mpor tant d et a i l s . "
st at u s " "F i n i s h ed"
r epor t edBy • "BJ Al l mon"
des cr i pt i on = "Add Per for mance M et r i c s "
assi gnedTo • "BJ flllmon"
s ever i t y - "Maj or "
t ype
D
"F eat u r e Requ es t "
esti matedHour s • 1. 5
(Obj ect «5>
DSMPIO = (Typed Obj ect ttfi ' f l ex. mes s agi ng. mes s ages . Mes s agePer f or r cancei nf
o' >
ser yer Pr eAdapt er Ti me
3
0. 0
ser wer Pr eAdapt er E xt er nal Ti me - 0. 0
i r r foType = n u l l
sendTi ne - 1.2S5352SB4835E12
r ecor dMessageTi mes • f a l s e
ser uer Pr ePusl i Ti me • 0. 0
pushedF l ag - F al se
ser u er Post Adapt er E xt er nal Ti me = 0. 0
r ecei u eTi me - 0. 0
messacfeS i zc = 835 . 0
ouer heAdl i ni e • 0. 0
r ecor dMessageSi zes - f a l s e
ser u er Post Adapt er Ti me • 0. 0
1.2SS3S2S8483SE12
3
Fi g u r e 5 . 6 B l a z e D S M es s a geP er f oma n c el n f o in acti on
www.it-ebooks.info
1 1 0 CHAPTER 5 BlazeDS remoting and logging
As seen i n fi gur e 5.6 you now have an addi ti onal l og message di recdy under the
i nserti on of a new issue for the pr oj ect Fl exBugs. The BlazeDS Me s sage Per for mance-
U t i l s class shows the sendTi me and tire messageSi ze that you defi ned i n tire ser-
vi ces- confi g.xml . You can see that tire sendTi me is equal to 1.25ms and a message size
of 835.0 bytes.
I n general , the fl ex. messages. messagi ng. MessagePer for manceUt i l s class pro-
vi des metri cs drat descri be tire size and timing of a message sent f r om a cl i ent to tire
server and its server response message. Per for mance i nfor mati on can be captured
when tire r ecor d- message- ti mes and r ecor d- message- si zes are confi gur ed to
TRUE. F r om tirere it's possi bl e to set up mor e per for mance- gather i ng metri cs i n tire
cl i ent. Confi gur i ng tire cl i ent woul d mean creati ng a response acknowl edgment or
message handl er.
NOTE The BlazeDS devel opment gui de instructs devel opers to not activate
mor e than one per for mance measur ement at a time because of tire extra per-
for mance hi t that each measur ement adds to the appl i cati on runti me. Use
dr em wisely. I f you truly have per for mance issues you may consi der other
means for per for mance testi ng l i ke an open source tool or commer ci al alter-
nati ve. Usi ng a separate tool for per for mance testi ng woul d al l ow tire BlazeDS
confi gur ati on to stay true to its pr oducti on envi r onment confi gur ati on dur-
i ng tire per for mance testing.
For mor e on how to confi gur e message per for mance l oggi ng thr ough a message
event handl er r efer to tire BlazeDS devel opment gui de at http:/ / l i vedocs.adobe.com/
bl azeds/ l / bl azeds_devgui de/ hel p. html ?content=mp i _3.html .
5.7 Summary
I n dris chapter you r efactor ed out the XML / HTTP web servi ce i mpl ementati on and
r epl aced it witir BlazeDS AMF r emoti ng. The web servi ce i mpl ementati ons had tire
least i mpact on tire server side but r equi r ed mor e wor k to be done on the cl i ent side,
because we'r e not recei vi ng first class obj ects i n the responses. When you swi tched to
usi ng BlazeDS to communi cate witir tire server side you gai ned i n per for mance witir-
out i ncreasi ng tire compl exi ty of tire appl i cati on.
Usi ng tire Spri ng BlazeDS I ntegr ati on fr amewor k r educed tire amount of confi gu-
rati on typically r equi r ed to set up r emoti ng desti nati ons. I t also gave you a handful of
useful annotati ons and oti rer features that r educed tire compl exi ty of the appl i cati on
even mor e. As you'l l conti nue to see thr oughout tire r emai nder of the book, tire
Spri ng BlazeDS I ntegr ati on si mpl i fi es tire code and makes bui l di ng robust Fl ex and
J ava appl i cati ons much easier.
You also confi gur ed l oggi ng to be sure drat you can capture tirose i mpor tant appl i -
cati on activities i n a l og fi l e. Setti ng up tire l oggi ng for BlazeDS events was a si mpl e
task usi ng both l og4j and tire Spri ng BlazeDS I ntegr ati on fr amewor k l ogger class.
www.it-ebooks.info
Summary 1 1 1
BlazeDS also enabl es di e gather i ng of per for mance measurements on a channel ser-
vi ce. Wi th that you wer e abl e to pump per for mance stats on message size and time to
your l og fi l e.
I n the next chapter you'l l take the next step i n evol vi ng our Fl ex and J ava
communi cati ons and take advantage of real - ti me messagi ng between the two usi ng
BlazeDS messagi ng.
www.it-ebooks.info
Flex messM^n^
o
Thi s chapt er covers
• S e t t i n g u p B l a z e D S f o r m e s s a g i n g
• U s i n g t h e F l e x M e s s a g i n g A P I
• C re a t i n g a p o l l i n g c h a n n e l
The Flex Messaging API, bundl ed with BlazeDS, provides asynchronous messaging,
which you can use to create a better user experi ence by enabling your application
to refresh itself in real time whenever anyone using the application makes any
changes. The BlazeDS MessageServi ce allows bidirectional communication
between Flex clients and di e server side.
I n general, you want to use messaging to noti fy the client of changes. This will
fi re off an event to refresh di e FlexBugs issues list. Figure 6.1 demonstrates tiiis use
of messaging.
Thi s chapter will expl oi t the use of the Flex Messaging API and simple pol l i ng to
receive updates fr om the server when changes in di e model have occurred.
Changes will cause an event to be dispatched tiiat will refresh the master view and
ultimately the list of issues.
The details of messaging operations depend on your needs and di e style of
underlying messaging architecture you've chosen; for example, client-to-client,
112
www.it-ebooks.info
Setting up BlazeDS for messaging 1 1 3
J MS, Fl ex to POJ O, orJ avaBean messagi ng. On top of that, it's possi bl e to confi gur e the
cl i ent to per for m si mpl e or l ong pol l i ng or even streami ng. Al l these scenari os for
messagi ng are useful and have accompanyi ng benefi ts and consequences. I t's always
best to start wi th tire si mpl e appr oach befor e movi ng to tire compl ex.
6.1 Set t i ng up Bl azeDS f or messagi ng
Li ttl e confi gur ati on is needed to set up a si mpl e messagi ng archi tecture drat allows
a Fl ex cl i ent to subscribe to a server-side component. I t's also good to use a messag-
i ng API drat is agnosti c to tire underl yi ng messagi ng archi tecture. Thi s makes it easy
to start witir a si mpl e server side, say wi th POJ Os, and expand to somethi ng l i ke J MS
i f necessary.
6.1.1 Modifying the services-config.xml
You fi rst modi fy tire servi ces- confi g.xml fi l e. I f wor ki ng i n the Fl exBugs sampl e appl i -
cati on, it is found i n tire bl aze- conf i g modul e. The servi ces- confi g.xml fi l e is l ocated
i n tire src/ mai n/ resources di rectory.
You want to pr epar e tire server side witir a new channel defi ni ti on for pol l i ng as
seen i n listing 6.1. For brevi ty we've excl uded el ements of tire fi l e that have al ready
been discussed and are not goi ng to change.
Li s t i n g 6 . 1 Ad d i n g t h e p o l l i n g c h a n n e l -d e f i n i t i o n t o s e r v i c e s -c o n f i g . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<ser vi c es- c onf i g>
<c ha nnel s> A Channel -def i ni t i on
• • • T decl ar at i on
<c ha nnel - def i ni t i on i d=" my- pol l i ng- a mf " <—I
c l a ss=" mx. messa gi ng. c ha nnel s. AMFCha nnel " >
<endpoi nt ur l =" ht t p: / / {ser ver . na me}: {ser ver . por t }/ {c ont ext . r oot }/
messa gebr oker / a mf pol l i ng"
c l a ss=" f l ex. messa gi ng. endpoi nt s . AMFEndpoi nt " / > <1—i
<pr oper t i es> Endpoi nt ur l ©
<pol l i ng- ena bl ed>t r ue</ pol l i ng- ena bl ed>
<
l

i
© Pol l i ng is enabl ed
www.it-ebooks.info
1 1 4 CHAPTER 6 Flex messaging
<pol l i ng- i nt er va l - sec onds>4</ pol l i ng- i nt er va l - sec onds>
</ pr oper t i es>
</ c ha nnel - def i ni t i on>
D
Polling i nt erval
</ c ha nnel s>
</ ser vi c es- c onf i g>
Al l you need to do to set up di e channel defi ni ti on is specify an i d © and endpoi nt
and enable pol l i ng The channel defi ni ti on for di e my- pol l i ng- amf channel ©
will be used by Flex when contacting the server.
The endpoi nt el ement Q provides a URL that must be unique fr om other end-
points, and di e endpoi nt class for di e server. The endpoi nt is used by di e channel ser-
vice to do its business in regards to client-side and server-side communication.
Properties defi ni ng the channel are nested in a properties element. The channel
defi ni ti on contains behaviors that allow it to be confi gured in a variety of ways. I n our
example, you have simple pol l i ng enabled Q and di e pol l i ng interval Q set to pol l at
every 4 seconds. Simple pol l i ng is generally less effi ci ent tiian l ong pol l i ng because it
continues to pi ng the server at each specified interval and receives acknowledgments
even when tiiere are no changes, and di e acknowledgments are empty. Long pol l i ng
allows di e client to pi ng di e server; the server keeps di e request and returns an
acknowl edgment when tiiere is a message.
P o lli n g p e rfo rm a n ce
Wh e n s e l e c t i n g a p o lli n g m e c h a n i s m , c o n s i d e r w h i c h s o l u t i o n w o u l d re q u i re t h e
le a s t a m o u n t o f o v e rh e a d . B o t h s i m p le a n d lo n g p o lli n g c a n b e s e rv e r-s i d e i n t e n s i v e
i f t h e re a re n u m e ro u s m e s s a g e s b e i n g p a s s e d b a c k a n d f o rt h a n d a n a b u n d a n c e o f
u s e rs . E v e n t h o u g h lo n g p o lli n g i s g e n e ra l l y m o re e f f i c i e n t t h a n s i m p le , i t 's p o s s i b l e
t h a t a n a p p l i c a t i o n w i t h m a n y u s e rs w i t h f re q u e n t c h a n g e s c o u l d c a u s e m o re c l i e n t
a n d s e rv e r f ri c t i o n a n d b e le s s re s p o n s i v e t h a n c o n t ro l l i n g p o lli n g w i t h t h e s i m p le
a p p ro a c h . I f lo n g p o lli n g i s a n o p t i o n , s t re a m i n g s h o u l d b e a c o n s i d e ra t i o n a s w e l l .
S t re a m i n g i s s i m i la r b u t k e e p s a c o n n e c t i o n o p e n i n s t e a d o f o p e n i n g a n d c l o s i n g
o n e b e t w e e n e a c h t ra n s m i s s i o n .
The changes to the services-config.xml were di e only changes necessary for di e con-
figuration modul e to add a pol l i ng channel. Now let's move on to di e webapp mod-
ule changes.
6.1.2 Updating the webapp server-side module
Now diat you've tackled the channel defi ni ti on in the services-config.xml fi l e you can
move on to modi fyi ng the webapp. We'l l start witii the flex-spring-servlet.xml and
applicationContext.xml changes, then move on to changes in di e J ava code.
www.it-ebooks.info
Setting up BlazeDS for messaging 1 1 5
MODI FY THE FLEX-SPRI NG-SERVLET.XML
You start by edi ti ng tire flex-spring-servlet.xml found i n tire src/ mai n/ webapp/ WEB-
I NF di rectory of the f l ex- bugs- web modul e. Her e you wi l l be addi ng a new Spri ng-
managed Messa geBr oker , Messa geSer vi c e, and Messa geD est i na t i on for your new
pol l i ng channel .
Li st i n g 6.2 Ad d i n g MessageBr ok er , Mes s ageS er vi ce, a n d Mes s ageDes t i n at i on
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<bea ns xml ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns"
xml ns: f l ex=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex"
xml ns : xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on="
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns/ spr i ng- bea ns- 2. 5. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex/ spr i ng- f l ex- 1. 0. xsd" >
<f l ex : messa ge- br oker > <—n
<f l ex: r emot i ng- ser vi c e def a ul t - c ha nnel s="my- a mf "/ > O Added message-brok er
<f l ex: messa ge- ser vi c e def a ul t - c ha nnel s=" my- pol l i ng- a mf " / >
<f l ex: sec ur ed/ >
</ f l ex : messa ge- br oker >

vi ce Q Added message-servi ce
^ ^ P Added message-dest i nat i on
<f l ex : r emot i ng- dest i na t i on r ef =" user D a o" / >
<f l ex : messa ge- dest i na t i on i d=" f l exMessa ge" / >
</ bea ns>
I n the l i sti ng you added tire Spr i ng message- ser vi ce Q that poi nts to tire my-
pol l i n g- amf channel you defi ned i n tire servi ces- confi g.xml . Because you are usi ng
a Spri ng- managed MessageBr oker Q , you can speci fy the message desti nati on © by
addi ng tire el ement and gi vi ng it tire i d you want to r efer to i n tire server-side i mpl e-
mentati on. You wi l l use tire message desti nati on to send messages f r om the server-
side obj ects.
MODI FY THE APPLI CATI ONCONTEXT.XML
The last bi t of confi gur ati on detai l is found i n the Spri ng appl i cati onContext. xml .
Thi s file is also l ocated i n tire src/ mai n/ webapp/ WEB- I NF di rectory of tire f l ex- bu gs -
web modul e. The code l i sted her e shows tire two Spri ng beans you need to defi ne i n
the appl i cati onContext. xml .
<bea n i d=" def a ul t Messa geTempl a t e"
c l a ss=" or g. spr i ngf r a mewor k. f l ex. messa gi ng. Messa geTempl a t e" / >
<bea n i d=" i ssueSer vi c e" c l a ss=" or g. f oj . ser vi c e. i mpl . I ssueMa na ger l mpl " >
<c onst r uc t or - a r g r ef =" i ssueD a o" / >
<c onst r uc t or - a r g r ef =" c omment Ser vi c e" / >
<c onst r uc t or - a r g r ef =" def a ul t Messa geTempl a t e" / >
</ bea n>
So that you can push messages to tire message desti nati on f r om your J ava obj ects,
Spri ng has gi ven us tire MessageTempl ate hel per class. I nj ect an i nstance of tire
www.it-ebooks.info
1 1 6 CHAPTER 6 Flex messaging
MessageTempl ate i nto the i s s u eSer vi ce and use it i n di e I ssueManager l mpl .
Because the MessageTempl ate is confi gur ed as a Spri ng bean, it autodetects the
MessageBroker. Otherwi se, it woul d need to be confi gur ed.
MODI FY THE I SSUEMANAGERI MPL
Now di at you have di e Spri ng confi gur ati on squared away, you can take advantage of
di e i nj ected MessageTempl ate obj ect by addi ng it to di e I ssueManager l mpl class as
seen i n listing 6.3.
Li s t i n g 6 . 3 Ad d i n g t h e i n j e c t e d M e s s a g e T e m p l a t e
i mpor t or g. spr i ngf r a mewor k. f l ex. messa gi ng. Messa geTempl a t e;
( i WebSer vi c e( ser vi c eNa me = " I ssueSer vi c e" ,
endpoi nt l nt er f a c e = " or g. f oj . ser vi c e. I ssueMa na ger " )
publ i c c l a ss I ssueMa na ger l mpl i mpl ement s I ssueMa na ger {
pr i va t e Gener i c D a o<I ssue, Long> i ssueD a o;
pr i va t e Comment Ma na ger c omment Ma na ger ;
pr i va t e Messa geTempl a t e messa geTempl a t e;
publ i c I ssueMa na ger l mpl ( Gener i c D a o<I ssue, Long> i ssueD a o,
Comment Ma na ger c omment Ma na ger ,
Messa geTempl a t e messa geTempl a t e)
{
t hi s. i ssueD a o = i ssueD a o;
t hi s. c omment Ma na ger = c omment Ma na ger ;
t hi s . messa geTempl a t e = messa geTempl a t e; <—,
A MessageTempl at e
< ] _! f i el d
^ ^ Const r uct or
argument s
Set messageTempl at e
publ i c I ssue sa ve( I ssue i ssue) {
St r i ng messa geBody = "I ssue wa s sa ved" ;
messa geTempl a t e. send( " f l exMessa ge" , messa geBody) ;
r et ur n i ssueD a o. sa ve( i ssue) ;
}
publ i c voi d r emove( Long i d) {
c omment Ma na ger . del et eAHComment sFor l ssuel d( i d) ;
St r i ng messa geBody = "I ssue wa s r emoved" ;
messa geTempl a t e. send( " f l exMessa ge" , messa geBody) ;
i ssueD a o. r emove( i d) ;
}
To take advantage of di e Spri ng MessageTempl ate, you first create a pri vate fi el d to
store the MessageTempl ate i nstance Q that you i nj ect. Because you are i nj ecti ng
thr ough the constructor © you set the pri vate fi el d Q to equal di e i nj ected instance.
I n the exampl e you wi l l use di e MessageTempl ate to send di e cl i ent a text message
noti fi cati on. Thi s message wi l l l et the cl i ent know tiiat a refresh is needed. You wi re up
Updat ed save
13 met hod
J
Updat ed remove
met hod
www.it-ebooks.info
Modifying the client for messaging 1 1 7
the notification to the save Q and remove © methods and pass a message to die cli-
ent indicating that die issue was eitiier saved or removed.
Now diat all the necessary changes are in place for simple messaging witii Spring
and Flex, it's time to update the Flex client.
6.2 Modi f yi ng t he cl i ent f or messagi ng
The Flex client changes are extremely simple. The use of die MVP design pattern iso-
lates die changes to only two locations. We're goi ng to create a ChannelSetFactory to
leverage the power of the ChannelSet object for communicating with BlazeDS, and
we'll modi fy the IssueModel object to receive the issue model updates from the poll-
ing channel.
6.2.1 Creating a ChannelSetFactory
Similar to die approach you took earlier witii the EventFactory, you create a single-
ton instance of a ChannelSet and retrieve it so tiiat all your components are using the
same ChannelSet. Using a ChannelSet allows you to leverage communication chan-
nels such as AMFChannel, HTTPChannel, StreamingAMFChannel, and StreamingHTTP-
Channel at the same time, creating redundancy and fail-safes that help guarantee your
data gets transmitted. To do tiiis you'll create a ChannelSetFactory in the fl ex- bugs-
l i b module.
Li st i ng 6 .4 Channel Set Fact or y.as
pa c ka ge or g. f oj . model {
i mpor t mx. messa gi ng. Cha nnel Set ;
i mpor t mx. messa gi ng. c ha nnel s. AMFCha nnel ;
publ i c c l a ss Cha nnel Set Fa c t or y {
pr i va t e st a t i c va r _messa gi ngCha nnel Set : Cha nnel Set ;
publ i c f unc t i on Cha nnel Set Fa c t or y! ) {
}
o si
<hJ in
Si ngl et on
i nst ance
J
St at i c
f act or y
m et hod
publ i c st a t i c f unc t i on get Messa gi ngCha nnel ( ) : Cha nnel Set {
i f ( _messa gi ngCha nnel Set == nul l ) {
va r pol l i ngCha nnel : AMFCha nnel = new AMFCha nnel ( " my- pol l i ng- a mf " ,
" ht t p: / / l oc a l host : 8080/ f l exbugs/ messa gebr oker / a mf pol l i ng" ) ;
_messa gi ngCha nnel Set = new Cha nnel Set ( ) ;
_messa gi ngCha nnel Set . a ddc ha nnel ( pol l i ngCha nnel ) ; AMFChannel
}
r et ur n _messa gi ngCha nnel Set ;
The code for die ChannelSetFactory is similar to the EventDi spatcherFactory.
Start by declaring your private instance variable to hold the ChannelSet then
define a static factory method tiiat the rest of the application will use to retrieve
www.it-ebooks.info
118 CHAPTER 6 Flex messaging
the Cha nnel Set I nsi de tiiis meti i od you check to see i f di e i nstance has been
instantiated; i f not create one and assign your AMFCha nnel to it Al l tirat's l eft is
to return di e Cha nnel Set to the caller. Next let's l ook at modi fyi ng di e I ssueModel to
l everage tiiis Cha nnel Set .
6.2.2 Changing the IssueModel
The fi nal task to per for m, i n your sampl e messagi ng desi gn, is to fi r e off an event
when tire cl i ent recei ves a push noti fi cati on message whi ch shoul d refresh tire issue
master vi ew D a t a Gr i d. You do tiris by addi ng a Consumer of tire messagi ng channel .
Li s t i n g 6 . 5 The I s s u eModel m e s s a g e Consumer
pa c ka ge or g. f oj . model {
I m por t Fl ex
MessageEvent cl ass
i mpor t mx. messa gi ng. event s. Messa geEvent ;
publ i c c l a ss I ssueModel {
pr i va t e va r _i ssueSer vi c e: Remot eObj ec t ;
publ i c f unc t i on I ssueModel ( ) {
va r def a ul t Cha nnel Set : Cha nnel Set = Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ;
_i ssueSer vi c e = new Remot eObj ec t ( ) ;
_i ssueSer vi c e. dest i na t i on = " i ssueSer vi c e" ;
_i ssueSer vi c e. Cha nnel Set = def a ul t Cha nnel Set ;
va r messa gi ngCha nnel Set : Cha nnel Set
= Cha nnel Set Fa c t or y. get Messa gi ngCha nnel ( ) ;
J
Get messagi ng
Channel Set
va r c onsumer : Consumer = new Consumer ( ) ;
c onsumer . dest i na t i on = " f l exMessa ge" ;
c onsumer . Cha nnel Set = messa gi ngCha nnel Set ;
c onsumer . a ddEvent Li st ener ( Messa geEvent . MESSAGE, messa geHa ndl er ) ;
c onsumer . subsc r i be ( ) ;
pr i va t e f unc t i on messa geHa ndl er ( event : Messa geEvent ) : voi d{
va r event D i spa t c her : Event D i spa t c her =
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) ;
va r r ef r eshEvent : UI Event = new
UI Event ( UI Event . REFRESH_I SSUES_BUTTON_CLI CKED ) ;
event D i spa t c her . di spa t c hEvent ( r ef r eshEvent ) ;
Fl ex Consumer Q
<—
messageHandl er Q
}
}
www.it-ebooks.info
Modifying the client for messaging 119
I n the I ssueModel you receive notification of changes through the built-in Flex Mes-
saging API . After i mporti ng the Messa geEvent class Q, you need to get an instance of
the messaging AMF Cha nnel Set fr om the Cha nnel Set Fa c t or y
Next you need to create a Flex Consumer Q and establish its properties. You con-
fi gured di e consumer's destination to be the f l exMessage destination, defi ned in di e
f l ex- spr i ng- ser vl et .xml. The consumer's ChannelSet was set to di e one you got
fr om the Channel SetFactory.
The event listener is an important piece. I t allows you to invoke a meti i od when a
consumer receives a message fr om di e server. You declared that you wanted di e event
to be di e Messa geEvent type Messa ge and tiiat the method to call is messa geHa ndl er
O Finally, you subscribe to di e server-side message destination by calling c on-
sumer . subsc r i be( ) .
Now that your Flex client is set up to subscribe to a messaging destination, you can
see it in action. This is possible by openi ng up two di fferent browser instances; make
changes in one while keepi ng an eye on the other as in fi gure 6.2 where di e browser
snippet on di e l eft shows the issue for m that persisted di e issue and di e browser on
the right automatically gets the update.
Changes should be noticeable in the issues D a t a Gr i d as changes occur in the
application to the issues. The changes will occur within 4 seconds, as specified in
the channel defi ni ti on. That's all there is to setting up a simple messaging solution
with Flex!
P i o ji i t
Dsscrtpknn:
"Ci
sevwitf
Btttttt:
Details:
fi ['[j't'j J
Ritprtso On;
Assured To:
Es& mated Hours;
M3I0F
This is a sample
ertilicl
:
£5UG
J S
| save issue | | cared cnargas |
FlexBugs
My Fl Oj OCt DESC
| Refresh usi |
Figure 6.2 Tryi ng out t he messagi ng usi ng t wo browsers
www.it-ebooks.info
120 CHAPTER 6 Flex messaging
6.3 Summary
I n this chapter you confi gured BlazeDS, Spring, and a Flex client for a simple messag-
i ng architecture. You changed certain J ava service methods so drat drey woul d noti fy
tire client of changes and made changes to the I ssueModel to listen as a consumer.
Using tire Flex messaging API you used a Consumer to subscribe to tire messaging
channel service and received dynamic updates for tire I ssues master view. You will
take messaging a step farther by confi guri ng J MS when discussing Flex witir Grails.
I n tire next chapter you will take a peek at securing and personalizing an applica-
tion. The Spring security framework will be used with its annotation to provi de great
flexibility witir the least amount of complexity.
www.it-ebooks.info
Part 3
The joys of Flex on J ava
J L ar t 3, chapters 7 through 11, goes beyond what you'd fi nd in most books
on Flex and J ava. You will cover topics like security and personalization
because most applications need to i mpl ement a security strategy, and personal-
ization usually comes next.
You will also cover charting with Degrafa, an open source Flex drawing API,
and addi ng a chart to tire exampl e application.
One feature that sets tire Flex framework apart fr om other web frameworks is
its ability to run as a native desktop application. Wi th this in mind, you will refac-
tor the exampl e application to include a depl oyment to tire desktop version of
the application.
Because writing code without tests is irresponsible, these final chapters
demonstrate how to test your Flex application with FlexUnit. We not only pro-
vi de basics on test-driven devel opment (TDD), we break down the exampl e
application's structure and show you how to maintain good coverage across tire
entire application.
The last chapter covers Flex and Grails devel opment. This is an exciting com-
bination of technologies. You will quickly construct a new exampl e application
with Grails and build a Flex frontend for it.
www.it-ebooks.info
www.it-ebooks.info
Securing
persona
your applic
Thi s chapt er covers
• A u t h e n t i c a t i o n
• A u t h o ri z a t i o n
• P e rs o n a l i z a t i o n
I n the past couple of chapters you've experi enced some of tire great integration
features that BlazeDS gives us. Now you're goi ng to take integration one step fur-
ther as you strengthen your application and add security features.
You'l l leverage tire existing security infrastructure provi ded by AppFuse and not
have to spend precious time on tire particulars of setting up a Li ghtwei ght Direc-
tory Access Protocol (LDAP) server, authenticating against Active Directory, and
creating Access Control Lists (ACLs). There are plenty of resources on tire web that
cover these advanced topics, which are beyond the scope of our goals for tiris chap-
ter. The i nformati on you cover in tiris chapter should be sufficient for about 90% of
the applications that you'l l encounter.
You'l l take an iterative approach to addi ng security to tire sample application,
starting by addi ng simple l ogi n and l ogout functionality, allowing tire application
to authenticate using tire same mechanism that AppFuse uses internally. You'l l
build upon drat by addi ng security constraints to the services and lock down tire
123
www.it-ebooks.info
124 CHAPTER 7 Securing and personalizing your application
destructive meti i od calls to only users bel ongi ng to specific roles. You'l l also learn
about an often-overl ooked aspect of security, personalization. Before getting started,
let's cover basic concepts of di e Spring Security framework.
7.1 Aut hent i cat i on
The simplest for m of security tiiat you can add to di e application is to allow a user to
enter his user name and password and autiienticate using the server side. For many
applications this is usually sufficient. There are many strategies for authenticating
users, fr om rol l i ng your own authentication methods and exposing di em as remote
services for di e application to use, to i mpl ementi ng basic authentication measures
using the web server, or in your case using a security framework like Spring Security.
AppFuse provides, out of di e box, a simple autiientication mechanism based on
user i nformati on bei ng stored in di e database, so you don't need to go through the
trouble of setting up an autiientication provider. The bi g advantage to leveraging a
framework like Spring Security is that you can change out the mechanism for authen-
tication fr om a database table to an LDAP server witiiout having to change anything in
your Flex application. So now let's get started witii i mpl ementi ng the components you
need to allow users to autiienticate using your application.
7.1.1 Modifying the ChannelSetFactory
Even though all the remote components that you use to communicate witii external
services have methods supporting sending credentials for authentication, this is not
an ideal solution because the application woul d need to hol d di e username and pass-
word, in order for you to manually pass di em al ong with every remote meti i od call you
made. Not only is tiiis tedious, it's error prone. Instead you'l l leverage di e Cha nnel Set
to autiienticate the user to the server side and maintain a session until you either close
the application or l og out.
To do this you'l l modi fy the Cha nnel Set Fa c t or y tiiat you created in the last chap-
ter as shown in listing 7.1
C h a n n e ls a n d C h a n n e lS e ts
F le x u s e s d i ffe re n t m e t h o d s o f c o m m u n i c a t i n g w i t h B l a ze D S o n t h e s e rv e r s i d e
d e p e n d i n g o n t h e t y p e o f c o m m u n i c a t i o n : AMFCha nnel , HTTPCha nnel , st r ea m-
i ngAMFCha nne1, a n d st r ea mi ngHTTPCha nnel . T h e s e c h a n n e l s e n c a p s u l a t e t h e
b e h a v i o r o f c o n n e c t i n g a n d m a i n t a i n i n g c o m m u n i c a t i o n s w i t h t h e B l a ze D S c o m p o -
n e n t s o n t h e s e rv e r s i d e . Yo u m a y re c a ll t h a t w h e n s e t t i n g u p B l a ze D S y o u c o n f i g -
u re d a n AMFCha nnel i n t h e s e rv i c e s -c o n f i g . x m l fi le p ro vi d i n g a m e a n s o f c o n n e c t i n g
t o B l a ze D S u s i n g y o u r Remot eObj ec t c o m p o n e n t s . T h e F le x re m o t i n g c o m p o n e n t s
s u c h a s Remot eObj ec t a llo w y o u t o a s s i g n a s e t o f t h e s e c h a n n e l s fo r u s e b y t h e
c o m p o n e n t s , g i v i n g y o u f a llb a c k a n d fa i lo ve r b e h a v i o r o u t o f t h e b o x , a s w e l l a s
a llo wi n g u s e rs t o a u t h e n t i c a t e t o t h e s e rv e r s i d e .
www.it-ebooks.info
Authentication 125
Li s t i n g 7 . 1 Ch a n n e l Se t Fa c t o r y . a s
pa c ka ge or g. f oj . model {
i mpor t mx. messa gi ng. Cha nnel Set ;
i mpor t mx. messa gi ng. c ha nnel s. AMFCha nnel ;
publ i c c l a ss Cha nnel Set Fa c t or y {
pr i va t e st a t i c va r _def a ul t Cha nnel Set : Cha nnel Set ;
pr i va t e st a t i c va r _messa gi ngCha nnel Set : Cha nnel Set ;
publ i c f unc t i on Cha nnel Set Fa c t or y( ) {
}
publ i c st a t i c f unc t i on get D ef a ul t c ha nnel ( ) : Cha nnel Set {
i f ( _def a ul t Cha nnel Set == nul l ) {
va r c ha nnel : AMFCha nnel = new AMFCha nnel ( " my- a mf " ,
" ht t p: / / l oc a l host : 8080/ f l exbugs/ messa gebr oker / a i
_def a ul t Cha nnel Set = new Cha nnel Set ( ) ;
_def a ul t Cha nnel Set . a ddc ha nnel ( c ha nnel ) ;
}
r et ur n _def a ul t Cha nnel Set ;
}
publ i c st a t i c f unc t i on get Messa gi ngCha nnel ( ) : Cha nnel Set {
i f ( _messa gi ngCha nnel Set == nul l ) {
va r pol l i ngCha nnel : AMFCha nnel = new AMFCha nnel ( " my- pol l i ng- a mf " ,
" ht t p: / / l oc a l host : 8080/ f l exbugs/ messa gebr oker / a mf pol l i ng" ) ;
_messa gi ngCha nnel Set = new Cha nnel Set ( ) ;
_messa gi ngCha nnel Set . a ddc ha nnel ( pol l i ngCha nnel ) ;
}
r et ur n _messa gi ngCha nnel Set ;
}
}
}
You start by decl ari ng a pri vate i nstance vari abl e to hol d tire Cha nnel Set O - Then you
add another static factory method drat tire rest of tire appl i cati on wi l l use to retri eve
the Cha nnel Set ©. I nsi de this method you check to see i f tire i nstance has been
instantiated, and i f not create one and assign your AMFCha nnel to it Then return
the Cha nnel Set to tire caller.
Next l et's create the custom event class for your l ogi n panel to use.
7.1.2 Creating a UserEvent
The User Event class shoul d l ook fami l i ar; it's anoti rer custom event class j ust l i ke tire
one you created for tire rest of tire events that your appl i cati on uses. You'r e creati ng
this one separate f r om the other event class, because it is a separate area of concer n
f r om UI events. Thi s wi l l make it easier to extract tire l ogi n panel to a separate
l i brary later, by keepi ng all of tire l ogi n functi onal i ty separate f r om tire rest of the
appl i cati on l ogi c.
J
Si ngl et on
i nst ance
J
St at i c f act or y
met hod
1>
AMF
m f
" >
;
« Channel
www.it-ebooks.info
126 CHAPTER 7 Securing and personalizing your application
Li s t i n g 7 . 2 Us e r Ev e n t . a s
pa c ka ge or g. f oj . event {
i mpor t f l a sh. event s. Event ;
publ i c c l a ss User Event ext ends Event {
publ i c st a t i c va r LOGI N_BUTTON_PRESSED : St r i ng =
" l ogi nBut t onPr essed" ;
publ i c st a t i c va r LOGOUT_BUTTON_PRESSED : St r i ng
" l ogout But t onPr essed" ;
publ i c st a t i c c onst USER_LOGGED _I N: St r i ng =
" user Loggedl n" ;
publ i c st a t i c c onst CURRENT_USER_UPD ATED : St r i ng
" c ur r ent User Upda t ed" ;
publ i c va r da t a : *;
publ i c f unc t i on User Event ( t ype : St r i ng,
bubbl es : Bool ea n = t r ue,
c a nc el a bl e : Bool ea n = f a l se)
{
super ( t ype, bubbl es, c a nc el a bl e) ;
}
}
}
Li sti ng 7.2 shows your custom User Event . You begi n j ust as you di d i n di e last event
class by defi ni ng constants to descri be what events you'l l be usi ng tiiis class for Q .
Next you defi ne a da t a member vari abl e to carry any data wi th di e event i f necessary
Next you decl are an over l oaded constructor © and i nsi de tiiis is a call to di e base
constructor i n di e Event class Q . Now tiiat you've defi ned di e custom event, l et's put
it to use and start to create di e l ogi n panel .
7.1.3 Creating a login panel
Ther e are many ways to i mpl ement di e l ogi n functi onal i ty. You can create a separate
l ogi n screen, a pop up, or i mpl ement it i nl i ne. Because you'r e not goi ng to attempt to
pr event users f r om accessi ng and browsi ng the appl i cati on unless they're l ogged i n,
havi ng a separate l ogi n screen that takes users away f r om the appl i cati on doesn't
make sense. Nei ti i er does bl ocki ng di e appl i cati on wi th a modal di al og for ci ng di em
to l ogi n, so you'r e goi ng wi ti i the si mpl est possi bl e sol uti on, whi ch is to present the
user wi th a coupl e of fi el ds i n di e upper- ri ght side of di e appl i cati on for enter i ng the
username and password.
The l ogi n panel wi l l use a Vi ewSt a c k j ust as your mai n appl i cati on does, so tiiat as
users l og in, the l ook of the l ogi n panel wi l l change to r efl ect that di e user has l ogged
i n successfully as shown i n fi gur e 7.1. When di e user l ogs out, di e vi ew wi l l change
back to the i ni ti al l ogged out state.
J
Event t ype
const ant s
J
Dat a f i el d
1,
Cal l t o
Over l oaded
const r uct or
super
www.it-ebooks.info
Authentication 127
Fl exBu gs Appl i cat i on I i S I
I o vV. \
I
ID Pr«|«t
I Plat f l ugj i O* Hi
\
Fl exBugs Ap p l i ca t i on
IÜ pT«J«t 1W1« Typ. Swrlfy StdM
] Pl*x bp r«*n l It 1 OhtM
Z W«rM(toafcMttan a «Wu> I'j wMdental fUw Ina 1 Acttr*
X
|i 0«tJill t o, ] ütäth V*m\
JO; [l_
TM*: Ir«lur« |.j~
Fi gure 7.1 Loggi ng in t o t he appl i cat i on
Li st i ng 7 .3 Logi nPanel .m xm l
<?xml ver si on="1. 0" encodi ng="utf- 8"?>
<s:Group xml ns:fx="http:/ / ns.adobe.com/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
c r ea t i onCompl et e=" i ni t ( ) " >
<s: l a yout >
<s: Hor i zont a l La yout / >
</ s: l a yout >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t mx. messa gi ng. Cha nnel Set ;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . User Event ;
i mpor t or g. f oj . model . Cha nnel Set Fa c t or y;
i mpor t or g. f oj . pr esent er . Logi nPr esent er ;
pr i va t e va r pr esent er : Logi nPr esent er ;
pr i va t e f unc t i on i ni t ( ) : voi d {
pr esent er = new Logi nPr esent er ( t hi s) ;
}
pr i va t e f unc t i on l ogi n( ) : voi d {
va r l ogi nEvent : User Event =
new User Event ( User Event . LOGI N_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( l ogi nEvent ) ;
}
pr i va t e f unc t i on l ogout ( ) : voi d {
va r l ogout Event : User Event =
new User Event ( User Event . LOGOUT_BUTTON_PRESSED ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( l ogout Event ) ;
}
] ]>
</ f x: Sc r i pt >
Ext ends Gr oup
Set l ayout f or
component
s
1>
Present er f or
l ogi n component
I ni t met hod

Event handl er f or
t he l ogi n but t on
1>
Event handl er f or
t he l ogout but t on
www.it-ebooks.info
128 CHAPTER 7 Securing and personalizing your application
<mx: Spa c er wi dt h=" 100%" / >
<mx:ViewStack i d="l ogi nStack"
paddi ngTop="5"
paddi ngBottom="5">
<mx:HBox i d="l oggedOut">
<mx:FormItem l abel ="Username">
<mx:Textl nput i d="usernamel nput" wi dth="150"/ >
</ mx:FormItem>
<mx:FormItem l abel ="Passwor d">
<mx: Text l nput i d=" pa sswor dl nput " wi dt h=" 150"
di spl a yAsPa sswor d=" t r ue" / >
</ mx: For mI t em>
<mx:Button i d="l ogi nL i nk" l abel ="L ogi n" cl i ck ="l ogi n ()"/ >
</ mx:HBox>
<mx:HBox i d=" l oggedl n" > <1—,
<mx: Spa c er wi dt h=" 100%"/ > Q Loggedl n vi ew
<mx: Text i d=" l ogi nLa bel " t ext =" Logged i n a s: "/ >
<mx: Text i d=" user Na me" / >
<mx:Button i d="l ogoutLi nk" l abel ="Logout" cl i ck ="l ogou t ()"/ >
</ mx:HBox>
</ mx: Vi ewst a c k>
</ s: Gr oup>
Li sti ng 7.3 shows the code f or our Logi nPa nel . As wi th most of our oti i er compo-
nents, di i s panel wi l l extend the Gr oup component Q , and you defi ne its l ayout to be
hor i zont a l Q . Next you defi ne a pri vate member vari abl e for your Presenter Q and
i ni ti al i ze it i n your i ni t method Q passing i n a r efer ence to di e panel i n di e construc-
tor. Then you defi ne a coupl e of event handl ers for di e l ogi n button bei ng cl i cked Q
as wel l as the l ogout button bei ng cl i cked ©. These two event handl ers fol l ow the
same pattern tiiat you establ i shed i n chapter 3. They create di e appr opr i ate User -
Event and di spatch it for your Presenter, and anyone else who is concer ned can react.
You defi ne di e visual components starting wi th defi ni ng a Vi ewSt a c k Q that wi l l
al l ow you to switch between di e states that are possi bl e for di e l ogi n panel . I nsi de of
di e Vi ewSt a c k component you create two HBox components, one for di e l oggedOut
vi ew state © and one for di e l oggedl n vi ew state Q . Now you need to create di e Pre-
senter for the Logi nPa nel .
7.1.4 Creating a login Presenter
The Logi nPr esent er class starts out simply. I t fol l ows di e same gener al pattern tiiat all
of the previ ous Presenters have, onl y havi ng to react to a coupl e of button presses and
not havi ng to mai ntai n any ki nd of state j ust yet.
Li s t i n g 7 . 4 Lo g i n Pr e s e n t e r . a s
pa c ka ge or g. f oj . pr esent er {
Vi ew st ack
1>
LoggedOut vi ew
publ i c cl ass Logi nPr esenter {
www.it-ebooks.info
Authentication 129
pr i va t e va r _vi ew: Logi nPa nel ;
pr i va t e va r _model : Logi nModel ;
publ i c f unc t i on Logi nPr esent er ( vi ew: Logi nPa nel ) {
t hi s. _vi ew = vi ew;
t hi s. _model = new Logi nModel ( ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( User Event . LOGI N_BUTTON_PRESSED ,
l ogi n) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( User Event . LOGOUT_BUTTON_PRESSED ,
l ogout ) ;
}
pr i va t e f unc t i on l ogi n( event : User Event = nul l ) : voi d {
va r r esponder : I Responder = new Async Responder (
l ogi nResul t , ha ndl eEr r or ) ;
_model . l ogi n( _vi ew. user na mel nput . t ext ,
_vi ew. pa sswor dl nput . t ext , r esponder ) ;
}
pr i va t e f unc t i on l ogout ( event : User Event = nul l ) : voi d {
va r r esponder : I Responder = new Async Responder !
l ogout Resul t , ha ndl eEr r or ) ;
_model . l ogout ( r esponder ) ;
}
pr i va t e f unc t i on l ogi nResul t ( event : Resul t Event ,
t oken: Obj ec t = nul l ) : voi d {
_vi ew. l ogi nSt a c k. sel ec t edChi l d = _vi ew. l oggedl n;
_vi ew. pa sswor dl nput . t ext = "";
View
Model
J Add event
l i st ener f or
l ogi n
Add event
l i st ener f or
l ogout
Event
handl er f or
l ogi n event
Event
handl er f or
O l ogout event
Event
handl er f or
O l ogi n resul t
Al er t . show( " You ha ve l ogged i n a s: " + event . r esul t . na me) ;
}
pr i va t e f unc t i on l ogout Resul t ( event : Resul t Event ,
t oken: Obj ec t = nul l ) : voi d {
_vi ew. l ogi nSt a c k. sel ec t edChi l d = _vi ew. l oggedOut ;
Al er t . show( " You ha ve suc c essf ul l y l ogged out " ) ;
}
pr i va t e f unc t i on ha ndl eEr r or ( event : Fa ul t Event ,
t oken: Async Token =
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
Al er t . show( event . f a ul t . f a ul t st r i ng) ;
}
nul l ) : voi d {
Event
handl er f or
l ogout resul t
Er r or
O handl er
You start your Presenter by defi ni ng di e _vi ew O and _model © i nstance vari-
ables. I n di e constructor you assign di e vi ew r efer ence passed i n to your i nstance
vari abl e and create a new i nstance of your model . Then you add an event l i stener
for LOGI N_ BUTTON_ PRESSED event ©, assi gni ng the l ogi n handl er and an event
l i stener for di e LOGOUT_ BUTTON_ PRESSED event Q , assi gni ng di e l ogout handl er Q
to it.
www.it-ebooks.info
1 3 0 CHAPTER 7 Securing and personalizing your application
I nsi de di e l ogi n handl er, you create an Async Responder to pass i nto tire model ,
poi nti ng it to the l ogi nResul t handl er method Q and the er r or handl er Q . Then
you call tire l ogi n method on your model passing i n tire username, password, and
tire responder. I nsi de the l ogout handl er, you similarly create a r esponder poi nti ng
to the l ogout Resul t © and er r or handl er methods, tiren call the l ogout method
on your model passing i n tire responder.
When tire l ogi n method f r om tire model responds, your l ogi n result handl er is
i nvoked, and switches tire current vi ew state of tire l ogi n panel , blanks out tire pass-
wor d box contents so drat tire user wi l l be for ced to type i n a password the next time
she tries to l ogi n, and displays an Al er t stating that she has l ogged i n successfully. On
tire other side of tire equati on, when the l ogout method f r om tire model responds,
tire l ogout result handl er is cal l ed, whi ch switches tire vi ew stack back to tire i ni ti al
l ogged out state, and alerts tire user that she has l ogged out.
7.1.5 Creating a login manager
Now drat tire Presenter is created, you need to i mpl ement tire model so that you can
audrenti cate users agai nst tire appl i cati on. The fol l owi ng l i sti ng shows tire Logi nModel
for tire Logi nPa nel .
Li s t i n g 7 . 5 L o g i n M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. messa gi ng. Cha nnel Set ;
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . I Responder ;
i mpor t mx. r pc . r emot i ng. Remot eObj ec t ;
publ i c c l a ss Logi nModel {
pr i va t e va r _def a ul t Cha nnel Set : Cha nnel Set ; Get def aul t A
Channel Set
publ i c f unc t i on Logi nModel ( ) {
_def a ul t Cha nnel Set = Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ; <
}
publ i c f unc t i on l ogi n( user na me: St r i ng,
pa sswor d: St r i ng, O Logi n
r esponder : I Responder ) : voi d {
met hod
i f ( ! _def a ul t Cha nnel Set . a ut hent i c a t ed) {
va r t oken: Async Token = _def a ul t Cha nnel Set . l ogi n( user na me, pa sswor d) ;
t oken. a ddResponder ( r esponder ) ;
}
publ i c f unc t i on l ogout ( r esponder : I Responder ) : voi d {
va r t oken: Async Token = _def a ul t Cha nnel Set . l ogout ( ) ;
t oken. a ddResponder ( r esponder ) ;
}
J
Logout
met hod
www.it-ebooks.info
Authentication 1 3 1
The model for di e Logi nPa nel is si mpl e to start wi th. I nsi de di e constructor for di e
model , you get di e defaul t Cha nnel Set f r om your Cha nnel Set Fa c t or y O -
a n (
i assign
it to an i nstance vari abl e. I nsi de of di e l ogi n method Q , you first check to see i f di e
user is al ready l ogged i n, as tiiis someti mes results i n an er r or condi ti on, and BlazeDS
wi l l compl ai n about the Cha nnel Set bei ng al ready auti i enti cated. I f di e user is not
l ogged i n, it wi l l tiien call the l ogi n method on di e Cha nnel Set . The l ogout method
Q calls l ogout on the Cha nnel Set , not havi ng to wor r y about checki ng to see i f di e
user is currendy l ogged i n.
7.1.6 Updating the header
Now you need to update your Header . mxml to i ncl ude di e newl y created Logi nPa nel .
Li s t i n g 7 . 6 He a d e r . m xm l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: vi ew=" or g. f oj . vi ew. *"
wi dt h=" 100%"
hei ght =" 100" >
<s: l a yout >
<s: Hor i zont a l La yout / >
</ s: l a yout >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t mx. c ont a i ner s. Vi ewSt a c k;
publ i c va r vi ewSt a c k: Vi ewSt a c k;
] ] >
</ f x: Sc r i pt >
<mx: Spa c er wi dt h=" 5" / >
<s: Si mpl eText t ext =" Fl ex Bugs Appl i c a t i on"
hei ght =" 100%"
f ont Si ze=" 32 "
f ont Wei ght =" bol d"
ver t i c a l Al i gn=" mi ddl e" / >
<mx: Spa c er wi dt h=" 100%" / >
<s: VGr oup hei ght =" 100%" >
<vi ew: Logi nPa nel hei ght =" 100%" / >
<s: HGr oup i d=" t oggl eBut t onPa nel " wi dt h=" 100%" >
<mx: Spa c er wi dt h=" 100%" / >
<mx: Toggl eBut t onBa r da t a Pr ovi der =" vi ewSt a c k" / >
</ s: HGr oup>
</ s: VGr oup>
<mx: Spa c er wi dt h=" 5" / >
^ ^ Logi nPanel
</ s: Gr oup>
www.it-ebooks.info
132 CHAPTER 7 Securing and personalizing your application
The changes necessary to add the l ogi n panel to tire header are trivial. You've made a
few mi nor tweaks to tire l ayout and spaci ng components and onl y had to add one l i ne
of X ML to add tire Logi nPa nel O to tire header. When drat is done, all tirat's l eft is to
confi gur e BlazeDS to enabl e security.
7.1.7 Enabling security for Flex
I n or der to enabl e security for our appl i cati on, you need to make a small modi fi cati on
to the fl ex- spri ng- servl et.xml context fi l e.
Li s t i n g 7 . 7 f l e x -s p r i n g -s e r v l e t . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<bea ns xml ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns"
xml ns: f l ex=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on="
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns/ spr i ng- bea ns- 2. 5. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / f l ex/ spr i ng- f l ex- 1. 0. xsd" >
<f l ex: messa ge- br oker >
<f l ex: sec ur ed/ >
</ f l ex: messa ge- br oker >
</ bea ns>
Wi th all of that i n pl ace, it's time to run tire appl i cati on and l og i n. By defaul t, two
users are created i n AppFuse, a regul ar user witir the R0LE_ USER authori ty and an
admi ni strator witir tire ROLE_ AD MI N authority. The regul ar user's username is user witir
a password of user; and i n case you hadn't guessed, tire admi ni strator's username is
admin wi th a password of admin. After you bui l d and run tire appl i cati on you shoul d
be presented witir somethi ng that l ooks l i ke fi gur e 7.2.
L og i n wi th tire user and user account, and you'l l be pr esented wi th an Al er t
wi ndow tel l i ng you drat you've successfully l ogged i n. I f you mi stype tire password,
you shoul d be pr esented witir an er r or message stating that your credenti al s wer e
Username user P a s s w o rd L o g i n
[ Det ai l s Vi ew | Gr a p h Vi ew
S e ve ri ty S ta tu s
n u ll n u ll
I D :
P ro je ct: te st
D e sc ri p ti o n : te st
Fi gur e 7 .2 The l ogi n panel in act i on
www.it-ebooks.info
Authentication 133
i ncorrect. Thi s was the fi rst pi ece of functi onal i ty you wanted to i mpl ement i n this
chapter. Now l et's move on to addi ng auti i ori zati on to di e appl i cati on.
7.2 Aut hori zat i on
Someti mes authenti cati ng the users i sn't enough. You mi ght want to be abl e to selec-
tively secure speci fi c parts of the appl i cati on and not others. You can al l ow users who
are not l ogged i n to be abl e to browse di e list of open bugs and comments, but
restri ct l oggi ng new bugs to auti i enti cated users. Thi s is wher e auti i ori zati on comes
i nto play.
Many appl i cati on frameworks do not have tiiis l evel of support, so you end up hav-
i ng to put crosscutti ng concerns such as auti i ori zati on thr oughout di e code, sur-
r oundi ng certai n functi onal i ty wi th checks to see i f di e user is auti i enti cated or has
permi ssi ons to access that parti cul ar pi ece of functi onal i ty. I n this area the Spri ng
Security fr amewor k shines.
Spri ng Security l everages aspect- ori ented pr ogr ammi ng (AOP) to al l ow you to
appl y compl ex rules for who shoul d be abl e to execute method calls. You can even get
such fi ne- grai ned control tiiat you can al l ow l ogged i n users to add new issues and
comments and make changes to exi sti ng issues and comments, but restrict del eti ng to
admi ni strators. We won't be discussing AOP much i n tiiis book, so i f you'd l i ke to l earn
mor e about how to use AOP wi ti i Spri ng, check out Crai g Wal l s' excel l ent book Spring
in Action. The thi rd edi ti on is to be publ i shed i n December 2010. (http:/ / manni ng.
com/ wal l s4/ ).
7.2.1 Flex Spring Security primer
The Spri ng BlazeDS I ntegr ati on provi des several di ffer ent meti i ods of securi ng the
appl i cati on. You'l l start wi th the broadest contr ol and wor k your way to mor e and
mor e fi ne- grai ned control . The fi rst meti i od you coul d use is to secure an enti re AMF
channel usi ng the flex-spring-servlet.xml as shown here, but tiiis woul d not be desir-
abl e because you l ose all ability to defi ne di ffer ent levels of security for di ffer ent parts
of di e appl i cati on.
<f l ex: messa ge- br oker >
<f l ex: sec ur ed>
<f l ex: sec ur ed- c ha nnel c ha nnel =" my- a mf " a c c ess=" ROLE_USER" / >
</ f l ex: sec ur ed>
</ f l ex: messa ge- br oker >
The next method is to secure di e appl i cati on by addi ng securi ty constrai nts
directiy to the destinations by confi guri ng the destination i n a remoti ng- confi g.xml
as shown here.
<dest i na t i on i d=" i ssueSer vi c e" >
<sec ur i t y>
<sec ur i t y- c onst r a i nt s
<a ut h- met hod>Cust om</ a ut h- met hod>
www.it-ebooks.info
1 3 4 CHAPTER 7 Securing and personalizing your application
<r ol es>
<r ol e>ROLE_USER</ r ol e>
</ r ol es>
</ sec ur i t y- c onst r a i nt >
</ sec ur i t y>
</ dest i na t i on>
This would apply a security constraint for the i ssueServi ce, on a system-wide level,
allowing only users in the role ROLE_USER access to this destination. This method of
securing an application, while simple, will not work for what you're trying to do with
the application for a couple of reasons. This would effectively cut off any ability to do
method-level authorization for the application. In addition, you are not defining the
destinations using a remoting-config.xml. You're allowing the Spring BlazeDS Integra-
tion to dynamically configure the remoting destinations for you.
Moving on to a more finely grained security, you can set up a global method inter-
ceptor using AOP pointcut syntax to define a pattern of methods you want to secure.
The following code shows an example of this taken from the security.xml file provided
by AppFuse.
<gl oba l - met hod- sec ur i t y>
<pr ot ec t - poi nt c ut
expr essi on=" exec ut i on( * *. . ser vi c e. User Ma na ger . get User s( . . ) ) "
a c c ess=" ROLE_AD MI N" / >
</ gl oba l - met hod- sec ur i t y>
This will constrain any call to a method named getUsers contained in a class or
interface named UserManager whose package name ends with " ser vi ce ". As you can
see this method allows you to apply very complex patterns to define which methods
get secured.
<bea n i d=" i ssueSer vi c e" c l a ss=" or g. f oj . ser vi c e. i mpl . I ssueMa na ger l mpl " >
<c onst r uc t or - a r g r ef =" i ssueD a o" / >
<c onst r uc t or - a r g r ef =" c omment Ser vi c e" / >
<sec ur i t y: i nt er c ept - met hods>
<sec ur i t y: pr ot ec t met hod=" sa ve"
a c c ess=" ROLE_USER, ROLE_AD MI N" / >
<sec ur i t y: pr ot ec t met hod=" r emove*"
a c c ess=" ROLE_AD MI N" / >
</ sec ur i t y: i nt er c ept - met hods>
</ bea n>
The code shows how to secure methods at the bean level in XML by using the Spring
application context. This gives you more localized control over the security than the
global method illustrated previously, keeping the security constraints closer to the code
that it affects.
publ i c i nt er f a c e I ssueMa na ger {
@Sec ur ed( {" ROLE_USER" , " ROLE_AD MI N" })
@Remot i ngI nc l ude
I ssue sa ve( I ssue i ssue) ;
www.it-ebooks.info
Authentication 135
( i Sec ur ed( {" ROLE_ADMI N" })
( i Remot i ngl nc l ude
voi d r emove( Long i d) ;
}
The code shows di e fi nal meti i od of securi ng di e business meti i ods by usi ng di e
@Secured annotati on. Thi s is the most l ocal i zed meti i od of security and the meti i od
you'r e goi ng to use i n upcomi ng exampl es. Thi s keeps the decl ar ed security con-
straints ri ght wi th di e code you'r e tryi ng to secure. The oti i er advantage to usi ng di e
annotati ons over the other meti i ods is that i f peopl e deci de to over r i de what you've
defi ned i n di e code, tiiey can over r i de it usi ng di e XML confi gur ati on.
7.2.2 Spring Integration Security
I n or der for di e Fl ex appl i cati on to be abl e to take advantage of usi ng Spri ng Security
for auti i ori zati on, you first need to add di e Spri ng I ntegrati on Security dependency to
the pom. xml i n di e f l ex- bugs- web proj ect.
Li s t i n g 7 . 8 Sp r i n g I n t e g r a t i o n Se c u r i t y d e p e n d e n c y
<dependenc y>
<gr oupI d>or g. spr i ngf r a mewor k. i nt egr a t i on- ; / gr oupI d>
<a r t i f a c t l d>spr i ng- i nt egr a t i on- sec ur i t y</ a r t i f a c t l d>
<ver si on>l . 0. 3. RELEASE</ ver si on>
</ dependenc y>
By addi ng tiiis dependency, BlazeDS wi l l use a speci al Logi nComma nd obj ect on di e
server side that enabl es di e Cha nnel Set l ogi n and l ogout functi onal i ty to i ntegrate
wi th Spri ng Security's authori zati on mechani sms by returni ng the username and any
authori ti es that the user has i n the result event. I t also does er r or transl ati ng on the
server side to translate security excepti ons that may occur i nto thei r BlazeDS security
excepti on equi val ent. Now the er r or can be r epor ted back to the Fl ex cl i ent i nstead of
r etur ni ng an HTTP 403 status code, whi ch wi l l break di e appl i cati on. You can r ead
mor e about di e Spri ng I ntegr ati on Security i n the docs for the Spri ng BlazeDS I nte-
grati on at http:/ / stati c.spri ngsource.org/ spri ng- fl ex/ docs/ 1.0.x/ reference/ html / .
7.2.3 @Secured annotations
Ther e are a number of meti i ods you can use to secure your appl i cati on; we have cho-
sen to conti nue al ong the path of usi ng annotati ons wher e possi bl e to decl are whi ch
i nter face methods we want to secure and what security constraints we want to pl ace on
them. We'l l start by addi ng di e necessary annotati ons to the I ssueManager.
Li s t i n g 7 . 9 I s s u e M a n g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . I ssue;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngD est i na t i on;
www.it-ebooks.info
1 3 6 CHAPTER 7 Securing and personalizing your application
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngl nc l ude;
i mpor t or g. spr i ngf r a mewor k. sec ur i t y. a nnot a t i on. Sec ur ed;
i mpor t j a va x. j ws. WebSer vi c e;
( i WebSer vi c e
@Remot i ngD est i na t i on( c ha nnel s = {" my- a mf " })
publ i c i nt er f a c e I ssueMa na ger {
( i Remot i ngl nc l ude
j a va . ut i l . Li st <I ssue> get AHO;
( i Remot i ngl nc l ude
I ssue get ( Long i d) ;
@Sec ur ed( {
M
ROLE_USER
M
, " ROLE_AD MI N" })
( i Remot i ngl nc l ude
I ssue sa ve( I ssue i ssue) ;
( i Sec ur ed( {" ROLE_ADMI N" })
( i Remot i ngl nc l ude
voi d r emove( Long i d) ;
J

save met hod
annot at i on
remove met hod
annot at i on
You've added an @Secured annotati on to di e save method © and decl ar ed tiiat onl y
users havi ng ROLE_USER and ROLE_ADMIN pri vi l eges can add and update issues. You
defi ned botir rol es si nce your rol es are not overl appi ng, meani ng that ROLE_ADMIN is
not a superset of ROLE_USER but ratirer separate al togeti rer. Next you decl are tire
remove method to be usable onl y by those who have di e ROLE_ADMIN granted to
dr em ©. Next you add tire necessary annotati ons to the CommentManager.
Li s t i n g 7 . 1 0 Co m m e n t M a n a g e r . j a v a
pa c ka ge or g. f oj . ser vi c e;
i mpor t or g. f oj . model . Comment ;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngD est i na t i on;
i mpor t or g. spr i ngf r a mewor k. f l ex. r emot i ng. Remot i ngl nc l ude;
i mpor t or g. spr i ngf r a mewor k. sec ur i t y. a nnot a t i on. Sec ur ed;
i mpor t j a va x. j ws. WebSer vi c e;
i mpor t j a va . ut i l . Li st ;
( i WebSer vi c e
@Remot i ngD est i na t i on( c ha nnel s = {" my- a mf " })
publ i c i nt er f a c e Comment Ma na ger {
( i Remot i ngl nc l ude
Li st <Comment > f i ndComment sByl ssuel d( Long i ssuel d) ;
( i Sec ur ed ( { " ROLE_AD MI N" } )
( i Remot i ngl nc l ude
voi d del et eAHComment sFor l ssuel d( Long i ssuel d) ;
del et e AIICom m ent sForl ssuel d
met hod annot at i on
( i Remot i ngl nc l ude
Comment get ( Long i d)
www.it-ebooks.info
Authentication 137
@Sec ur ed( {" ROLE_USER" , " ROLE_AD MI N" })
( i Remot i ngl nc l ude
Comment sa ve( Comment c omment ) ;
( i Sec ur ed ( { " ROLE_AD MI N" } )
( i Remot i ngl nc l ude
voi d r emove( Long i d) ;
save met hod
annot at i on
remove met hod
annot at i on
Si mi l ar to the I ssueMa na ger annotati ons, you start by decl ari ng that onl y member s
of ROLE_ AD MI N can call the del et eAHComment s For l s s uel d O
a n(
i r emove Q meth-
ods. Then you decl are that di e sa ve method can be cal l ed by users wi ti i ei ther
ROLE_ USER or ROLE_ AD MI N pri vi l eges Q . Noti ce that you never speci fi ed any security
constraints for di e get methods of your services. Thi s ensures tiiat anyone can call
them whether or not they're auti i enti cated to di e appl i cati on. Now that you've
decl ar ed the security wi ti i annotati ons, you need to enabl e support for these annota-
ti ons i n Spri ng Security.
7.2.4 Overriding default security settings
AppFuse has Spri ng Security i nstal l ed and confi gur ed out of di e box, so to extend
upon tiiat you need to extract its security.xml confi gur ati on and put tiiat i n the
f l ex- bugs- web pr oj ect i n the WEB- I NF fol der al ongsi de di e oti i er Spri ng confi gura-
ti on files. To do this you copy the security.xml tiiat is i ncl uded i n di e appfuse-web-
common. war tiiat basically is overl ai d on top of di e flex-bugs-web.war when you bui l d
this proj ect.
Li s t i n g 7 . 1 1 s e c u r i t y . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<bea ns: bea ns xml ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xml ns: bea ns=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns"
xsi : sc hema Loc a t i on=" ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / bea ns/ spr i ng- bea ns- 2. 0. xsd
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y
ht t p: / / www. spr i ngf r a mewor k. or g/ sc hema / sec ur i t y/
spr i ng- sec ur i t y- 2. 0. 1. xsd" >
<ht t p a ut o- c onf i g=" t r ue" l ower c a se- c ompa r i sons=" f a l se" >
<i nt er c ept - ur l pa t t er n=" / a dmi n/ *" a c c ess=" ROLE_AD MI N" / >
<i nt er c ept - ur l pa t t er n=" / pa sswor dHi nt . ht ml *"
a c c ess=" ROLE_ANONYMOUS, ROLE_AD MI N, ROLE_USER" / >
<i nt er c ept - ur l pa t t er n=" / si gnup. ht ml *"
a c c ess=" ROLE_ANONYMOUS, ROLE_AD MI N, ROLE_USER" / >
<i nt er c ept - ur l pa t t er n=" / a 4j . r es/ *. ht ml *"
a c c ess=" ROLE_ANONYMOUS, ROLE_AD MI N, ROLE_USER" / >
<f or m- l ogi n l ogi n- pa ge=" / l ogi n. j sp"
a ut hent i c a t i on- f a i l ur e- ur l =" / l ogi n. j sp?er r or =t r ue"
l ogi n- pr oc essi ng- ur l =" / j _sec ur i t y_c hec k" / >
Securi t y by
ur l pat t er n
www.it-ebooks.info
1 3 8 CHAPTER 7 Securing and personalizing your application
<r emember - me user - ser vi c e- r ef =" user D a o"
key="e37 f4b31- 0c45- l l dd- bd0b- 0800200c9a66"/ >
</ ht t p>
<a ut hent i c a t i on- pr ovi der user - ser vi c e- r ef =" user D a o" >
<pa sswor d- enc oder r ef =" pa sswor dEnc oder " / >
</ a ut hent i c a t i on- pr ovi der >
Aut hent i cat i on
pr ovi der
Enabl e secur i t y
annot at i ons
<gl obal - method- secur i ty
secured- annotati ons="enabl ed" j sr 250- annotati ons="enabl ed">
<pr otect- poi ntcut
. ser vi c e. User Ma na ger . get User s( . . ) ) "
i i ri t y Q
:ions T
. ser vi c e. User Ma na ger . r emoveUser ( . . ) ) "
expr essi on=" exec ut i on( * *.
a c c ess=" ROLE_AD MI N" / >
<pr ot ec t - poi nt c ut
expr essi on=" exec ut i on( * *.
a c c ess=" ROLE_AD MI N" / >
</ gl oba l - met hod- sec ur i t y>
</ bea ns: bea ns>
Li sti ng 7.11 shows the modi fi ed security.xml, whi ch for tire most part is i denti cal to
tire security.xml i ncl uded i n AppFuse. The first secti on Q , whi ch is confi gur ed by
AppFuse, dictates whi ch URL patterns to i nter cept and pass thr ough tire security fil-
ters. You don't need to speci fy anyti ri ng i n this secti on for tire Fl ex appl i cati on as tire
Spri ng I ntegr ati on Security handl es all the fi l ter i ng for tire Fl ex and BlazeDS i nterac-
tions. The second secti on Q defi nes tire authenti cati on provi der, whi ch i n tiris case is
usi ng tire defaul t user D a o pr ovi ded by AppFuse. I f you wanted to change drat meti r od
of authenti cati on to an LDAP server, for instance, you woul d confi gur e it tirere.
I n the last segment Q you added a coupl e of attri butes to the gl oba l - met hod-
sec ur i t y tag to set tire sec ur ed- a nnot a t i ons to ena bl ed and tire j sr 250- a nnot a t i ons
to ena bl ed as wel l .
7.2.5 Updating IssueModel and CommentModel
Now all that's l eft to enabl e authori zati on to wor k i n tire Fl ex appl i cati on is to modi fy
tire model s to use the Cha nnel Set Fa c t or y you created earlier. The fol l owi ng l i sti ng
shows tire changes for tire I ssueModel .
Li s t i n g 7 . 1 2 I s s u e M o d e l . a s
pa c ka ge or g. f oj . model {
publ i c c l a ss I ssueModel {
pr i va t e va r _i ssueSer vi c e: Remot eObj ec t ;
publ i c f unc t i on I ssueModel ( ) {
va r def a ul t Cha nnel Set : Cha nnel Set =
Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ;
_i ssueSer vi c e = new Remot eObj ec t ( ) ;
_i ssueSer vi c e. dest i na t i on = " i ssueSer vi c e"
J
Get Channel Set
www.it-ebooks.info
Persona liza tion 1 3 9
_i ssueSer vi c e. c ha nnel Set = def a ul t Cha nnel Set ;
Set channel Set
on servi ce
As you can see the i mpact of addi ng tiiis functi onal i ty to the Fl ex appl i cati on is mi ni -
mal . First you get the defaul t Cha nnel Set f r om the Cha nnel Set Fa c t or y ©, j n s l as you
di d earl i er for di e Logi nModel , and you set the c ha nnel Set pr oper ty on the
Remot eObj ec t © to the def a ul t Cha nnel Set . The fol l owi ng listing shows the same
changes for the Comment Model .
Li s t i n g 7 . 1 3 Co m m e n t M o d e l . a s
pa c ka ge or g. f oj . model {
publ i c c l a ss Comment Model {
pr i va t e va r _c omment Ser vi c e: Remot eObj ec t ;
publ i c f unc t i on Comment Model ( ) {
va r def a ul t Cha nnel Set : Cha nnel Set =
Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ;
_c omment Ser vi c e = new Remot eObj ec t ( ) ;
_c omment Ser vi c e. dest i na t i on = " c omment Ser vi c e" ;
_c omment Ser vi c e. c ha nnel Set = def a ul t Cha nnel Set ;
}
Now you can bui l d and run the appl i cati on and
i f you try to save or del ete an i tem wi thout bei ng
l ogged i n wi th the pr oper auti i ori ti es granted,
you wi l l be pr esented wi ti i an er r or message l i ke
that i n fi gur e 7.3
Agai n, di e error handl i ng is si mpl e, displaying
the faul t message i n an Al er t box. Noti ce that the
er r or message accuratel y descri bes di e error. The
last security enhancement you'r e goi ng to make
to di e appl i cati on is to add personal i zati on.
Personal i zat i on
When you thi nk about l ever agi ng a security fr amewor k i n the Fl ex appl i cati on, you
probabl y don't tiiink about personal i zati on, even though the two are closely rel ated.
Recal l earl i er when we discussed di e Spri ng I ntegr ati on Security modul e, you saw
that one of di e tilings r etur ned i n di e Resul t Event is di e username of di e per son
who was audi enti cati ng.
J
Get Channel Set
Set channel Set
on servi ce
Fi gur e 7 .3 Error when t r yi ng t o execut e
a met hod wi t hout aut hor i zat i on
www.it-ebooks.info
1 4 0 CHAPTER 7 Securing and personalizing your application
Now that the user has authenti cated to the appl i cati on, you can use the i nfor ma-
tion r etur ned f r om the l ogi n process to get mor e i nfor mati on such as the user's fi rst
and last names. Why not j ust use di e username tiiat the user typed i nto di e l ogi n box
you ask? Si mpl e. I f you wai t for di e l ogi n meti i od to return successfully and take di e
val ue r etur ned instead, you are guar anteed tiiat the user has fi rst authenti cated, and
tiiat the username r etur ned i n the Resul tE vent is di e correct username for tiiat user.
7.3.1 Adding the UserService to the LoginModel
Because the Resul tE vent r etur ned f r om l oggi ng i n and out of di e Channel Set onl y
i ncl udes the user name, you'l l have to use anoti i er method to get the user's ful l name
f r om di e appl i cati on. Fortunatel y AppFuse exposes this functi onal i ty i n the userDao
obj ect; you still have to tel l BlazeDS to expose this to the Fl ex appl i cati on. So you
need to add the fol l owi ng l i ne to the flex-spring-servlet.xml i n the sr c/ mai n/
webapp/ WEB- I NF fol der of the f l ex- bu gs- web proj ect:
<f l ex: r emot i ng- dest i na t i on r ef =" user D a o" / >
Thi s one l i ne of xml confi gur ati on accompl i shes the same thi ng you di d i n chapter 5
wi th the ORemoti ngDesti nati on annotati ons, the di ffer ence bei ng tiiat you don't have
to crack open di e AppFuse source code to expose tiiis Spri ng bean as a r emote servi ce
to Fl ex. Now l et's add tiiis servi ce to the Logi nModel .
Li s t i n g 7 . 1 4 L o g i n M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. messa gi ng. Cha nnel Set ;
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . I Responder ;
i mpor t mx. r pc . r emot i ng. Remot eObj ec t ;
publ i c c l a ss Logi nModel { - « „
userServi ce
pr i va t e va r _user Ser vi c e: Remot eObj ec t ;
pr i va t e va r _def a ul t Cha nnel Set : Cha nnel Set ;
J
publ i c f unc t i on Logi nModel ( ) {
_def a ul t Cha nnel Set = Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ;
_user Ser vi c e = new Remot eObj ec t ( ) ;
_user Ser vi c e. dest i na t i on = " user Da o" ;
_user Ser vi c e. Cha nnel Set = _def a ul t Cha nnel Set ;
}

Creat i ng
Remot eObj ect
publ i c f unc t i on get User D et a i l s( user na me: St r i ng,
r esponder : I Responder ) : voi d {
va r t oken: Async Token = _user Ser vi c e. l oa dUser ByUser na me( user na me) ;
t oken. a ddResponder ( r esponder ) ;
}
get UserDet ai l s
met hod
}
}
www.it-ebooks.info
Persona liza tion 1 4 1
First you defi ne an i nstance vari abl e for tire user Ser vi c e O and create a new i nstance
of it i n the constructor Q . As witir other r emote obj ects, you set its desti nati on to
user D a o because that is what tire Spri ng bean is defi ned as, and you set tire c ha nnel -
Set to the def a ul t Cha nnel Set that you got f r om tire Cha nnel Set Fa c t or y. As a fi nal
step you defi ne a meti r od cal l ed get User D et a i l s ©, whi ch takes as its first ar gument
the username to l ook up and a r esponder to call back to when tire servi ce returns.
Now let's update tire Logi nPr esent er to use this new functi onal i ty.
7.3.2 Updating the LoginPresenter
You need to make a coupl e of mi nor modi fi cati ons to tire Logi nPr esent er to use tire
meti r od you j ust created i n the Logi nModel .
Li s t i n g 7 . 1 5 Lo g i n Pr e s e n t e r . a s
pa c ka ge or g. f oj . pr esent er {
publ i c c l a ss Logi nPr esent er {
pr i va t e va r _vi ew: Logi nPa nel ;
pr i va t e va r _model : Logi nModel ;
publ i c f unc t i on Logi nPr esent er ( vi ew: Logi nPa nel ) {
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( User Event . USER_LOGGED _I N,
get User D et a i l s) ;
pr i va t e f unc t i on l ogi nResul t ( event : Resul t Event ,
t oken: Obj ec t = nul l ) : voi d
_vi ew. l ogi nSt a c k. sel ec t edChi l d = _vi ew. l oggedl n;
_vi ew. pa sswor dl nput . t ext = "";
va r user Loggedl nEvent : User Event =
new User Event ( User Event . USER_LOGGED _I N) ;
user Loggedl nEvent . da t a = event . r esul t . na me;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( user Loggedl nEvent ) ;
}
pr i va t e f unc t i on l ogout Resul t ( event : Resul t Event ,
t oken: Obj ec t = nul l ) : voi <
_vi ew. user Na me. t ext = "";
_vi ew. l ogi nSt a c k. sel ec t edChi l d = _vi ew. l oggedOut ;
Al er t . show( " You ha ve suc c essf ul l y l ogged out " ) ;
va r user Cha ngedEvent : User Event =
new User Event ( User Event . CURRENT_USER_UPD ATED ) ;
user Cha ngedEvent . da t a = nul l ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
A Event l i st ener f or
q T user l ogged i n
J
Event handl er
f or user l ogged
i n resul t
A Event handl er
f or user l ogged
, out r esul t
d {
www.it-ebooks.info
142 CHAPTER 7 Securing and personalizing your application
. di spa t c hEvent ( user Cha ngedEvent ) ;
Ey ent ha nd
|
er
f
or
Q
' user l ogged i n I
pr i va t e f unc t i on get User D et a i l s ( event : User Event = nul l ) : voi d { <3—'
va r r esponder : I Responder = new Async Responder (
get User D et a i l sResul t , ha ndl eEr r or ) ;
}
model . get User D et a i l s( event . da t a , r esponder ) ; „ „ ,
~ ' ^ A Handl er f or
userServi ce
pr i va t e f unc t i on get User D et a i l sResul t ( event : Resul t Event , <
t oken: Obj ec t = nul l ) : voi d {
va r user = event . r esul t ;
_vi ew. user Na me. t ext = user . f ul l Na me;
Al er t . show( " Wel c ome Ba c k " + user . f ul l Na me) ;
va r user Cha ngedEvent : User Event =
new User Event ( User Event . CURRENT_USER_UPD ATED ) ;
user Cha ngedEvent . da t a = user ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. di spa t c hEvent ( user Cha ngedEvent ) ;
}
r esul t
}
}
The fi rst change you make is to add a l i stener for di e USER_ LOGGED _ I N event © so that
you know when you need to update the user details. Next you make a sl i ght modi fi ca-
tion to the method tiiat is cal l ed when di e result comes back f r om the call to l og i n on
di e I ssueModel ©. Her e you take the username f r om the event result and create a
new User Event of type USER_ LOGGED _ I N, and you set di e event's da t a pr oper ty to di e
username. Thi s allows you to pass al ong di e username to whoever woul d want to
r espond to a user l oggi ng i n. You do someti i i ng si mi l ar i n the l ogged out result han-
dl er © except you create a CURRENT_ USER_ UPD ATED event to noti fy other parts of di e
appl i cati on that the currentl y l ogged i n user has been changed, and set its da t a prop-
erty to nul l .
Next you defi ne the event handl er for di e USER_ LOGGED _ I N event l i stener you
defi ned i n di e constructor Q . I nsi de tiiis method you create an Async Responder
obj ect and make a call to di e get User D et a i l s meti i od on di e I ssueModel you defi ned
i n di e previ ous secti on. When the result f r om this call comes back, it is handl ed by di e
get User D et a i l sResul t method © wher e you update di e vi ew to show di e current
user's ful l name, and you create a new CURRENT_ USER_ UPD ATED event setti ng its da t a
pr oper ty to the User obj ect that came back i n di e Resul t Event .
Now l et's l ook at updati ng the D et a i l Pr esent er and Comment sLi st Pr esent er ,
whi ch wi l l be l i steni ng for di e CURRENT_ USER_ UPD ATED event tiiat you j ust added.
7.3.3 Updating the DetailPresenter and CommentsListPresenter
Now tiiat the Logi nPr esent er is broadcasti ng an event that noti fi es the rest of the
appl i cati on that the currentl y l ogged i n user has changed, you can add event listeners
www.it-ebooks.info
Persona liza tion 1 4 3
to the other parts of tire appl i cati on that may want to listen for that. You'l l start wi th
the Det ai l P r es en t er so that you can defaul t tire text i n the author fi el d for any new
issues to tire currentl y l ogged i n user. The fol l owi ng listing shows the changes needed
to add dris to the Det ai l Pr esent er .
Li s t i n g 7 . 1 6 De t a i l Pr e s e n t e r
pa c ka ge or g. f oj . pr esent er {
J
publ i c c l a ss D et a i l Pr esent er {
pr i va t e va r _c ur r ent User : User ;
pr i va t e va r _i ssue: I ssue;
pr i va t e va r _vi ew: D et a i l Vi ew;
pr i va t e va r _i ssueModel : I ssueModel ;
publ i c f unc t i on D et a i l Pr esent er ( vi ew: D et a i l Vi ew) {
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( User Event . CURRENT_USER_UPD ATED ,
c ur r ent User Cha nged) ;
Inst ance vari abl e f or
cur r ent user
J
Event l i st ener
f or cur r ent
user changi ng
pr i va t e f unc t i on c a nc el Cha nges( event : UI Event = nul l ) : voi d {
sel ec t edl ssue = new I s s ued;
sel ec t edl ssue. r epor t edBy = _c ur r ent User . f ul l Na me;
va r event : UI Event = new UI Event ( UI Event . SELECTED _I SSUE_CHANGED ) ;
event . da t a = sel ec t edl ssue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( event ) ;
Event handl er f or A
cur r ent User Changed I
pr i va t e f unc t i on c ur r ent User Cha nged ( event : User Event ) : voi d { <1—'
_c ur r ent User = event . da t a ;
i f ( sel ec t edl ssue. i d == 0) {
_vi ew. i ssueRepor t edBy. t ext = _c ur r ent User == nul l ?
"" : _c ur r ent User . f ul l Na me;
}
First you add an i nstance vari abl e for tire D et a i l Pr esent er to be abl e to cache the
current user i n Q< Next you add an event l i stener for tire CURRENT_ USER_ UPD ATED
event Q and poi nt it at tire c ur r ent User Cha nged event handl er. I nsi de the c a nc el -
Cha nges event handl er, whi ch is i nvoked each time tire user wants to cl ear out the
changes made i n tire detai l for m and creates a new issue, you set tire defaul t for the
r epor t edBy pr oper ty to the current user's ful l name Last you i mpl ement an
Q Def aul t
aut hor f i el d
www.it-ebooks.info
1 4 4 CHAPTER 7 Securing and personalizing your application
event l i stener for the current user changi ng wher e you set the i nstance vari abl e
of current user to the user that was passed al ong i n di e event. Then you update the
r epor t ed by fi el d on the vi ew i f di e currendy di spl ayed issue is not an exi sti ng
issue. The fol l owi ng l i sti ng shows the changes for the Comment sLi st Pr esent er .
Li s t i n g 7 . 1 7 Co m m e n t s L i s t Pr e s e n t e r
pa c ka ge or g. f oj . pr esent er {
J
Inst ance vari abl e
f or cur r ent user
publ i c c l a ss Comment sLi st Pr esent er {
pr i va t e va r _c ur r ent User : User ;
pr i va t e va r _sel ec t edl ssue: I ssue;
pr i va t e va r _sel ec t edComment : Comment ;
pr i va t e va r _c omment Model : Comment Model ;
pr i va t e va r _vi ew: Comment sVi ew;
pr i va t e va r _popl : Edi t Comment For m;
publ i c f unc t i on Comment sLi st Pr esent er ( vi ew: Comment sVi ew = nul l ) {
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) < —. Event l i st ener f or
. a ddEvent Li st ener ( User Event . CURRENT_USER_UPD ATED , Q user changed
c ur r ent User Cha nged) ;
}
pr i va t e f unc t i on a ddNewComment ( event : * = nul l ) : voi d {
sel ec t edComment = new Comment ( ) ;
sel ec t edComment . i ssue = sel ec t edl ssue;
_popl = PopUpMa na ger . c r ea t ePopUp( ( _vi ew a s Ul Component ) . r oot ,
Edi t Comment For m, t r ue) a s Edi t Comment For m;
_popl . a ut hor . t ext = _c ur r ent User . f ul l Na me;
PopUpMa na ger . c ent er PopUp( _popl a s Ul Component ) ;
}
Def aul t
aut hor f i el d
pr i va t e f unc t i on c ur r ent User Cha nged ( event : User Event ) : voi d { <1—i
_c ur r ent User = event . da t a ;
} Event handl er f or I
user changed event O
As wi th di e D et a i l Pr esent er , you start by defi ni ng an i nstance vari abl e to al l ow tiiis
Presenter to cache the currentl y l ogged i n user Q . After tiiat, you add an event lis-
tener for the CURRENT_ USER_ UPD ATED event Q poi nti ng it to the c ur r ent User Cha nged
method wher e you set the current user to di e user passed i n wi ti i the event. I nsi de
di e a ddNewComment meti i od you defaul t di e text of di e Aut hor fi el d i n di e comment
pop up to be di e current user's ful l name ©.
www.it-ebooks.info
Summary 145
I B
Add/Edit Comment
Ajlhor:
Daie:
coi n ment
Save Commem
Fi gur e 7 .4 Add new com m ent def aul t s Aut hor t o cur r ent l y l ogged in user
Now bui l d and run the appl i cati on. I f you l og i n usi ng the Tomcat User username of
user and password of user and try to add a new comment to an issue, you shoul d see
that the Aut hor fi el d is now defaul ti ng to tire l ogged i n user's ful l name as shown i n
fi gur e 7.4. When you l og out you shoul d see drat the fi el ds are no l onger bei ng
defaul ted to anythi ng.
Summary
When you started this chapter, you had an appl i cati on whi ch anybody coul d have
added critical issues to and r emoved i mpor tant issues f r om wi th no control s to pre-
vent such destructi ve behavi or. Over tire course of tire chapter you added measures to
contr ol access.
You started by addi ng the si mpl est of security constraints to the appl i cati on, allow-
i ng tire users to authenti cate to the server side, al though tiris doesn't do you much
good unti l you can contr ol what tire users do to tire data. After you added tire authori -
zati on constraints, you had fi ne- grai ned control over who coul d modi fy and del ete the
data. Thi s is i mportant, because befor e Spri ng Security was devel oped, tire most com-
mon way to decl arati vel y defi ne security constraints this way at tire method l evel was to
use EJ Bs and contai ner- managed security, whi ch woul d probabl y have made tiris tight
i ntegrati on di ffi cul t to create.
Even i n tire fai rl y si mpl e exampl e you have been abl e to defi ne three di ffer ent lev-
els of security for tire appl i cati on wi th mi ni mal i ntrusi on to tire exi sti ng web appl i ca-
ti on. The ability to decl arati vel y defi ne security constraints on tire business methods
www.it-ebooks.info
1 4 6 CHAPTER 7 Securing and personalizing your application
by using either the @Secured annotations or using AOP pointcut syntax is extremely
powerful. This means that you no longer have to litter the source code with i f state-
ments checking if users are l ogged in and whether or not they have the right level of
access to perform the operation.
The last thing you did in the j ourney through this chapter was to add functionality
that doesn't do much for securing the application, but will likely delight the users for
the simple fact that the application is personalized to them. They no longer have to
type their names into the author fields when adding new issues and comments, and
can see that they are l ogged in, and whom they are l ogged in as.
In the next chapter you're goi ng to continue enhancing the application by adding
data visualization to put a bird's-eye view on the data. You're going to tackle creating a
pie chart component from scratch using the Degrafa framework.
www.it-ebooks.info
Thi s chapt er covers
• I n t ro d u c i n g t h e D e g ra f a d ra w i n g l i b ra ry
• C re a t i n g a c u s t o m P i e C h a rt c o m p o n e n t
• C re a t i n g a n I t e m R e n d e re r f o r a D a t a G ri d
• D y n a m i c o b j e c t c re a t i o n
Now that your application is secured and communicating with tire server side, it's
time to add data visualization components and enable a bird's-eye view on tire data.
Addi ng data visualization components to your application allows peopl e to see at a
glance tire open proj ect issues and the number of bugs versus the number of fea-
ture requests, without having to manually count them in tire data gri d in tire master
view. The data could be visualized in many ways—we'll only scratch tire surface in
this chapter.
Adobe provides data visualization components, but only when you purchase a
license for tire professional version of the Flash Builder IDE. Because our goal is to
do Flex devel opment using only free and open source technologies, we've deci ded
to create our own visualization components—besides, it's more fun.
147
www.it-ebooks.info
1 4 8 CHAPTER 8 Charting with Dégrafa
8.1 Drawi ng i n Fl ex
Fl ex and Flash pr ovi de power ful drawi ng l i brari es tiiat we coul d l everage to create our
custom gr aph components, but we'r e goi ng to l everage an open source graphi cs l i brary
cal l ed Degr afa. Usi ng Degr afa gi ves us di e ability to decl arati vel y bui l d our gr aphi ng
components rather tiian havi ng to deal wi ti i di e compl ex cal cul ati ons i nvol ved i n draw-
i ng pi e chart slices as i l l ustrated i n listing 8.1, whi ch shows an exampl e Acti onScr i pt
class speci fi cal l y for drawi ng a pi e chart slice found at http:/ / www.adobe.com/ devnet/
flash/ articles/ adv_draw_mediods.html. Noti ce how much tr i gonometr y is i nvol ved i n
creati ng somethi ng as si mpl e as a pi e chart slice f r om scratch.
Li s t i n g 8 . 1 Ex a m p l e of d r a w i n g i n Ac t i o n Sc r i p t
/ *
mc . dr a wWedge i s a met hod f or dr a wi ng pi e sha ped
wedges. Ver y usef ul f or c r ea t i ng c ha r t s. Spec i a l
t ha nks t o: Rober t Penner , Er i c Muel l er a nd Mi c ha el
Hur wi c z f or t hei r c ont r i but i ons.
*/
Movi eCl i p. pr ot ot ype. dr a wWedge = f unc t i on( x, y, st a r t Angl e, a r c ,
r a di us, yRa di us) {
/ / mc . dr a wWedge( ) - by Ri c Ewi ng ( r i c @f or mequa l sf unc t i on. c om) -
ver si on 1. 3 - 6. 12. 2002
/ / x, y = c ent er poi nt of t he wedge.
/ / st a r t Angl e = st a r t i ng a ngl e i n degr ees.
/ / a r c = sweep of t he wedge. Nega t i ve va l ues dr a w c l oc kwi se.
/ / r a di us = r a di us of wedge. I f [ opt i ona l ] yRa di us i s def i ned,
t hen r a di us i s t he x r a di us.
/ / yRa di us = [ opt i ona l ] y r a di us f or wedge.
/ / ==============
/ / Tha nks t o: Rober t Penner , Er i c Muel l er a nd Mi c ha el Hur wi c z
f or t hei r c ont r i but i ons.
/ / ==============
i f ( a r gument s. l engt h<5) {
r et ur n;
/ / move t o x, y posi t i on
t hi s. moveTo( x, y) ;
/ / i f yRa di us i s undef i ned, yRa di us = r a di us
i f ( yRa di us == undef i ned) {
yRa di us = r a di us;
}
/ / I ni t va r s
va r segAngl e, t het a , a ngl e, a ngl eMi d, segs, a x, a y, bx, by, c x, c y;
/ / l i mi t sweep t o r ea sona bl e number s
i f ( Ma t h. a bs( a r c ) >360) {
a r c = 3 60;
}
/ / Fl a sh uses 8 segment s per c i r c l e, t o ma t c h t ha t , dr a w i n a ma xi mum
/ / of 45 degr ee segment s. Fi r st c a l c ul a t e how ma ny segment s a r e needed
/ / f or our a r c .
www.it-ebooks.info
Common Dégrafa concepts 1 4 9
segs = Ma t h. c ei l ( Ma t h. a bs( a r c ) / 45) ;
/ / Now c a l c ul a t e t he sweep of ea c h segment .
segAngl e = a r c / segs;
/ / The ma t h r equi r es r a di a ns r a t her t ha n degr ees. To c onver t f r om degr ees
/ / use t he f or mul a ( degr ees/ 180) *Ma t h. PI t o get r a di a ns.
t het a = - ( segAngl e/ 180) *Ma t h. PI ;
/ / c onver t a ngl e st a r t Angl e t o r a di a ns
a ngl e = - ( st a r t Angl e/ 180) *Ma t h. PI ;
/ / dr a w t he c ur ve i n segment s no l a r ger t ha n 45 degr ees,
i f ( segs>0) {
/ / dr a w a l i ne f r om t he c ent er t o t he st a r t of t he c ur ve
a x = x+Ma t h. c os( st a r t Angl e/ 180*Ma t h. PI ) *r a di us;
a y = y+Ma t h. si n( - st a r t Angl e/ 180*Ma t h. PI ) *yRa di us;
t hi s. l i neTo( a x, a y) ;
/ / Loop f or dr a wi ng c ur ve segment s
f or ( va r i = 0; i <segs; i ++) {
a ngl e += t het a ;
a ngl eMi d = a ngl e- ( t het a / 2) ;
bx = x+Ma t h. c os( a ngl e) *r a di us;
by = y+Ma t h. si n( a ngl e) *yRa di us;
c x = x+Ma t h. c os( a ngl eMi d) *( r a di us/ Ma t h. c os( t het a / 2) ) ;
c y = y+Ma t h. si n( a ngl eMi d) *( yRa di us/ Ma t h. c os( t het a / 2) ) ;
t hi s. c ur veTo( c x, c y, bx, by) ;
}
/ / c l ose t he wedge by dr a wi ng a l i ne t o t he c ent er
t hi s. l i neTo( x, y) ;
}
Adobe has rel eased the speci fi cati ons for its decl arati ve graphi cs library, cal l ed FXG. I t
appears that tire Degr afa team has col l aborated wi th tire Adobe team to create tiris
speci fi cati on, but tire FXG functi onal i ty is onl y a subset of what is avai l abl e f r om tire
Degr afa library. Thi s may be a l i brary to keep your eye on as it's bei ng devel oped.
Common Degraf a concept s
Befor e di vi ng i nto devel opi ng tire component, let's fami l i ari ze ourselves wi th some of
the terms and concepts that we'l l see as we wor k tirrough tiris exampl e.
• Surface—This is tire base component for everythi ng you'l l do i n Degr afa. Al l
odr er Degr afa components wi l l be composed witirin a Sur f a c e.
• GeometryGroup—After tire Sur f a c e, tiris is tire next l evel of composi ti on. The
Geomet r yGr oup tag allows you to gr oup Degr afa components to compose
an obj ect.
• Stroke—St r oke is tire obj ect that is used to defi ne tire l ook of an obj ect's outl i ne,
i n terms of col or, thickness, and style. Degr afa provi des di ffer ent St r oke obj ects
for your use dependi ng on tire style of stroke you want: Sol i dSt r oke, Li nea r -
Gr a di ent , and Ra di a l Gr a di ent .
• Fill—Fill refers to the appearance of tire bounded area of a graphi cal compo-
nent. Degr afa provi des tire fol l owi ng fills: Sol i dFi l l , Li nea r Gr a di ent , Ra di a l -
Gr a di ent , Bi t ma pFi l l , Bl endFi l l , and Compl exFi l l .
www.it-ebooks.info
150 CHAPTER 8 Charting with Dégrafa
• Shapes—Dégrafa supports drawing many di fferent shapes out of the box, such
as Ci r c l e, El l i pse, Regul a r Rec t a ngl e, RoundedRec t a ngl e, Pol ygon, and
more. For irregular shapes, Dégrafa also has an extensive library of auto shapes
and enables defi ni ng any shape you'd like by providing a Scalable Vector
Graphics (SVG) path.
• Repeaters—This gives you the ability to repeat a shape any number of times on
the surface.
Much like other Flex components, the Dégrafa components are considered either
container components, meani ng they will contain other Dégrafa components, or
graphical elements. Figure 8.1 shows the relationship of the common components.
Mor e than a single chapter woul d be needed to cover all the features that Dégrafa
offers, especially when it comes to skinning and the advanced CSS functions you can
accomplish with this powerful framework. We're only goi ng to scratch the surface; to
learn more about Dégrafa, you can start with the Foundation section of the documen-
tation at http:^www.degrafa.org/ samples/ foundation.html.
8.3 Creat i ng a pi e chart f or f un and prof i t
Now that we have some of the basic concepts, let's get on with the task of creating a
custom pie chart component. We were inspired by a bl og posting by Derrick Gri gg
titled appropriately enough Dégrafa Pie Chart, which can be found at http:/ / www.
dgri gg.com/ post.cfm/ 04/ 15/ 2008/ Degrafa-Pie-Chart. After we decomposed it and
removed some of the extra visual effects such as tweening and gradients, it barely
S u rfa ce
G e o m e tryG ro u p
S tro k e
Fill
C ircle
G e o m e tryG ro u p
Fi gure 8.1 Rel at i onshi p of Dégraf a component s
www.it-ebooks.info
Creating a pie chart for fun and profit 151
F le xB u g s Ap p lica tio n
KW.l! VkW | Sfliptl V«» |
La»I Units
Project t S
Pr-ajeet 2 5
Ccpv-K/ ' ¿009 Flex On Java
Fi gur e 8 .2 Mock -up of t he Graph Vi ew
resembl es what we started witir. Fi gure 8.2 shows a mock- up of the chart we'l l be devel -
opi ng i n this chapter.
Recal l i n chapter 2 you created a separate vi ew to contai n your data vi sual i zati on.
For this exampl e you'l l be devel opi ng onl y a si ngl e pi e chart component, but some of
the concepts illustrated her e coul d potenti al l y be appl i ed to creati ng any number of
charti ng components.
The component you'l l devel op is a combi nati on of a pi e chart and a data gri d,
whi ch wi l l serve the pur pose of a l egend for tire pi e chart. Wi thout this it may be
di ffi cul t for someone l ooki ng at tire chart to di ffer enti ate between data poi nts on
the graph. The pi e chart wi l l consist of tire pi e chart itself and anoti rer component
for each of the slices that make up tire chart. You'l l also devel op a si mpl e custom
I t emRender er for tire chart l egend to draw a si mpl e box i nsi de one of tire cells i n
the data gri d.
You'l l also be addi ng a l abel and a combo box to tire Gr a phVi ew to al l ow tire user to
change tire data tire chart shows. By changi ng tire val ue of the combo box tire user can
show how many issues there are by proj ect, type, status, or severity.
8.3.1 New custom event
We'r e goi ng to create a new custom event for our pi e chart. The reason we'r e creati ng
a new one rather than conti nui ng to use tire UI Event we created earl i er is that i f we
ever wanted to put mor e tiran one pi e chart component i nto our appl i cati on, we'd
need to be abl e to di sti ngui sh whi ch component fi r ed tire event.
www.it-ebooks.info
152 CHAPTER 8 Charting with Dégrafa
Li s t i n g 8 . 2 Pi e Ch a r t Ev e n t . a s
pa c ka ge or g. f oj . event {
i mpor t f l a sh. event s. Event ;
publ i c c l a ss Pi eCha r t Event ext ends Event {
publ i c st a t i c c onst D ATA_PROVI D ER_UPD ATED : St r i ng =
" da t a Pr ovi der Upda t ed" ;
publ i c va r da t a : *;
publ i c va r i d: *; <—© i d pr oper t y
publ i c f unc t i on Pi eCha r t Event ( t ype : St r i ng,
bubbl es : Bool ea n = t r ue,
c a nc el a bl e : Bool ea n = f a l se)
{
super ( t ype, bubbl es, c a nc el a bl e) ;
}
Thi s event di ffers f r om di e one created previ ousl y i n di e addi ti on of an i d O prop-
erty. Thi s is done so that di e presenter can deci de wheti i er or not it needs to react
to di e event. Wi ti i the new event created, you can move on to creati ng the compo-
nent itself.
8.3.2 PieChart component
First you'l l devel op di e vi ew tiiat contai ns the pi e chart and l egend. You'l l create these
vi ew components i n a new package, so create a fi l e named Pi eChar t. mxml i n di e or g.
f oj . c omponent s package of your proj ect. The fol l owi ng listing shows the first part of
the code for the Pi eCha r t view.
Li s t i n g 8 . 3 Pi e Ch a r t . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: degr a f a =" ht t p: / / www. degr a f a . c om/ 2007"
c r ea t i onCompl et e=" i ni t ( ) " >
<s: l a yout >
<s: Hor i zont a l La yout / >
</ s: l a yout >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t mx. c ol l ec t i ons. I Col l ec t i onVi ew;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . Pi eCha r t Event ;
i mpor t or g. f oj . pr esent er . Pi eCha r t Pr esent er ;
pr i va t e va r _pr esent er : Pi eCha r t Pr esent er ;
pr i va t e va r _da t a Pr ovi der : I Col l ec t i onVi ew;
Creat i onCompl et e
handl er
J
Hor i zont al Layout
J
Def ine pr esent er
f i el d
Def ine dat a
pr ovi der f i el d
www.it-ebooks.info
Creating a pie chart for fun and profit 153
pr i va t e f unc t i on i ni t ( ) : voi d
{
pr es ent er = new Pi eCha r t Pr esent er ( t hi s, i d) ; <- , p a s s c o m p o n e n t > s
© i d t o pr esent er
publ i c f unc t i on set da t a Pr ovi der ( da t a Pr ovi der : I Col l ec t i onVi ew) : voi d {<
va r r ef r eshEvent : Pi eCha r t Event =
new Pi eCha r t Event ( Pi eCha r t Event . D ATA_PROVI D ER_UPD ATED ) ;
r ef r eshEvent . i d = i d; Set pr oper t y f or
r ef r eshEvent . da t a = da t a Pr ovi der ; d a t a p r ovi d er ©
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( r ef r eshEvent ) ;
}
</ f x: Sc r i pt >
</ s: Gr oup>
The code is si mi l ar to what you devel oped i n chapter 3 when you created all the MVP
components. You set the c r ea t i onCompl et e event © to call the i ni t meti rod. Next
you set the l ayout of your component to use Hor i zont a l La yout ©. Then you decl are
a coupl e of pri vate member vari abl es for tire data pr ovi der and its presenter ©, ©.
I nsi de the i ni t meti r od you bootstrap your presenter ©. Last you create a set pr op-
erty © for the data pr ovi der wher e you create an event to noti fy tire presenter that tire
data pr ovi der was updated. Li sti ng 8.4 shows the rest of your pi e chart component.
Li s t i n g 8 . 4 Pi e Ch a r t . m x m l ( c o n t i n u e d )
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: degr a f a =" ht t p: / / www. degr a f a . c om/ 2007"
c r ea t i onCompl et e=" i ni t ( ) " >
</ f x : Sc r i pt >
<mx: Spa c er wi dt h=" 10" / >
<degr a f a : Sur f a c e i d=" pi eSur f a c e"
wi dt h=" 200" hei ght =" 200" >
<degr a f a : Geomet r yGr oup i d=" pi eGr oup" >
<degr a f a : f i l t er s>
<mx: D r opSha dowFi l t er c ol or =" 0x000000"
a l pha =" 0. 5" / >
</ degr a f a : f i l t er s>
</ degr a f a : Geomet r yGr oup>
</ degr a f a : Sur f a c e>
<mx: D a t a Gr i d i d=" l egendD a t a Gr i d" >
<mx: c ol umns>
J
Spacer t o hel p l ay out
t he component
1
< —© Degraf a surf ace
Geom et r y gr oup
© cont ai ni ng pi e char t
Dr op shadow
f or pie char t
Legend f or
pie char t
www.it-ebooks.info
154 CHAPTER 8 Charting with Dégrafa
J
Cust om
I t em Render er
<mx: D a t a Gr i dCol umn wi dt h=" 40"
sor t a bl e=" f a l se"
i t emRender er =" or g. f o j . c omponent s . Pi eLegendRender er " / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" l a bel "
hea der Text =" La bel " / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" uni t s"
hea der Text =" Uni t s" / >
</ mx: c ol umns>
</ mx: D a t a Gr i d>
</ s: Gr oup>
First you added a spacer Q to the component to put a bit of padding between your
pie chart and its surrounding components. Next you added a Degrafa Surface com-
ponent Q and a GeometryGroup © to hold die rest of die Degrafa components neces-
sary for the pie chart component. The GeometryGroup is die component to which
you'll add your pie chart slices when you create diem. You've also added a Drop-
ShadowFilter © to die GeometryGroup to add a bit of visual flair to die pie chart. Last
you defined the DataGrid component © for your chart legend, witii a custom I tem-
Renderer © to display the color tiiat corresponds to the data in die chart, which
you'll create in a bit.
8.3.3 PieChartSlice
Now that we've defined the pie chart component, let's move on to defining die slices
diat will make up die pie chart. The pie chart slice is a ratiier simple component. We
probably could have created die pie chart slice programmatically in ActionScript,
however tiiis approach allows us to define sensible defaults declaratively in MXML,
adding behavior as well.
Li st i ng 8 .5 Pi eChar t Sl i ce.m xm l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<degr a f a : Geomet r yGr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: degr a f a =" ht t p: / / www. degr a f a . c om/ 2007"
hei ght =" 400"
wi dt h=" 400" >
<f x: Sc r i pt >
<! [ CD ATA[
publ i c f unc t i on r ef r esh( ) : voi d
{
t hi s. gr a phi c s. c l ea r ( ) ;
t hi s. a r c . pr eD r a w( ) ;
t hi s. a r c . dr a w( gr a phi c s, nul l ) ;
}
] ]>
</ f x: Sc r i pt >
<degr a f a : El l i pt i c a l Ar c
i d=" a r c "
wi dt h=" 200"
1>
Ext ends
Geom et r yGr oup

Your pi e char t sl i ce
J
Adds El l i pt i cal Ar c
www.it-ebooks.info
Creating a pie chart for fun and profit 155
hei ght =" 200"
c l osur eType=" pi e" / >
</ degr a f a : Geomet r yGr oup>
The pi e chart slice wi l l extend f r om Geomet r yGr oup O i nstead of tire standard Fl ex
Gr oup component drat you extended i n chapter 2. Next you defi ne a r ef r esh meti r od
Q to abstract behavi or away f r om your presenter. Last you add an El l i pt i c a l Ar c
component to tire component Q and set defaul t values such as its wi dt h, hei ght , and
most i mportantl y c l osur eType property, whi ch you set to pie.
8.3.4 Custom ItemRenderer
The next component you'r e goi ng to create is tire custom I t emRender er for tire pi e
chart l egend. Thi s si mpl e component wi l l draw a col or ed box i n tire data gr i d cel l to
cor r espond witir tire col ors of tire pi e chart.
Li s t i n g 8 . 6 Pi e Le g e n d Re n d e r e r . m xm l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: HBox xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: degr a f a =" ht t p: / / www. degr a f a . c om/ 2007" >
<mx: Spa c er wi dt h=" 2" / >
<degr a f a : Sur f a c e>
<degr a f a : Geomet r yGr oup>
<degr a f a : f i l l >
<degr a f a : Sol i dFi l l i d=" f i l l " >
<degr a f a : c ol or >{da t a . l egend}" </ degr a f a : c ol or >
</ degr a f a : Sol i dFi l l >
</ degr a f a : f i l l >
<degr a f a : Regul a r Rec t a ngl e
J
1
Ext ends HBox
Spacer t o
hel p al i gn box
Sol i dFi l l f or
rect angl e
Col or of
l egend i t em
Rect angl e
wi dt h=" 20"
hei ght =" 20"
f i l l =" {f i l l }" / >
</ degr a f a : Geomet r yGr oup>
</ degr a f a : Sur f a c e>
</ mx: HBox>
The I t emRender er is extendi ng HBox O because all I t emRender er obj ects for the
D a t a Gr i d component must be hal o components. Add a Spa c er component Q to
hel p al i gn tire rectangl e tire way you want it. The Sol i dFi l l component Q defi nes
the fi l l col or for tire Regul a r Rec t a ngl e Now that you've fi ni shed creati ng all tire
visual components for tire pi e chart, l et's move on to creati ng the Presenter. An
i mpl i ci tl y defi ned vari abl e is available to tire I t emRender er named da t a , whi ch cor-
responds to tire i tem i n tire da t a Pr ovi der that you'r e r ender i ng. LTse tiris i mpl i ci t
vari abl e to set tire col or of tire Fi l l obj ect Q , whi ch is contai ned i n the l egend
pr oper ty of tire obj ect.
www.it-ebooks.info
156 CHAPTER 8 Charting with Dégrafa
8.3.5 Presenter for the PieChart
Now that all the visual components are created for di e pi e chart, l et's create di e Pre-
senter. The Presenter for the pi e chart becomes mor e i nvol ved tiian any of your previ -
ous ones, but it shoul dn't be hard to fol l ow.
Li st i ng 8 .7 Pi eChar t Pr esent er .as
pa c ka ge or g. f oj . pr esent er {
i mpor t c om. degr a f a . pa i nt . Sol i dFi l l ;
i mpor t or g. f oj . c omponent s. Pi eCha r t ;
i mpor t mx. c ol l ec t i ons. Ar r a yCol l ec t i on;
i mpor t or g. f oj . c omponent s. Pi eCha r t Sl i c e;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . Pi eCha r t Event ;
i mpor t or g. f oj . model . Pi eCha r t Model ;
publ i c c l a ss Pi eCha r t Pr esent er { _ _ . . .
A Pri vat e member
J pr i va t e va r _vi ew: Pi eCha r t ; <1—
1
vari abl es
pr i va t e va r _model : Pi eCha r t Model ;
pr i va t e va r _i d: St r i ng;
pr i va t e va r _da t a Pr ovi der : Ar r a yCol l ec t i on;
publ i c f unc t i on Pi eCha r t Pr esent er ( vi ew: Pi eCha r t , i d: St r i ng)
t hi s. _vi ew = vi ew;
t hi s. _model = new Pi eCha r t Model ! ) ;
t hi s. _i d = i d; Const r uct or
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( Pi eCha r t Event . D ATA_PROVI D ER_UPD ATED ,
r ef r eshD a t a ) ;
1
©
publ i c f unc t i on set da t a Pr ovi der ( da t a : Ar r a yCol l ec t i on) : voi d {
_vi ew. l egendD a t a Gr i d. da t a Pr ovi der = da t a ;
t hi s . _da t a Pr ovi der = da t a ; Set pr oper t y
i dat aPr ovi der
publ i c f unc t i on get da t a Pr ovi der ( ) : Ar r a yCol l ec t i on {
r et ur n t hi s. _da t a Pr ovi der ;
}
f f or I
i der G
pr i va t e f unc t i on r ef r eshD a t a ( event : Pi eCha r t Event = nul l ) : voi d {
i f ( event . i d == _i d) {
c ha ngeD a t a ( event . da t a ) ;
, Event handl er
1
o
}
pr i va t e f unc t i on c ha ngeD a t a ( da t a : Ar r a yCol l ec t i on) : voi d {
da t a Pr ovi der = da t a ;
c r ea t eSl i c es( ) ;
}
Creat e slices
« T
whi l e ( da t a Pr ovi der . l engt h > _vi ew. pi eGr oup. numChi l dr en) {
pr i va t e f unc t i on c r ea t eSl i c es ( ) : voi d { —
1
met hod
J
www.it-ebooks.info
Creating a pie chart for fun and profit 157
_vi ew. pi eGr oup. a ddc hi l d( new Pi eCha r t Sl i c e( ) ) ;
}
set LegendCol or s( ) ;
r edr a wSl i c es( ) ;
}
S
Set l egend
col or s on dat a
pr i va t e f unc t i on set LegendCol or s( ) : voi d {
f or ( va r i : i nt =0; i < da t a Pr ovi der . l engt h; i ++)
{
da t a Pr ovi der . get l t emAt ( i ) . l egend = _model . get LegendCol or For l ndex( i ) ;
}
A Redraw sl i ces
pr i va t e f unc t i on r edr a wSl i c es ( ) : voi d { <1—I af t er updat e
va r c ur r ent Angl e: Number = 0;
va r t ot a l Uni t s: Number = _model . get Tot a l Uni t s( _da t a Pr ovi der ) ;
f or ( va r i : i nt =0; i < _vi ew. pi eGr oup. numChi l dr en; i ++) {
va r sl i c e: Pi eCha r t Sl i c e = _vi ew. pi eGr oup. get Chi l dAt ( i )
a s Pi eCha r t Sl i c e;
va r l egendCol or : Number = _model . get LegendCol or For l ndex( i ) ;
va r a r c : Number = i < da t a Pr ovi der . l engt h ?
_model . get Angl eFor l t em(
da t a Pr ovi der [ i ] . uni t s, t ot a l Uni t s) : 0;
/ / wor ka r ound f or wei r d di spl a y i f onl y one a r c a nd i t ' s 360 degr ees
a r c = a r c < 360 ? a r c : 359. 99;
1
Wor k ar ound
r edr a wSl i c e( sl i c e, c ur r ent Angl e, a r c , l egendCol or ) ;
c ur r ent Angl e += a r c ;
}
_vi ew. pi eGr oup. dr a w( nul l , nul l ) ;
}
pr i va t e f unc t i on r edr a wSl i c e ( sl i c e: Pi eCha r t Sl i c e, <a —,
st a r t Angl e: Number , A Redraw sl i ce
a r c : Number ,
c ol or : Number ) : voi d {
sl i c e. a r c . f i l l = new Sol i dFi l l ( c ol or , 1) ;
sl i c e. a r c . st a r t Angl e = st a r t Angl e;
sl i c e. a r c . a r c = a r c ;
sl i c e. r ef r esh( ) ;
}
You first defi ne pri vate member vari abl es to hol d onto r efer ences to tire vi ew and tire
model , the i d of tire component this Presenter bel ongs to, and tire da t a Pr ovi der for
your pi e chart Q . The constructor Q for this Presenter not onl y takes i n a r efer ence
to the vi ew, but also is used to bootstrap tire i d for the vi ew component because
there may be mul ti pl e pi e charts contai ned i n tire appl i cati on. You also defi ne an
event l i stener for tire da t a Pr ovi der bei ng updated i n the vi ew component. Next you
defi ne a pai r of get and set pr oper ti es Q for the da t a Pr ovi der you l everage to
update tire da t a Pr ovi der pr oper ty of tire l egend data gr i d whenever the da t a -
Pr ovi der for tire pi e chart is updated.
www.it-ebooks.info
158 CHAPTER 8 Charting with Dégrafa
You then defi ne di e event handl er meti i od for the event tiiat is fi r ed whenever di e
dat aPr ovi der for the vi ew is updated Q . I nsi de this meti i od you check to see i f the i d
of the component fi r i ng the event is di e same as di e i d tiiat created tiiis Presenter.
That way i f there are mul ti pl e pi e chart components, this method can deter mi ne
whether or not it needs to react.
The cr eat eS l i ces © meti i od checks to see i f the data pr ovi der has mor e ele-
ments contai ned i n it tiian there are pi e chart slices i n your pi e chart. I f there are
mor e el ements i n the data provi der, it wi l l create mor e pi e chart slices. I n di e s et -
LegendCol or s Q meti i od you i terate thr ough the i tems i n the dat aPr ovi der and set
di e l egend pr oper ty of di e i tem to the cor r espondi ng col or, whi ch you'l l get f r om the
pi e chart model class.
After all of tiiat, refresh your pi e chart wi th a call to the r edr aws 1 i ces Q method.
Thi s wi l l i terate over the pi e chart slices and update di e data values, such as di e start
angl e of di e slice and its arc. You i terate over the pi e chart slices i nstead of di e data
pr ovi der because tiiere may be mor e slices than i tems i n the dat aPr ovi der , and this
wi l l draw the extra slices wi ti i an arc of 0. Ther e is also a little wor kar ound © for when
tiiere is onl y a si ngl e slice and its arc is 360, whi ch sets its arc to 359.99 so tiiat it woul d
draw correcti y. After all of the data for the slice is updated, it is passed i nto di e
r edr awSl i ce Q meti i od to tel l the slice to redraw itself.
8.3.6 Model for the PieChart
Now you onl y have one pi ece of di e MVP tri ad to compl ete for your pi e chart. Even
though the pi e chart doesn't need to call out to any r emote services, you've still refac-
tor ed a coupl e of meti i ods that coul d be consi der ed business l ogi c rati i er than presen-
tati on l ogi c and have no need to mai ntai n any ki nd of state. The fol l owi ng listing
shows the code for di e pi e chart model .
Li s t i n g 8 . 8 Pi e Ch a r t M o d e l . a s
pa c ka ge or g. f oj . model {
i mpor t mx. c ol l ec t i ons. I Col l ec t i onVi ew;
publ i c c l a ss Pi eCha r t Model {
pr i va t e va r c ol or s: Ar r a y = [
0x468966,
0xFFB03B,
0xFFF0A5,
0x999574,
0x007D 9F,
0x8E2800,
0x8E28F4,
0x0528F4,
0XF42105,
0x0CF405
] ;
Ar r ay of col ors
O f or l egend
www.it-ebooks.info
Adding your pie chart to the application 159
publ i c f unc t i on get LegendCol or For l ndex( i ndex: Number ) : Number {
r et ur n c ol or s[ i ndex] ;
r
Conveni ence met hod I
f or get t i ng col or ©
publ i c f unc t i on get Angl eFor l t em( uni t s: Number ,
t ot a l Uni t s: Number ) : Number {
r et ur n ( ( ( ( uni t s / t ot a l Uni t s) * 100) * 360) / 100) ;
Cal cul at e angl e
© f or i t em
publ i c f unc t i on get Tot a l Uni t s( da t a Pr ovi der : I Col l ec t i onVi ew) : Number {
va r t ot a l : Number = 0;
f or ea c h( va r i t em: Obj ec t i n da t a Pr ovi der ) {
t ot a l += i t em. uni t s;
Cal cul at e t ot al number
of i t ems f or pi e char t
r et ur n t ot a l ;
An array of 10 di ffer ent hex values © corresponds to tire col ors you want the pi e chart
to use for its data poi nts. Thi s number coul d easily be i ncreased shoul d tire need arise
for mor e data poi nts i n your graphs; for tiris exampl e this number shoul d suffi ce.
Next you defi ne a conveni ence method © for getti ng the col or val ue for a speci fi c
i ndex. The meti r od get Angl eFor l t em© takes care of tire cal cul ati on for deter mi ni ng
the size of tire angl e for an i tem based on tire total number of i tems contai ned wi thi n
the pi e chart and tire number of i tems passed in. The last meti r od you defi ne © i n
your model iterates thr ough tire data set passed i n and returns back tire total number
of i tems for the pi e chart.
8.4 Addi ng your pi e chart t o t he appl i cat i on
That takes care of all of the pi eces you need for tire pi e chart component. Next you'r e
goi ng to need to make changes to tire Gr a phVi ew components i n or der to support it.
For tire exampl e you'l l add onl y a si ngl e i nstance of this pi e chart drat you'l l be abl e to
change the data it's vi sual i zi ng wi th a combo box. You coul d j ust as easily display each
of drese visualizations for tire data separately. We chose tiris appr oach because it's an
easy way to illustrate tire event handl i ng wor ki ng for tire pi e chart components
because tire data wi l l be updated for the chart each time you sel ect a di ffer ent report-
i ng poi nt f r om tire combo box.
8.4.1 Updating the GraphView
To add tire pi e chart to tire appl i cati on, you'l l fi rst update the Gr a phVi ew. I n chapter 2
you created the Gr a phVi ewwi th si mpl e pl acehol der text; now is tire time to i mpl ement
this view. The fol l owi ng listing shows tire updated Gr a phVi ew component after you
made tire changes to add tire pi e chart.
www.it-ebooks.info
1 6 0 CHAPTER 8 Charting with Dégrafa
Li st i ng 8 .9 Gr aphVi ew.m xm l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Pa nel t i t l e=" Gr a ph Vi ew"
xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: c omponent s=" or g. f oj . c omponent s. *"
wi dt h=" 100%"
hei ght =" 100%"
c r ea t i onCompl et e=" i ni t ( ) " >
<f x: Sc r i pt >
<! [ CD ATA[
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
i mpor t or g. f oj . pr esent er . Gr a phPr esent er ;
pr i va t e va r _pr esent er : Gr a phPr esent er ;
pr i va t e f unc t i on i ni t ( ) : voi d {
_pr esent er = new Gr a phPr esent er ( t hi s) ;
r ef r eshD a t a ( ) ;
}
Com ponent s
namespace decl ar at i on
S
Boot st r ap
pr esent er
pr i va t e f unc t i on r ef r eshD a t a ( ) : voi d {
va r r ef r eshEvent : UI Event = new UI Event ( UI Event . REFRESH_GRAPHS) ;
r ef r eshEvent . da t a = gr oupByComboBox. va l ue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) .
di spa t c hEvent ( r ef r eshEvent ) ;
Ref resh but t on
event handl er
}
J
Gr ou p by com bo
box event handl er
pr i va t e f unc t i on c ha ngeGr oupBy( event : Event ) : voi d {
va r c ha ngeEvent : UI Event = new UI Event ( UI Event . REFRESH_GRAPHS) ;
c ha ngeEvent . da t a = gr oupByComboBox. va l ue;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) . di spa t c hEvent ( c ha ngeEvent ) ;
}
</ f x: Sc r i pt >
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<mx: HBox>
<mx: Text t ext =" I ssues By: " f ont Wei ght =" bol d" f ont Si ze=" 16" / >
<mx: ComboBox i d=" gr oupByComboBox" c ha nge=" c ha ngeGr oupBy( event ) " / >
</ mx: HBox>
Gr ou p by
com bo box
J
«c omponent s: Pi eCha r t i d=" i ssuesPi eCha r t " / >
<mx: Spa c er hei ght =" 100%" / >
<mx: Cont r ol Ba r >
<mx: But t on i d=" r ef r eshBut t on"
l a bel =" Ref r esh D a t a "
c l i c k=" r ef r eshD a t a ( ) " / >
</ mx: Cont r ol Ba r >
Pie char t

Ref resh but t on
</ s: Pa nel >
www.it-ebooks.info
Adding your pie chart to the application 1 6 1
By now this shoul d be al most second nature. You start by decl ari ng tire namespace for
your pi e chart components Q , and bootstrap tire presenter i n tire i n i t method
Next defi ne a coupl e of event handl er methods for use when tire refresh button is
cl i cked Q and when the group by combo box is updated Q . Add an HBox to contai n a
l abel component as wel l as the ComboBox © to switch data fi el d by whi ch tire data is
gr ouped i n your pi e chart ©. Last, add a button Q to tri gger a refresh on tire data
bei ng di spl ayed i n tire pi e chart.
8.4.2 Creating a Presenter for the GraphView
After you've updated tire vi ew component for the GraphView, you need to create tire
Presenter to support it.
Li s t i n g 8 . 1 0 Gr a p h Pr e s e n t e r . a s
pa c ka ge or g. f oj . pr esent er {
i mpor t mx. c ol l ec t i ons. Ar r a yCol l ec t i on;
i mpor t mx. c ont r ol s. Al er t ;
i mpor t mx. ma na ger s. Cur sor Ma na ger ;
i mpor t mx. r pc . Async Responder ;
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . event s. Fa ul t Event ;
i mpor t mx. r pc . event s. Resul t Event ;
i mpor t or g. f oj . dt o. I ssue;
i mpor t or g. f oj . event . Event D i spa t c her Fa c t or y;
i mpor t or g. f oj . event . UI Event ;
i mpor t or g. f oj . model . I ssueModel ;
i mpor t or g. f oj . model . Gr a phModel ;
i mpor t or g. f oj . vi ew. Gr a phVi ew;
publ i c c l a ss Gr a phPr esent er {
pr i va t e va r _vi ew: Gr a phVi ew;
pr i va t e va r _i ssueModel : I ssueModel ;
pr i va t e va r _model : Gr a phModel ;
pr i va t e va r _gr oupByVa l ues: Ar r a yCol l ec t i on =
new mx. c ol l ec t i ons. Ar r a yCol l ec t i on( [
J
Ar r ayCol l ect i on f or
gr oup by combo box
{ l a bel
{ l a bel
{ l a bel
{ l a bel
" Pr oj ec t " , da t a : "pr oj ec t " },
" St a t us" , da t a : "st a t us" },
"Type", da t a : "t ype" },
" Sever i t y" , da t a : " sever i t y" }
] ) ;
publ i c f unc t i on Gr a phPr esent er ( vi ew: Gr a phVi ew)
t hi s. _vi ew = vi ew;
t hi s. _i ssueModel = new I ssueModel ( ) ;
t hi s. _model = new Gr a phModel ( ) ;
Event D i spa t c her Fa c t or y. get Event D i spa t c her ( )
. a ddEvent Li st ener ( UI Event . REFRESH_GRAPHS,
J
Const r uct or
Event Li st ener f or
ref resh but t on and
combo box event s
r ef r eshGr a phs) ;
_vi ew. gr oupByComboBox. da t a Pr ovi der = _gr oupByVa l ues;
Set dat aPr ovi der f or .
gr oup by combo box ©
www.it-ebooks.info
162 CHAPTER 8 Charting with Dégrafa
pr i va t e f unc t i on r ef r eshGr a phs( event : UI Event = nul l ) : voi d { <—
Cur sor Ma na ger . set BusyCur sor ( ) ;
_i ssueModel . get l ssues( new Async Responder ( get l ssuesResul t ,
ha ndl eEr r or ) ) ; g
Event
I handl er f or
© ref resh event
pr i va t e f unc t i on get l ssuesResul t ( event : Resul t Event ,
t oken: Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
va r i ssues : Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on( ) ;
Event handl er
f or r esul t f r om
i ssue model O
f or ea c h( va r i t em: Obj ec t i n event . r esul t ) {
va r i ssue: I ssue = new I ssue( i t em) ;
i ssues. a ddl t em( i ssue) ;
vi ew. i ssuesPi eCha r t . da t a Pr ovi der =
_model . gr oupCol l ec t i onBy( i ssues,
_vi ew. gr oupByComboBox. sel ec t edl t em. da t a ) ;
pr i va t e f unc t i on ha ndl eEr r or ( event : Fa ul t Event , J
Event handl er
f or er r or s
t oken : Async Token = nul l ) : voi d {
Cur sor Ma na ger . r emoveBusyCur sor ( ) ;
Al er t . show( event . messa ge. t oSt r i ng( ) ) ;
}
You start by defi ni ng an Ar r a yCol l ec t i on of i tems for di e combo box ©. Thi s is an
exampl e of di e power of a dynami c l anguage such as Acti onScri pt. Those fami l i ar wi ti i
J avaScri pt may r ecogni ze this as J SON notati on. Acti onScr i pt allows you to create
obj ects l i ke this wi ti i out any type of Cl a ss decl arati on, whi ch is great for these one off
throwaway obj ects.
Next you defi ne di e constructor ©, whi ch takes as an ar gument the vi ew com-
ponent that bel ongs to this Presenter. I nsi de tiiis constructor you instantiate an
issue model whi ch you use to retri eve di e issues f r om the server side, as wel l as
an i nstance of the Gr a phModel tiiat you'l l create i n a moment. You then add an
event l i stener for di e REFRESH_ GRAPHS event © and map it to your handl er. The
last tiling your constructor wi l l do is set di e da t a Pr ovi der pr oper ty of di e gr oup-
ByComboBox © so tiiat it has the appr opr i ate display values and data values to func-
tion correctl y.
NOTE The two pr oper ti es you defi ne for di e obj ects bei ng passed to your
combo box have special meani ng to tiiis component. The l a bel pr oper ty is
what wi l l be di spl ayed to di e user i n the combo box. The second property,
da t a , wi l l be r etur ned when usi ng di e va l ue pr oper ty for di e combo box,
whi ch is similar to how HTML dr op- down boxes work.
You next defi ne an event handl er for when di e REFRESH_ GRAPHS event is tr i gger ed
©. I nsi de tiiis handl er you make a call to di e issue model to fetch di e list of issues i n
www.it-ebooks.info
Adding your pie chart to the application 1 6 3
the system. I n the result event handl er for tiris call Q you make a call to tire gr aph
model to aggr egate tire data and set tire pi e chart's da t a Pr ovi der pr oper ty to tire
resul t f r om this call. Last you defi ne a gener i c er r or handl er as you have i n tire other
Presenters Q .
8.4.3 Creating the graph model
Now tire onl y thi ng l eft to do is i mpl ement your Gr a phModel . Thi s model wi l l contai n
onl y one meti r od drat is used to aggr egate and for mat the list of issues retri eved f r om
the issue model i nto a for mat drat your pi e chart can understand.
Li s t i n g 8 . 1 1 Gr a p h M o d e l
pa c ka ge or g. f oj . model {
i mpor t mx. c ol l ec t i ons. Ar r a yCol l ec t i on;
publ i c c l a ss Gr a phModel {
publ i c f unc t i on Gr a phModel ( )
}
{
Ar r ay t o hol d
i nt ermedi at e gr oupi ngs
publ i c f unc t i on gr oupCol l ec t i onBy( a l l l ssues: Ar r a yCol l ec t i on,
f i el d: St r i ng) : Ar r a yCol l ec t i on {
va r gr oup: Ar r a y = new Ar r a y( ) ;
f or ea c h( va r i ssue: Obj ec t i n a l l l ssues) {
i f ( gr oup[ i ssue[ f i el d] ] == nul l ) {
gr oup[ i ssue[ f i el d] ] = 1;
} el se {
gr oup[ i ssue[ f i el d] ] ++;
}
}
It erat e over
i t ems and creat e
associ at i ve ar r ay
va r r esul t : Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on( ) ;
f or ( va r key: St r i ng i n gr oup) {
r esul t . a ddl t em( {l a bel : key, uni t s: gr oup[ key] }) ;
}
r et ur n r esul t ;
J
Ar r ayCol l ect i on
f or resul t s
It erat e over
i nt ermedi at e resul t s
and bui l d real resul t s
The i mpl ementati on for this meti r od is fai rl y simplistic. First you create an array ©
that wi l l be used to hel p gr oup and count tire i tems passed i n by tire pr oper ty name i n
the fi el d vari abl e. Next you i terate over tire col l ecti on of issues ©. I f the array does
not contai n an entry al ready wi th the fi el d name, add it and set its val ue to 1. Other-
wise i ncr ement tire val ue for that fi el d name. Now create an Ar r a yCol l ec t i on that
wi l l contai n tire real results that you need to return f r om this meti r od I terate over
the i nter medi ate results Q creati ng a dynami c obj ect contai ni ng the two properti es
that your pi e chart needs to pr oper l y display the data: l a bel and uni t s. Last you
return tire result Ar r a yCol l ec t i on.
www.it-ebooks.info
1 6 4 CHAPTER 8 Charting with Dégrafa
NOTE Concerni ng dynamically addi ng properties, recall that in your Pi e-
Cha r t Pr esent er you are setting a property called l egend on di e results fr om
this functi on call although you never defi ne di e objects bei ng returned as hav-
i ng a l egend property. This is anoti i er exampl e of how powerful, and some-
times dangerous, a dynamic language such as Acti onScri pt can be. Because
you never defi ned a property named l egend, ActionScript interpreted tiiis to
mean add a property to tiiis obj ect named l egend, which it did, and happily
continued on its merry way. I f you fat fi ngered that property name somewhere
else in your code it woul d make for a difficult bug to track down.
Wi th all of di e components i mpl emented, build and depl oy the RIA modul e to the local
repository by issuing an mvn i nst a l l command on the command line witiiin tiiis mod-
ule's root folder. Then change directories to di e web module and run di e command mvn
j et t y: r un- wa r to start up di e J etty container so you can see your hard work in action.
Keep in mi nd tiiat you may want to add the - D ma ven. t est . ski p=t r ue opti on to
that command so Maven won't blow away any issues that you had entered into di e
database. After J etty starts up, if you don't have any issues created in the application,
add a few, tiien click the Graph Vi ew button in the upper-right corner and you should
see something similar to fi gure 8.3.
«HO Flex Bugs Q
Hex !«ot
F l e x B u g s A p p li c a t i o n F l e x B u g s A p p li c a t i o n
| Details ' vfcw | GtipitVfew |
Qrapti Vtew
By: ¡I HWi - l
LatMl Unira

Prated 1
FtexBLgs
5
2
| RUHh DH1B" 1
Capyrtotu : ÎX-i Fta* Or. Java
Tr)ftif»mfig tot» fromlocjlhwt. .
Figure 8.3 The finished GraphView
www.it-ebooks.info
Beyond the example 165
Next change the sel ected val ue i n di e combo box at di e top of di e page and watch
your gr aph and l egend update to display tire data gr ouped by a di ffer ent data poi nt. I f
you cl i ck back to tire D et a i l sVi ewand add or r emove issues you can come back to tiris
vi ew and click the Refr esh Data button at tire bottom of the screen and it shoul d
update your pi e chart wi th tire new data f r om the database.
Beyond t he exampl e
When it comes down to it, tirere isn't much that you coul dn't visualize usi ng Degr afa
and some i ngenui ty and i magi nati on. Ther e are great exampl es of ways to visualize your
data at the Degr afa site at http:/ / www.degrafa.org/ sampl es/ data- vi sual i zati on.html —
everythi ng f r om bar charts, to gauges, fi nanci al data, Gantt charts, even combi ni ng
vi sual i zati on wi th maps. Ther e was even a r ecent presentati on at 360| Flex I ndy (http:/ /
www.fl exj unk.eom/ 2009/ 05/ 30/ devel opi ng- a- smi th- chart- usi ng- axi i s- and- degrafa/ )
on creati ng a Smitir Chart usi ng a data vi sual i zati on fr amewor k cal l ed Axi i s whi ch is
bui l t on Degr afa. Fi gure 8.4 shows mor e exampl es of data vi sual i zati on components
created wi th Degr afa.
The Degr afa possibilities are endless; i n fact someone has even created a Growl l i ke
component for use i n Fl ex appl i cati ons (http:/ / l ukesh.wordpress.com/ 2009/ 04/ 04/
rawr- fl exgrowl - component- avai l abl e/ ). Fi gure 8.5 shows an exampl e of tiris component.
Figure 8.4 More examples of visualization components created with Degrafa
www.it-ebooks.info
166 CHAPTER 8 Charting with Dégrafa
Title
Grovwl Title
D escription
This isa test of the growl notification system.
Acton Button Label
Click Me...
C olor (H EX)
O xO O CCEE
N otification (O bject)
This can be anything.
[ Growl 2 (Colored Everything) •
Growl I
G ro w l T i tle
Figure 8.5 A Growl like component for Flex
You can do amazi ng tilings wi th Degrafa, whether ski nni ng your appl i cati on and com-
ponent to l ook l i ke an i Phone appl i cati on, or creati ng a ri ch user exper i ence such as
Autodesk's Pr oj ect Dr agonfl y shown i n fi gur e 8.6.
Autodesk Project Dragonfly
DESIGNER
Electronics
Flooring
Furniture
Figure 8.6 Autodesk's Project Dragonfly interactive home design software
www.it-ebooks.info
Summary 1 6 7
The Autodesk example, which can be found at http:/ / www.homestyler.com/ , is one of
our favorite examples of what is possible with using the Degrafa library. I n the Proj ect
Dragonfl y app, you can do anything fr om defi ni ng your floor plan to movi ng furni-
ture, doors, countertops, and otiier features interactively in eitiier a 2D top-down view
or a full 3D view that can be zoomed and rotated. This is a great exampl e of an immer-
sive rich internet experi ence; the kind of functionality you would never expect to be
available fr om a web application. You're limited only by your imagination.
Summary
I n this chapter we've i ntroduced di e Degrafa framework and created a custom pi e
chart component. We've also i ntroduced creating a custom I t emRender er for dis-
playing sometiiing other than simple text inside of a D a t a Gr i d cell. And if tiiat
weren't enough we also demonstrated some of di e dynamic features of di e Action-
Script language by creating ad hoc objects on the fly and addi ng properties to those
objects at runtime.
We've also built this component in such a way that you could now easily refactor it
into a separate reusable library. I t woul dn't take much effort to extract the compo-
nents you created in tiiis chapter into its own modul e and add di em as a dependency
to any project.
www.it-ebooks.info
Desktop 2.0 wit^L
Thi s chapt er covers
• C re a t i n g a c o m m o n S W C l i b ra ry
• M a k i n g a n A I R v e rs i o n o f a F le x a p p l i c a t i o n
• C re a t i n g a k e y f o r s i g n i n g t h e a p p l i c a t i o n
• P a c k a g i n g t h e a p p l i c a t i o n f o r d i s t ri b u t i o n
• D i s t ri b u t i n g t h e A I R a p p l i c a t i o n v i a t h e w e b
Al though your Flex application is rich and engaging, some power users will want
a version tiiat tiiey can downl oad and install locally as a desktop application.
Adobe AI R allows you to easily accomplish this otiierwise daunting task. RIAs blur
the line between traditional web applications and desktop client applications,
especially when you can convert the Flex application to a desktop application
runni ng in the Adobe AI R runtime by changing only a couple of lines of code.
Yes, you heard tiiat ri ght—onl y a coupl e of lines. What other framework allows
you to reuse tiiis much of the client code, goi ng fr om a purely web-based experi-
ence to a desktop application?
You do want to be able to use di e Flex version of your application, so you're
goi ng to refactor all the code tiiat will be common between the Flex application
and di e AI R application that you're goi ng to build into a separate Shockwave
1 6 8
www.it-ebooks.info
Creating a common library 1 6 9
Component (SWC) proj ect. Then you can decl are a dependency on diis SWC l i brary
i n both di e AI R pr oj ect and the Fl ex proj ect.
After you have the common l i brary pr oj ect created, create a new Maven pr oj ect for
your AI R appl i cati on, whi ch wi l l i n turn create an SWF file di at you'l l use to package
and depl oy your AI R appl i cati on. Then you'l l have to create one mor e pr oj ect di at wi l l
contai n all of the resources necessary to package your AI R appl i cati on, such as the cer-
tificate for si gni ng di e appl i cati on and any assets that the appl i cati on wi l l need, such
as the i cons di e OS wi l l use to display the appl i cati on.
Last, we'l l l ook at what it takes to di stri bute the appl i cati on via a web page and how
to l et users update di e versi on of thei r appl i cati on qui ckl y and painlessly. Let's get on
wi th the show.
Creat i ng a common l i brary
Because the onl y part of your appl i cati on that wi l l di ffer between the Fl ex versi on and
di e AI R versi on wi l l be di e mai n MXML file, you can r efactor all the common classes out
i nto a separate library. That way you can avoi d dupl i cati ng classes across di e two proj ects.
You'r e also goi ng to extract di e mai n contents of the ol d Mai n. mxml i nto a vi ew
component so that di e new Mai n. mxml contai ns onl y this new vi ew component. Thi s
wi l l al l ow you to change the appl i cati on structure and content i n a si ngl e pl ace and
enabl e you to bui l d both di e Fl ex versi on of the appl i cati on and the AI R versi on witii-
out havi ng to change ei ti i er of the Mai n. mxml files i n the appl i cati ons. Fi gure 9.1
y
#
Fx
F le x
Ap p li ca ti o n
V
Q
A d o b e A I R
Ap p li ca ti o n
Figure 9.1 High-level view of desired architecture
www.it-ebooks.info
1 7 0 CHAPTER 9 Desktop 2.0 with AIR
shows at a hi gh l evel how the Fl ex appl i cati on and AI R appl i cati on rel ate to the vi ew
component you'r e goi ng to extract. You fi rst need to create a new pr oj ect to contai n
di e common el ements of di e appl i cati on.
9.1.1 Creat i ng an SWC proj ect
To create your SWC proj ect, you'l l use the same archetype that you used to create your
Fl ex appl i cati on i n chapter 2. Open a command l i ne and change the current di rec-
tory to di e r oot of di e Fl exBugs pr oj ect hi erarchy, and type the fol l owi ng command.
mvn a r c het ype: c r ea t e - D a r c het ypeGr oupI d=or g. f oj \
- D a r c het ypeAr t i f a c t l d=f l ex- moj os- a r c het ype \
- D a r c het ypeVer si on=l . O- SNAPSHOT \
- D gr oupI d=or g. f oj \
- D a r t i f a c t l d=f l ex- bugs- l i b \
- D ver si on=l . O- SNAPSHOT \
- D r emot eReposi t or i es=
ht t p: / / f l exonj a va . googl ec ode. c om/ svn/ f l ex- bugs/ r eposi t or y
Thi s wi l l create a new fol der i n the Fl exBugs di rectory named flex-bugs-lib, whi ch con-
tains di e new proj ect.
Listing 9.1 f l ex - bug- l i b pom.xml
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<pr oj ec t xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ xsd/ ma ven- 4. 0. 0. xsd" xml ns=
" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e" >
<model Ver si on>4. 0. 0</ model Ver si on>
<pa r ent >
<a r t i f a c t l d>f l ex- bugs</ a r t i f a c t l d>
<gr oupI d>or g. f oj </ gr oupI d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
</ pa r ent >
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- l i b</ a r t i f a c t l d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<pa c ka gi ng>swc </ pa c ka gi ng>
<na me>Fl exBugs c ommon l i br a r y</ na me>
<bui l d>
<sour c eD i r ec t or y>sr c / ma i n/ f l ex</ sour c eD i r ec t or y>
<t est Sour c eD i r ec t or y>sr c / t est / f l ex</ t est Sour c eD i r ec t or y>
<f i na l Na me>f l ex- bugs- l i b</ f i na l Na me>
<pl ugi ns>
<pl ugi n>
<gr oupI d>or g. sona t ype. f l exmoj os</ gr oupI d>
<a r t i f a c t l d>f l exmoj os- ma ven- pl ugi n</ a r t i f a c t l d>
<ver si on>${f l exmoj os. Ver si on}</ ver si on>
<ext ensi ons>t r ue</ ext ensi ons>
<dependenc i es>
<dependenc y>
<gr oup! d>c om. a dobe. f l ex</ gr oup! d>
www.it-ebooks.info
Creating a common library 1 7 1
<a r t i f a c t I d>c ompi l er </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
</ dependenc i e s >
<c onf i gur a t i on>
<t a r get Pl a yer >10. 0. 0</ t a r get Pl a yer >
<l oc a l es>
<l oc a l e>en_US</ l oc a l e>
</ l oc a l es>
</ c onf i gur a t i on>
</ pl ugi n>
</ pl ugi ns>
</ bui l d>
<r eposi t or i es>
<r eposi t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent / gr oups/ publ i c / </ ur l >
</ r eposi t or y>
<r eposi t or y>
<i d>f l exonj a va - r eposi t or y</ i d>
<ur l >ht t p : / / f l exonj a va . googl ec ode. c om/ svn/ r eposi t or y- ; / ur l >
</ r eposi t or y>
</ r eposi t or i es>
<pl ugi nReposi t or i es>
<pl ugi nRepos i t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent / gr oups/ publ i c / </ ur l >
</ pl ugi nRepos i t or y>
</ pl ugi nReposi t or i es>
<dependenc i es>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t l d>f l ex- f r a mewor k</ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t I d>pl a yer gl oba l </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>swc </ t ype>
<c l a ssi f i er >10</ c l a ssi f i er >
</ dependenc y>
<dependenc y>
<gr oupI d>or g. degr a f a </ gr oupI d>
<a r t i f a c t l d>degr a f a </ a r t i f a c t l d>
<ver si on>Bet a 3. l </ ver si on>
<t ype>swc </ t ype>
</ dependenc y>
</ dependenc i e s >
<pr oper t i es>
<f l exmoj os. ver si on>3. 2. 0</ f l exmoj os. ver si on>
</ pr oper t i es>
</ pr oj ec t >
A Dégraf a
' dependency
www.it-ebooks.info
172 CHAPTER 9 Desktop 2.0 with AIR
By usi ng the archetype, the onl y modi fi cati on you need to make to di e pom. xml is to
add the dependency on Degr afa O Everyti i i ng else is confi gur ed for you automati -
cally by the archetype.
9.1.2 Ext ract i ng common cl asses
Now that di e pr oj ect has been created, l et's l ook at whi ch classes need to be moved. As
we stated at di e begi nni ng of this chapter, di e onl y fi l e tiiat is goi ng to be di ffer ent
between your Fl ex appl i cati on and your AI R versi on of di e appl i cati on is the
Mai n. mxml appl i cati on fi l e at the r oot of your source di rectory. So everyti i i ng else is a
pr i me candi date to move to di e new l i brary pr oj ect.
NOTE I f you've checked out di e source code f r om Subversi on (r enamed
Apache Subversi on), or are usi ng Subversi on l ocal l y on the proj ect, don't
copy and paste di e fi l es usi ng di e command l i ne or a fi l e expl or er wi ndow.
You'l l have to use the svn move command f r om ei ther the command l i ne, a
Subversi on cl i ent tool such as SmartSVN, or i nsi de di e IDE i f you'r e usi ng one;
otherwi se Subversi on won't know how to track those files.
After you've moved di e fi l es to di e new proj ect, add a dependency on di e new l i brary
pr oj ect you created i n di e f l ex- bugs - r i a proj ect. Open the pom. xml fi l e i n the
f l ex- bugs - r i a pr oj ect and add di e fol l owi ng to di e dependenci es secti on.
<dependenc y>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- l i b</ a r t i f a c t l d>
<ver si on>l . C) - SNAPSHOT</ ver si on>
<t ype>swc </ t ype>
</ dependenc y>
Treat the common l i brary j ust as you do any oti i er Maven dependency, wheti i er it is
for a J ava pr oj ect or a Fl ex proj ect. The onl y di ffer ence bei ng di e type el ement i n
di e dependency, whi ch i n tiiis i nstance is swc , because the dependency is an SWC
library. Now tiiat you've got the common l i brary created, you can now create di e
AI R appl i cati on.
9.1.3 Ext ract i ng a Mai nCanvas
To avoi d havi ng to dupl i cate di e code i n the Mai n. mxml across two separate proj ects,
extract the maj ori ty of tiiat code i nto a separate component i n the common l i brary
proj ect. Create a new MXML fi l e i n di e or g. f oj . vi ew package i n the f l ex- bugs- l i b
pr oj ect and enter the code shown i n listing 9.2.
Li s t i n g 9 . 2 M a i n Ca n v a s . m x m l
<?xml ver si on=" 1. 0" ?>
<s: Gr oup xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o
xml ns: vi ew=" or g. f oj . vi ew. *" >
<
~ 1 Ext ends
O Gr oup
www.it-ebooks.info
Creating a common library 1 7 3
<s: l a yout >
<s: Ver t i c a l La yout / >
</ s: l a yout >
<vi ew: Hea der vi ewSt a c k=" {ma i nVi ewSt a c k}" / >
<mx: Vi ewSt a c k i d=" ma i nVi ewSt a c k" wi dt h=" 100%" hei ght =" 100%" >
<mx: HBox i d=" vi ewl " l a bel =" D et a i l s Vi ew" >
<mx: Spa c er wi dt h=" 5" / >
<mx: HD i vi dedBox wi dt h=" 100%" hei ght =" 100%" >
<mx: VD i vi dedBox wi dt h=" 70%" hei ght =" 100%" >
<vi ew: Ma st er Vi ew i d=" ma st er Vi ew" hei ght =" 60%" / >
<vi ew: Comment sVi ew i d=" c omment sVi ew" hei ght =" 40%" / >
</ mx: VD i vi dedBox>
<vi ew: D et a i l Vi ew i d=" det a i l sVi ew" wi dt h=" 30%" / >
</ mx: HD i vi dedBox>
<mx: Spa c er wi dt h=" 5" / >
</ mx: HBox>
<mx: HBox i d=" vi ew2" l a bel =" Gr a ph Vi ew" >
<mx: Spa c er wi dt h=" 5" / >
<vi ew: Gr a phVi ew wi dt h=" 100%" hei ght =" 100%" / >
<mx: Spa c er wi dt h=" 5" / >
</ mx: HBox>
</ mx: Vi ewst a c k>
<vi ew: Foot er / >
</ s: Gr oup>
The maj ori ty of tire code i n Mai nCanvas.mxml is extracted f r om Mai n. mxml . You start
by decl ari ng this component as extendi ng tire Gr oup component Q , and set its l ayout
ver t i c a l Q . Then paste i n the rest of the code f r om the Mai n. mxml .
Li s t i n g 9 . 3 M a i n . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Appl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=" 950"
mi nHei ght =" 600"
hei ght =" 100%"
wi dt h=" 100%" >
<vi ew: Ma i nCa nva s i d=" a pp" wi dt h=" 100%" hei ght =" 100%" / >
</ mx: Appl i c a t i on>
Li sti ng 9.3 shows tire code drat is l eft over i n Mai n. mxml after you r efactor ed every-
thi ng out i nto the Ma i nCa nva s. Start by changi ng the decl arati on for tire Appl i c a t i on
back to use tire mx: Appl i c a t i on tag O - Ther e appears to be a bug i n tire latest beta
versi on of tire Fl ex 4.0 SDK that ul ti matel y prevents tire appl i cati on f r om r unni ng
3
Set l ayout
J
Changed back t o
mx:Appl i cat i on
J
Mai nCanvas
www.it-ebooks.info
174 CHAPTER 9 Desktop 2.0 with AIR
usi ng the newer Spark versi on of the Appl i c a t i on tag. Next add i n di e Ma i nCa nva s ©
and set its hei ght and wi dt h to 100% so it fills avai l abl e space i n di e appl i cati on win-
dow. Now l et's conti nue and create di e AI R appl i cati on.
9.2 Creat i ng t he AIR appl i cat i on
As you may have guessed, di e fi rst tiling needed to create di e AI R appl i cati on is to cre-
ate a Maven pr oj ect to hol d it. J ust as you di d earlier, open up a command l i ne, navi-
gate to di e r oot fol der for di e proj ect, and enter di e fol l owi ng command.
mvn a r c het ype: c r ea t e - D a r c het ypeGr oupI d=or g. f oj \
- D a r c het ypeAr t i f a c t l d=f l ex- moj os- a r c het ype \
- D a r c het ypeVer si on=l . O- SNAPSHOT \
- D gr oupI d=or g. f oj \
- D a r t i f a c t l d=f l ex- bugs- a i r \
- D ver si on=l . O- SNAPSHOT \
- D r emot eReposi t or i es=
ht t p: / / f l exonj a va . googl ec ode. c om/ svn/ f l ex- bugs/ r eposi t or y
Thi s wi l l create a new modul e i n di e Fl exBugs pr oj ect named f l ex- bu gs - ai r . List-
i ng 9.4 shows di e pom. xml tiiat is gener ated for di e f l ex- bu gs - ai r proj ect.
Listing 9.4 f l ex - bugs- ai r pom.xml
<?xml ver si on=" 1. 0" ?>
<pr oj ec t >
<pa r ent >
<a r t i f a c t l d>f l ex- bugs</ a r t i f a c t l d>
<gr oupI d>or g. f oj </ gr oupI d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
</ pa r ent >
<model Ver si on>4. 0. 0</ model Ver si on>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- a i r </ a r t i f a c t l d>
<pa c ka gi ng>swf </ pa c ka gi ng>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<na me>Fl exBugs Ai r a ppl i c a t i on</ na me>
<pr oper t i es>
<f l exmoj os. ver si on>3. 3. 0</ f l exmoj os. ver si on>
</ pr oper t i es>
<bui l d>
<sour c eD i r ec t or y>sr c / ma i n/ f l ex</ sour c eD i r ec t or y>
<t est Sour c eD i r ec t or y>sr c / t est / f l ex</ t est Sour c eD i r ec t or y>
<r esour c es>
<r esour c e>
<di r ec t or y>$ {ba sedi r } / sr c / ma i n/ r esour c es- ; / di r ec t or y>
</ r esour c e>
<r esour c e>
<di r ec t or y>$ {ba sedi r } / t a r get / gener a t ed- r esour c es- ; / di r ec t or y>
<f i l t er i ng>t r ue</ f i l t er i ng>
</ r esour c e>
</ r esour c es>
www.it-ebooks.info
Creating the Grails application 175
<f i na l Na me>f l ex- bugs- a i r </ f i na l Na me>
<pl ugi ns>
<pl ugi n>
<gr oupI d>or g. sona t ype. f l exmoj os</ gr oupI d>
<a r t i f a c t l d>f l exmoj os- ma ven- pl ugi n</ a r t i f a c t l d>
<ver si on>${f l exmoj os. ver si on}</ ver si on>
<ext ensi ons>t r ue</ ext ensi ons>
<c onf i gur a t i on>
<c ont ext Root >f l exbugs</ c ont ext Root >
<t a r get Pl a yer >10. 0. 0</ t a r get Pl a yer >
<l oc a l es>
<l oc a l e>en_US</ l oc a l e>
</ l oc a l es>
</ c onf i gur a t i on>
<dependenc i es>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex</ gr oupI d>
<a r t i f a c t I d>c ompi l er </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
</ dependenc i e s >
</ pl ugi n>
</ pl ugi ns>
</ bui l d>
<r eposi t or i es>
<r eposi t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent / gr oups/ publ i c / </ ur l >
</ r eposi t or y>
<r eposi t or y>
<i d>f l exonj a va - r eposi t or y</ i d>
<ur l >ht t p: / / f l exonj a va . googl ec ode. c om/ svn/ r eposi t or y- ; / ur l >
</ r eposi t or y>
</ r eposi t or i es>
<pl ugi nReposi t or i es>
<pl ugi nRepos i t or y>
<i d>f l exmoj os- r eposi t or y</ i d>
<ur l >ht t p: / / r eposi t or y. sona t ype. or g/ c ont ent / gr oups/ publ i c / </ ur l >
</ pl ugi nReposi t or y>
</ pl ugi nReposi t or i es>
<dependenc i es>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t l d>a i r - f r a mewor k</ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
<dependenc y>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- l i b</ a r t i f a c t l d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<t ype>swc </ t ype>
</ dependenc y>
AIR SDK
O dependency
<
~ l k Com m on l i br ar y
G dependency
www.it-ebooks.info
1 7 6 CHAPTER 9 Desktop 2.0 with AIR
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t l d>f l ex- f r a mewor k</ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<t ype>pom</ t ype>
</ dependenc y>
<dependenc y>
<gr oupI d>c om. a dobe. f l ex. f r a mewor k</ gr oupI d>
<a r t i f a c t I d>pl a yer gl oba l </ a r t i f a c t l d>
<ver si on>4. 0. 0. 7219</ ver si on>
<c l a ssi f i er >10</ c l a ssi f i er >
<t ype>swc </ t ype>
</ dependenc y>
</ dependenc i e s >
</ pr oj ec t >
As befor e, you have to make onl y mi nor modi fi cati ons to di e pom. xml for di e AI R
modul e. You add the dependency on di e AI R fr amewor k © and the dependency on
di e common l i brary you extracted earl i er Q . Now you can create di e Mai n. mxml for
di e AI R appl i cati on.
Li s t i n g 9 . 5 AI R M a i n . m x m l
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<s: Wi ndowedAppl i c a t i on xml ns: f x=" ht t p: / / ns. a dobe. c om/ mxml / 2009"
xml ns: s=" l i br a r y: / / ns. a dobe. c om/ f l ex/ spa r k"
xml ns: mx=" l i br a r y: / / ns. a dobe. c om/ f l ex/ ha l o"
xml ns: vi ew=" or g. f oj . vi ew. *"
mi nWi dt h=" 1024" .... . ,. .. A
WindowedApplication U
mi nHei ght =" 768"
r r
hei ght =" 100%"
wi dt h=" 100%" >
Mai nCanvas
<vi ew: Ma i nCa nva s i d=" a pp" wi dt h=" 100%" hei ght =" 100%" / >
^ ^ Main
</ s : Wi ndowedAppl i c a t i on>
The code for di e AI R appl i cati on is al most i denti cal to di e code necessary for the Fl ex
appl i cati on wi th di e one maj or di ffer ence bei ng tiiat the AI R appl i cati on extends di e
Wi ndowedAppl i c a t i on O i nstead of Appl i c a t i on as the Fl ex appl i cati on does. Last
you need to add di e Ma i nCa nva s to di e AI R appl i cati on Q . Next, l et's l ook at how to
go about creati ng the appl i cati on installer.
9.3 Pack agi ng t he AIR appl i cat i on
So now you've got the AI R versi on of di e sampl e appl i cati on created, and tiiat wi l l
gener ate a di ffer ent SWF tiiat you can use to package i nto an AI R appl i cati on. To dis-
tri bute this as an AI R appl i cati on you need to create a pr oj ect tiiat wi l l gener ate an
AI R appl i cati on installer for the AI R appl i cati on. Thi s wi l l al l ow you to distribute di e AI R
appl i cati on to the users to install by ei ther di stri buti ng the .air fi l e that is created, or
as you'l l see l ater i n tiiis chapter, by i nstal l i ng it via the web.
www.it-ebooks.info
Di stri buti ng the AIR application 1 7 7
NOTE Unti l now we've been abl e to get by wi thout havi ng to downl oad and
install di e FlexSDK. Unfor tunatel y because of l i censi ng restrictions, Sonatype
cannot publ i sh tire ADT J AR to tire Maven reposi tory. T o get ar ound tiris,
downl oad and install tire Fl ex4 SDK f r om Adobe's site at http:/ / www.adobe.
com/ go/ fl ex4_sdk_downl oad.
To package tire AI R appl i cati on, you use tire AI R Devel oper Tool (ADT). Because tiris
tool is not a part of tire open source SDK, you'l l need to manual l y install tire J AR fi l e,
found i n tire l i b di rectory of your Fl exSDK install, to tire l ocal Maven reposi tory usi ng
the fol l owi ng command.
mvn i nst a l l : i nst a l l - f i l e - D f i l e=a dt . j a r - D gr oupI d=c om. a dobe \
- D a r t i f a c t l d=a dt - D ver si on=4. 0. 0 - D pa c ka gi ng=j a r - D gener a t ePom=t r ue
After you've got drat l i brary i nstal l ed i nto tire l ocal reposi tory you'r e ready to move on
to creati ng tire pr oj ect that wi l l contai n all of tire confi gur ati on and assets necessary to
package tire AI R appl i cati on.
9.3.1 Creat i ng a proj ect t o pack age t he AIR app
One last time you need to gener ate a new Maven pr oj ect drat wi l l contai n all tire assets
for creati ng the AI R appl i cati on i nstal l er package. Open a command l i ne and navi gate
to tire r oot of tire pr oj ect and enter tire fol l owi ng command:
mvn a r c het ype: c r ea t e - D a r c het ypeGr oupI d=or g. f oj \
- D a r c het ypeAr t i f a c t l d=f l ex- moj os- a r c het ype \
- D a r c het ypeVer si on=l . O- SNAPSHOT \
- D gr oupI d=or g. f oj \
- D a r t i f a c t l d=f l ex- bugs- a i r - pa c ka ge \
- D ver si on=l . O- SNAPSHOT \
- D r emot eReposi t or i es=
ht t p: / / f l exonj a va . googl ec ode. c om/ svn/ f l ex- bugs/ r eposi t or y
Thi s wi l l create a new pr oj ect fol der named flex-bugs-air-package. I nsi de this proj -
ect you'l l see the standard fol der l ayout drat you've been usi ng all al ong. You can
del ete tire sr c/ mai n/ fl ex fol der and the src/ test fol ders, as you won't need them for
this proj ect.
9.3.2 Generat i ng a cert i f i cat e
To create an AI R appl i cati on i nstal l er you first gener ate a certi fi cate for si gni ng the
appl i cati on. The certi fi cate is necessary because you now are r unni ng an appl i cati on
l ocal l y on the computer, whi ch gi ves the appl i cati on access to l ocal resources that it
woul d not have had i n a si mpl e Fl ex appl i cati on, such as tire fi l esystem. I n l i ght of
that, Adobe deci ded to take measures to secure tire AI R i nstal l er by r equi r i ng you to
si gn it wi th ei ther a sel f-si gned certi fi cate, whi ch we'l l be using, or a di gi tal certi fi cate
that you woul d purchase f r om a certi fi cate authori ty (CA). That way nobody can tam-
per witir the appl i cati on and i ntr oduce mal i ci ous software to unsuspecti ng users.
www.it-ebooks.info
178 CHAPTER 9 Desktop 2.0 with AIR
For the exampl e, you'l l create a sel f-si gned certi fi cate, but i f you'r e di stri buti ng the
appl i cati on to the masses, it woul d be a good i dea to purchase a certi fi cate f r om a CA
such as Thawte (http:/ / www.tl i awte.com). To gener ate the certi fi cate you'l l use the
ADT utility i ncl uded wi th the Fl exSDK l ocated i n the bi n di rectory of di e SDK. The
basic usage for this tool is:
a dt - c er t i f i c a t e - c n na me [ - ou or g_uni t ] [ - o or g_na me] [ - c c ount r y] \
key_t ype pf x_f i l e pa sswor d
Thi s is di e basic usage of di e ADT utility that you'l l use to gener ate the certi fi cate.
Her e is an expl anati on of the abbrevi ati ons and opti ons:
• -cn: The common name of the new certi fi cate
• -ou: The organi zati onal uni t (opti onal )
• -o: The organi zati on name (opti onal )
• -c: The two-l etter country code (opti onal )
• key_type: The type of key used to create di e certi fi cate, 1024-RSA or 2048-RSA
• pfx_fi l e: The name of the certi fi cate fi l e to be created
• password: The password for di e certi fi cate you are creati ng
To gener ate your own sel f-si gned certi fi cate, open a command pr ompt and enter di e
fol l owi ng command:
a dt - c er t i f i c a t e - c n Fl exBugs 1024- RSA f l exbugs. pf x j a va 4ever
Thi s wi l l create a certi fi cate fi l e cal l ed fl exbugs. pfx wi ti i a password of j ava4ever . You
now need to copy this fi l e i nto di e src/ mai n/ resources fol der of di e f l ex- bu gs - ai r -
package pr oj ect so that you can sign the appl i cati on i nstal l er wi th it. Now let's see how
you add i cons to di e appl i cati on.
9.3.3 Addi ng i cons
Adobe AI R appl i cati ons al l ow you to defi ne i cons tiiat the OS displays i n di e dock/
taskbar, pr ogr ams fol der, fi l e expl or er wi ndow, and mor e. I f you don't pr ovi de a cus-
tom i con set, di e OS wi l l use a defaul t i con. Ther e are four common sizes of i cons you
can i ncl ude for the appl i cati on:
• 16x16
• 32x32
• 48x48
• 128x128
The i con we've chosen for the appl i cati on, whi ch is shown i n fi g-
ure 9.2, was found at di e Wi ki medi a Commons site at http:/ /
commons.wi ki medi a.org/ wi ki / Fi l e:Green_bug.svg.
You can downl oad the i con graphi c f r om di e Wi ki medi a Com-
mons site and create the i con sizes you need for the appl i cati on Figure 9 2 The ic<
usi ng your favori te i mage edi ti ng software, or i f you'd prefer, use for the application
www.it-ebooks.info
Di stri buti ng the AIR application 1 7 9
the fi l es i ncl uded i n di e code downl oad for tiris book. Ther e is a PNG i mage fi l e for
each cor r espondi ng i con size as fol l ows.
• i conl ô. png for the 16x16 i con
• i con32. png for the 32 x 32 i con
• i con48. png for the 48 x 48 i con
• i conl 28. png for dre 128 x 128 i con
After you've created the i con fi l es, copy them i nto the f l ex- bu gs - ai r - pack age proj -
ect i n dre src/ mai n/ resources/ i cons fol der. Now that you've got all dre assets you
need to create dre AI R package, l et's l ook at the AI R confi gur ati on necessary to pack-
age dre appl i cati on.
9.3.4 Addi ng t he AIR conf i gurat i on
Th e last thi ng you need to do to package dre appl i cati on as an AI R appl i ca-
ti on is to create tire appl i cati on confi gurati on fi l e. To do tiris, create a fi l e named
ai r- app.xml and pl ace it i n tire src/ mai n/ resources fol der of the f l ex- bu g- ai r -
package pr oj ect.
The AI R appl i cati on descri ptor fi l e is used to defi ne vari ous properti es for tire AI R
appl i cati on. The fol l owi ng are a few of the thi ngs you can confi gur e usi ng the appl i ca-
ti on descri ptor:
• The r equi r ed AI R r unti me versi on
• A uni que i denti fi er for the appl i cati on
• The fi l ename and path for i nstal l i ng tire ai r appl i cati on
• The appl i cati on versi on
• The size and display pr oper ti es of tire appl i cati on wi ndow
• Any appl i cati on- speci fi c i cons
You can l earn mor e about tire other features of tire appl i cati on descri ptor drat we haven't
menti oned at Adobe's websi te, i n tire AI R documentati on l ocated at http:/ / hel p.adobe,
com/ en_US/ AI R/ 1. 5/ devappshtml / WS5b3ccc516d4I bf351 e63e3d 118666ade46- 7ffl .
html . Li sti ng 9.6 shows the confi gur ati on fi l e you'l l use for tiris appl i cati on.
Li s t i n g 9 . 6 a i r -a p p . xm l
<?xml ver si on="1. 0" enc odi ng=" UTF- 8 " ?>
A I R
appl i cat i on namespace
<a ppl i c a t i on xml ns=" ht t p: / / ns. a dobe. c om/ a i r / a ppl i c a t i on/ 1. 5" >
<i d>or g. f oj . Fl exBugs</ i d>
J
<f i l ena me>Fl exBugs</ f i l ena me>
<na me>Fl exBugs For D eskt op</ na me>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<c opyr i ght >
Copyr i ght &c opy; Fl exOnJ a va 2009 ht t p: / / ma nni ng. c om/ a l l mon
</ c opyr i ght >
A Appl i cat i on
' met adat a
www.it-ebooks.info
180 CHAPTER 9 Desktop 2.0 with AIR
<i ni t i a l Wi ndow>
<c ont ent >f l exbugs. swf </ c ont ent >
<t i t l e>Fl exBugs For D eskt op</ t i t l e>
<wi dt h>1024</ wi dt h>
<hei ght >7 68</ hei ght >
<mi nSi ze>1024 768</ mi nSi ze>
</ i ni t i a l Wi ndow>
<i c on>
<i ma gel 6xl 6>i c ons/ i c onl 6. png</ i ma gel 6xl 6>
<i ma ge32x32>i c ons/ i c on32. png</ i ma ge32x32>
<i ma ge48x48>i c ons/ i c on48. png</ i ma ge48x48>
<i ma gel 28xl 28>i c ons/ i c onl 28. png</ i ma gel 28xl 28>
</ i c on>
Ini t i al wi ndow
O Appl i cat i on i cons
</ a ppl i c a t i on>
The r oot el ement of the appl i cati on descri ptor defi nes di e versi on of di e AI R appl i ca-
tion you'r e creati ng, i n this case versi on 1.5 Q . Next come el ements defi ni ng the
appl i cati on metadata Q starting wi th a uni que i denti fi er for the appl i cati on. The
appl i cati on i nstal l er uses this i denti fi er to deter mi ne i f di e appl i cati on has been previ -
ously i nstal l ed on di e computer. Then you defi ne a fi l ename and a descri pti ve name
for the appl i cati on. You defi ne your versi on for di e appl i cati on to be 1.0-SNAPSHOT,
whi ch also happens to match the versi on i n di e pom. xml . The two versi ons are unre-
l ated; it makes sense to keep tiiese two versi ons i n sync.
The next secti on i n the appl i cati on confi gur ati on deals wi th how di e appl i cati on
behaves when l aunched Start by defi ni ng di e i ni ti al content di spl ayed i n di e appl i -
cati on when it starts up as bei ng the SWF for the AI R appl i cati on. The title of the wi n-
dow is set to FlexBugs For Desktop, and you've confi gur ed di e appl i cati on to start wi th a
1024 x 762 wi ndow and also made that be di e mi ni mum size the appl i cati on wi l l run.
As a fi nal step you confi gur e the appl i cati on to use the i cons created earl i er Q .
9.3.5 Conf i guri ng t he pack age bui l d
Befor e you can bui l d and run di e appl i cati on you need to tweak di e pom. xml that
was gener ated for di e f l ex- bu gs - ai r - pack age modul e. The pom. xml is rati i er l arge
so we'l l break it down and discuss each pl ugi n separately; the fi rst part is shown i n list-
i ng 9.7. The discussion conti nues thr ough listing 9.11.
Listing 9.7 f l ex- bugs- ai r - pac k age pom.xml
<pr oj ec t xml ns=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ ma ven- v4_0_0. xsd" >
<model Ver si on>4. 0. 0</ model Ver si on>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- a i r - pa c ka ge</ a r t i f a c t l d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
www.it-ebooks.info
Di stri buti ng the AIR application 181
<na me>Fl exBugs Ai r Pa c ka ge</ na me>
<pa c ka gi ng>pom</ pa c ka gi ng>
<bui l d>
1,
Packaging t ype
^ ^ p exec-m aven-pl ugi n
J
Phase t o execut e i n
1>
Goal t o r un
Execut abl e
<pl ugi ns>
<pl ugi n>
<gr oupI d>or g. c odeha us. moj o</ gr oupI d>
<a r t i f a c t l d>exec - ma ven- pl ugi n</ a r t i f a c t l d>
<ver si on>l . 1. l </ ver si on>
<exec ut i ons>
<exec ut i on>
<pha se>pa c ka ge</ pha se>
<goa l s>
<goa l >exec </ goa l >
</ goa l s>
<c onf i gur a t i on>
<exec ut a bl e>j a va </ exec ut a bl e>
<wor ki ngD i r ec t or y>
${ba sedi r }/ t a r get / a i r
</ wor ki ngD i r ec t or y>
<a r gument s>
<a r gument >- c l a sspa t h</ a r gument >
<c l a sspa t h/ >
<a r gument >c om. a dobe. a i r . AD T</ a r gument >
<a r gument >- pa c ka ge</ a r gument >
<a r gument >- st or et ype</ a r gument >
<a r gument >pkc sl 2</ a r gument >
<a r gument >- st or epa ss</ a r gument >
<a r gument >j a va 4ever </ a r gument >
<a r gument >- keyst or e</ a r gument >
<a r gument >c er t s/ f l exbugs. pf x</ a r gument >
<a r gument >${ba sedi r }/ t a r get / a i r / f l exbugs. a i r </ a r gument >
<a r gument >a i r - a pp. xml </ a r gument >
<a r gument >f l exbugs. swf </ a r gument >
<a r gument >i c ons/ i c onl 6. png</ a r gument >
<a r gument >i c ons/ i c on32. png</ a r gument >
<a r gument >i c ons/ i c on48. png</ a r gument >
<a r gument >i c ons/ i c onl 28. png</ a r gument >
</ a r gument s>
</ c onf i gur a t i on> Command l i ne argument s 0
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
Start tire POMj ust as you di d for the shared BlazeDS confi gur ati on i n chapter 5, setti ng
the packagi ng type to pom O - Unfor tunatel y tire Fl ex- Moj os pl ugi n you've been usi ng
all al ong for bui l di ng the Fl ex appl i cati on does not i ncl ude a pl ugi n for packagi ng the
AI R appl i cati on, so you have to use the ADT utility pr ovi ded by Adobe i n the SDK. To
do this use a Maven pl ugi n cal l ed exec- maven- pl ugi n Q . Confi gur e tire pl ugi n to be
executed dur i ng tire package phase of tire Maven l i fecycl e and to execute tire exec
goal O You'l l be executi ng tire J ava executabl e Q to uti l i ze tire ADT utility © we
descr i bed earl i er. The fi rst set of ar guments you pass i nto the ADT utility deal wi th
www.it-ebooks.info
182 CHAPTER 9 Desktop 2.0 with AIR
the certi fi cate you gener ated earl i er i n this chapter. Next speci fy the output fi l e, the
l ocati on of the AI R appl i cati on confi gurati on, the SWF fi l e to i ncl ude i n the AI R appl i -
cati on, and di e appl i cati on i cons.
Li s t i n g 9 . 8 f l ex- bugs- ai r - pac k age p o m . xm l ( c o n t i n u e d )
<pl ugi n>
<gr oupI d>or g. a pa c he. ma ven. pl ugi ns</ gr oupI d>
<a r t i f a c t l d>ma ven- a ssembl y- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>Pa c ka ge AI R di st r i but i on</ i d>
<goa l s>
<goa l >si ngl e</ goa l >
</ goa l s>
<pha se>pa c ka ge</ pha se>
<c onf i gur a t i on>
<desc r i pt or s>
<desc r i pt or >
sr c / ma i n/ a ssembl y/ r esour c es. xml
</ desc r i pt or >
</ desc r i pt or s>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
J
1,
Assembl y
pl ugi n
Goal t o
execut e
Phase t o
execut e i n
1 >
Locat i on of resource
descr i pt or
Li sti ng 9.8 shows the confi gur ati on for creati ng an assembly for our AI R installer. I t
l ooks similar to the confi gur ati on you used i n chapter 5. The pl ugi n confi gur ati on
starts by defi ni ng itself as di e maven- assembl y- pl ugi n O You'l l be cal l i ng di e si ngl e
goal © duri ng di e package phase of di e Maven l i fecycl e Last you tell di e pl ugi n
wher e to fi nd di e assembly descri ptor Q .
Next you'l l confi gur e Maven to copy di e fi l es you need to a wor ki ng di rectory for
di e ADT utility for use when bui l di ng di e AI R installer.
Li s t i n g 9 . 9 f l ex- bugs- ai r - pac k age p o m . xm l ( c o n t i n u e d )
Maven-r esour ces-pl ugi n
'"J
J
Phase t o
execut e i n
<pl ugi n>
<gr oupI d>or g. a pa c he. ma ven. pl ugi ns</ gr oupI d>
<a r t i f a c t I d>ma ven- r esour c es- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>a i r </ i d>
<pha se>gener a t e- r esour c es- ; / pha se>
<goa l s>
<goa l >c opy- r esour c es- ; / goa l >
</ goa l s>
<c onf i gur a t i on>
<out put D i r ec t or y>${ba sedi r }/ t a r get / a i r </ out put D i r ec t or y> <
<r esour c es>
0 u t p u t di r ec t or y
t o copy resources t o O
J
Goal t o
execut e
<r esour c e>
www.it-ebooks.info
Di stri buti ng the AIR application 183
<di r ec t or y>${ba sedi r }/ sr c / ma i n/ r esour c es«/ di r ec t or y>
</ r esour c e>
</ r esour c es>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
Resource di r ect or y 1
Earl i er you confi gur ed the ADT utility to use a wor ki ng di rectory of target/ ai r to do
its wor k in. To get all tire resources you need i nto drat di r ector y l everage tire
maven- r esour ces- pl ugi n O - Confi gur e tire pl ugi n to execute its copy- r esour ces
goal Q dur i ng tire gener at e- r esou r ces phase of tire Maven l i fecycl e © and tel l it
to copy the resources f r om tire src/ mai n/ resources di rectory © to tire target/ ai r
di rectory Q .
•1 g in O
Maven-dependency-pl ugi n
Goal t o execut e
^ ^ P Phase t o execut e i n
Usi i f Usi ng art i f act i t em
Li s t i n g 9 . 1 0 f l ex- bugs- ai r - pac k age ( c o n t i n u e d )
<pl ugi n>
<a r t i f a c t l d>ma ven- dependenc y- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>unpa c k- a i r - a sset s</ i d>
<goa l s>
<goa l >c opy</ goa l >
</ goa l s>
<pha se>gener a t e- r esour c es</ pha se>
<c onf i gur a t i on>
<a r t i f a c t l t ems>
<a r t i f a c t l t em>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- a i r </ a r t i f a c t l d>
<ver si on>l . C) - SNAPSHOT</ ver si on>
<t ype>swf </ t ype>
<over Wr i t e>f a l se</ over Wr i t e>
<out put D i r ec t or y>
${ba sedi r }/ t a r get / a i r
</ out put D i r ec t or y>
<dest Fi l eNa me>f l exbugs. swf </ dest Fi l eNa me>
</ a r t i f a c t l t em>
</ a r t i f a c t l t ems>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
Li sti ng 9.10 shows tire confi gur ati on for unpacki ng the AI R SWF to be used by tire ADT
utility when bui l di ng tire AI R installer. To do this use tire maven- dependency- pl ugi n
j ust as you do for copyi ng tire Fl ex SWF i nto the WAR befor e packagi ng. Confi gur e
this pl ugi n to execute the copy goal © duri ng tire gener at e- r esou r ces phase of tire
Maven l i fecycl e ©. I t's goi ng to copy the arti fact you defi ne i n its confi gur ati on ©.
You tel l tire pl ugi n to copy tire arti fact to tire target/ ai r di rectory © so that it can be
i ncl uded when creati ng tire AI R installer.
J
Out put di r ect or y
www.it-ebooks.info
1 8 4 CHAPTER 9 Desktop 2.0 with AIR
Li s t i n g 9 . 1 1 f l ex- bugs- ai r - pac k age p o m . x m l ( c o n t i n u e d )
<pl ugi n>
<a r t i f a c t l d>ma ven- c l ea n- pl ugi n</ a r t i f a c t l d>
<ver si on>2. 2</ ver si on>
<c onf i gur a t i on>
<f i l eset s>
<f i l eset >
<di r ec t or y>t a r get </ di r ec t or y>
</ f i l eset >
</ f i l eset s>
</ c onf i gur a t i on>
</ pl ugi n>
</ pl ugi ns>
</ bui l d>
<dependenc i es>
<! - - Fl ex AD T t ool - - >
<dependenc y>
<gr oupI d>c om. a dobe</ gr oupI d>
<a r t i f a c t l d>a dt </ a r t i f a c t l d>
<ver si on>4. 0. 0</ ver si on>
<t ype>j a r </ t ype>
</ dependenc y>
<! - - Pr oj ec t D ependenc i es - - >
<dependenc y>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- a i r </ a r t i f a c t l d>
<ver si on>l . C) - SNAPSHOT</ ver si on>
<t ype>swf </ t ype>
</ dependenc y>
</ dependenc i e s >
</ pr oj ec t >
Li sti ng 9.11 shows the rest of the pom. xml for our packagi ng proj ect. You confi gur e
one last pl ugi n, the maven- cl ean- pl ugi n, for cl eanup. Q . The onl y ti l i ng l eft is to
decl are the dependenci es. The fi rst is on di e ADT utility so you can use that to bui l d
di e AI R installer. The second is on di e SWF arti fact for the AI R appl i cati on so that
you can i ncl ude it i n di e AI R installer.
Wi th all of those pi eces i n pl ace, you shoul d now be abl e to bui l d and install
di e AI R appl i cati on. Open a command l i ne and navi gate to the mai n pr oj ect
fol der, di en bui l d di e appl i cati on by typi ng mvn cl ean i n s t al l . Thi s wi l l go
thr ough and bui l d each of di e pr oj ect modul es. When it's fi ni shed, change i nto
di e flex-bugs-web di rectory so you can start up the web appl i cati on usi ng the mvn
j et t y: run- war command.
Aft er the web appl i cati on is r unni ng, open a file expl or er wi ndow and navi-
gate to the target/ ai r di rectory i n di e f l ex- bu gs - ai r - pack age proj ect. I nsi de this
fol der di er e shoul d be a file named fl exbugs.ai r. Thi s is di e i nstal l er for di e AI R
appl i cati on. Launch the i nstal l er and you shoul d be presented wi ti i a screen that
l ooks l i ke fi gur e 9.3.
Maven-cl ean-pl ugi n
1 »
ADT dependency
AIR dependency
www.it-ebooks.info
Di stri buti ng the AIR application 185
Application Install
Are yo u su re yo u wa n t to in sta ll th is
a p p lica tio n to yo u r co m p u te r?
Appl i cat i on: Flex Bu g; For Desk t oe
Cancel Install
i nst i l l i ng appl i cat i ons may present a securi t y risk t o you and your
computer. Install only from sources that you trust.
x Publ i sher I dent i t y UNKNOWN
The publ i sher of t hi s appl i cat i on cannot be det ermi ned.
x Syst em Access: UNRESTRI CTED
Thi s appl i cat i on may accessvour f l l e syst em and [he Int ernet ,
whi ch may put your comput er at ri sk.
Figure 9.3
Installing the
AIR application
Because you'r e usi ng a sel f-si gned certi fi cate, the i nstal l er warns you drat it's not sure
who wr ote tire appl i cati on and wheti rer or not they're trustworthy. After you cl i ck the
I nstall button you wi l l be pr esented witir a screen that l ooks l i ke fi gur e 9.4.
Appl i cati on I nstal l
Figure 9.4
Choosing where
to install the
application
Fle xB u g s Fo r D e sk to p
Insulation Pnftrenw
Q Start application after Installation
I nst al l at i on Loca t i on :
/ Appl i cat i ons
Cancel Continue
www.it-ebooks.info
186 CHAPTER 9 Desktop 2.0 with AIR
F le xB u g s A p p li ca ti o n
f rrrtMHI i Oj i t
Figure 9.5 The finished AIR application
On the second screen of the installer, you'r e asked i f you'd l i ke to l aunch di e appl i -
cati on when it's fi ni shed installing, and wher e you'd l i ke to install the appl i cati on. I f
you checked the checkbox i ndi cati ng that the appl i cati on shoul d start after installa-
tion, the appl i cati on shoul d l aunch and you shoul d see somethi ng tiiat resembl es
fi gur e 9.5.
Now you've got a versi on of the Fl exBugs appl i cati on that works outsi de di e
browser but you'r e stuck wi ti i the task of di stri buti ng this appl i cati on to the users. I n
di e next secti on you'l l take a l ook at the task of creati ng a web page to al l ow you to dis-
tri bute di e AI R appl i cati on usi ng an i nstal l er badge, whi ch allows users to install the
appl i cati on si mpl y by cl i cki ng the badge.
9.4 Di st ri but i ng t he AIR appl i cat i on
One of di e benefi ts to usi ng a web appl i cati on is the ease of di stri buti ng the appl i -
cati on to the peopl e who wi l l use it. Adobe has enabl ed you to streaml i ne di e distri-
buti on and i nstal l ati on process for AI R appl i cati ons by pr ovi di ng a SWF tiiat wi l l
al l ow the users to install di e AI R appl i cati on by cl i cki ng a badge i con tiiat you can
pl ace on any web page. I n this next secti on you'l l create an i nstal l er badge for the
sampl e appl i cati on.
www.it-ebooks.info
Distributing the AIR application 187
9.4.1 Assembl y conf i gurat i on
To distribute di e AI R appl i cati on, you fi rst get the appl i cati on i nstal l er i nto a pl ace
wher e the users can access it via a web browser. You al ready have tiris mechani sm i n
pl ace. You can l everage tire exi sti ng web appl i cati on and copy tire AI R arti fact i nto tire
WAR fi l e that wi l l be depl oyed to the appl i cati on server, whi ch also happens to be
wher e we woul d create the downl oad page. To do this you'l l take an appr oach si mi l ar
to drat you used to handl e the shared BlazeDS confi gur ati on i n chapter 5. Because
Maven doesn't know how to handl e .air fi l es, you can l everage tire assembly pl ugi n.
Create a fi l e cal l ed resources.xml i nsi de di e src/ mai n/ assembl y fol der of tire f l ex -
bugs- ai r - pack age proj ect. Thi s is tire fi l e that tells Maven whi ch fi l es to i ncl ude i n
the assembly.
Li s t i n g 9 . 1 2 r e s o u r c e s . x m l
<a ssembl y>
<i d>r esour c es</ i d>
<f or ma t s>
<f or ma t >zi p</ f or ma t >
</ f or ma t s>
<i nc l udeBa seD i r ec t or y>f a l se</ i nc l udeBa seD i r ec t or y>
<f i l eSet s>
<f i l eSet >
<di r ec t or y>t a r get / a i r </ di r ec t or y>
<out put D i r ec t or yx/ out put D i r ec t or y>
<i nc l udes>
<i nc l ude>**/ *. a i r </ i nc l ude>
</ i nc l udes>
</ f i l eSet >
</ f i l eSet s>
</ a ssembl y>
Si mi l ar to what you di d earlier, confi gur e tire assembly to be of type zi p O - The
mai n di ffer ence between tiris resource confi gur ati on and what you di d i n chapter 5
is drat you'r e confi gur i ng the assembly to contai n onl y tire .air fi l e whi ch is created
by tire ADT uti l i ty Q . Next you need to update the bui l d to be abl e to unpack
the assembly.
9.4.2 Updat i ng t he bui l d
To get tire AI R i nstal l er i nto tire web appl i cati on you need to be abl e to extract
the AI R appl i cati on f r om tire assembly you j ust confi gur ed. To do tiris you'l l be
creati ng another executi on i n the maven- dependency- pl ug i n secti on similar to tire
way i n whi ch you get tire shared BlazeDS confi gur ati on i nto tire WAR. Li sti ng 9.13
shows tire confi gur ati on you'l l add to the pom. xml i n tire f l ex- bu gs- web proj ect.
Li s t i n g 9 . 1 3 f l ex- bugs- web p o m . xm l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<pr oj ec t xml ns=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
A Format f or t he
assembl y
A •"<
-ail
Incl ude onl y
ai r f i l es
www.it-ebooks.info
188 CHAPTER 9 Desktop 2.0 with AIR
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e"
xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ ma ven- v4_0_0. xsd" >
<bui l d>
<def a ul t Goa l >i nst a l l </ def a ul t Goa l >
<f i na l Na me>f l exbugs</ f i na l Na me>
<pl ugi ns>
<pl ugi n>
<a r t i f a c t l d>ma ven- dependenc y- pl ugi n</ a r t i f a c t l d>
<exec ut i ons>
<exec ut i on>
<i d>unpa c k- bl a ze- c onf i g</ i d>
</ exec ut i on>
<exec ut i on>
<i d>unpa c k- a i r - pa c ka ge</ i d> O Unpa c k
<goa l s>
J
dependenci es
Wh er e t o unpack t he f i l e 0
<goa l >unpa c k- dependenc i es</ goa l > <—I a phase t o
</ goa l s> J execut e i n
<pha se>gener a t e- r esour c es- ; / pha se>
<c onf i gur a t i on>
<out put D i r ec t or y>
$ {pr o j ec t . bui l d, di r ec t or y} / $ {pr o j ec t . bui l d, f i na l Na me} <1—'
</ out put D i r ec t or y>
<i nc l udeGr oupI ds>${pr oj ec t . gr oupI d}</ i nc l udeGr oupI ds>
<i nc l udeAr t i f a c t l ds> <—, Ar t i f act t o
f l ex- bugs- a i r - pa c ka ge Q i ncl ude
</ i nc l udeAr t i f a c t l ds>
<i nc l udeCl a ssi f i er s>r esour c es</ i nc l udeCl a ssi f i er s>
<exc l udeTr a nsi t i ve>t r ue</ exc l udeTr a nsi t i ve>
<exc l udeTypes>j a r , swf </ exc l udeTypes>
</ c onf i gur a t i on>
</ exec ut i on>
</ exec ut i ons>
</ pl ugi n>
</ pr oj ec t >
First you create another executi on i nsi de di e maven- dependency- pl ugi n confi gura-
tion whi ch you confi gur e to execute the unpack- dependenci es goal Q dur i ng the
gener at e- r esou r ces phase of di e Maven l i fecycl e ©. You want di e pl ugi n to extract
di e AI R appl i cati on and put it i n di e wor ki ng di rectory tiiat Maven uses when packag-
i ng up the WAR fi l e ©. You also need to confi gur e di e pl ugi n to make sure tiiat it
i ncl udes onl y di e a r t i f a c t l d you want it to unpack Q .
Next, you need to add the dependency for di e assembly i n the dependenci es sec-
tion of the pom. xml i n the f l ex- bu gs- web proj ect. Add di e fol l owi ng dependency to
di e POM:
www.it-ebooks.info
Distributing the AIR application 189
<dependenc y>
<gr oupI d>or g. f oj </ gr oupI d>
<a r t i f a c t l d>f l ex- bugs- a i r - pa c ka ge</ a r t i f a c t l d>
<ver si on>l . 0- SNAPSHOT</ ver si on>
<c l a ssi f i er >r esour c es</ c l a ssi f i er >
<sc ope>pr ovi ded</ sc ope>
<t ype>zi p</ t ype>
</ dependenc y>
Wi th tliat i n pl ace, you can move on to creati ng tire downl oad page, whi ch wi l l contai n
the i nstal l er badge.
9.4.3 Creat i ng a downl oad badge
You'r e goi ng to create another J SP page i n tire f l ex- bug- web pr oj ect to contai n tire
install badge. Create a file i nsi de tire src/ mai n/ webapp fol der cal l ed downl oa d, j sp,
and enter tire code shown i n listing 9.14.
Li s t i n g 9 . 1 4 d o w n l o a d . j s p
<%@ t a gl i b pr ef i x=" c " ur i =" ht t p: / / j a va . sun. c om/ j sp/ j st l / c or e" %>
<! D OCTYPE ht ml PUBLI C ' - / / W3C/ / D TD XHTML 1. 0 St r i c t / / EN'
1
ht t p: / / www. w3 . or g/ TR/ xht ml l / D TD / xht ml l - st r i c t . dt d
1
>
<ht ml xml ns=
1
ht t p: / / www. w3. or g/ 1999/ xht ml
1
l a ng=' en' xml : l a ng=
1
en
1
>
<hea d>
<t i t l e>Fl exBugs AI R a ppl i c a t i on</ t i t l e>
<met a ht t p- equi v=
1
Cont ent - Type
1
c ont ent =
1
t ext / ht ml ; c ha r set =i so- 8859- l
1
/ >
<sc r i pt t ype=
1
t ext / j a va sc r i pt
1
sr c =
1
j s/ swf obj ec t . j s
1
></ sc r i pt > <—
<sc r i pt t ype=" t ext / j a va sc r i pt " >
I I <• [ CDATA [ . . ^ bj ec t I
j avascr i pt i ncl ude V
va r f l a shva r s = {}; <
f l a shva r s. a i r ver si on = ' 1. 5' ;
f l a shva r s. a ppna me = ' Fl ex Bugs' ; Fl ashvars ©
f l a shva r s. a ppur l =
' ${pa geCont ext . r equest . sc heme}: / / ${pa geCont ext . r equest . ser ver Na me}:
${pa geCont ext . r equest . ser ver Por t }${pa geCont ext . r equest . c ont ext Pa t h}/
f l exbugs. a i r ' ;
f l a shva r s. i ma geur l ' i ma ges/ ba dge- i c on. png'
swf obj ec t . embedSWF( ' ba dge. swf ' ,
' ba dge_di v' ,
' 205' ,
' 170 ' ,
' 9. 0. 0' ,
nul l ,
f l a shva r s) ;
/ / ] ] >
</ sc r i pt >
</ hea d>
<body>
<di v i d=' ba dge_di v' >
To i nst a l l t hi s a ppl i c a t i on you wi l l need t he
Cal l
embedSWF
J>
Pl acehol der di v
www.it-ebooks.info
1 9 0 CHAPTER 9 Desktop 2.0 with AIR
<a hr ef =
1
ht t p: / / www. a dobe. c om/ pr oduc t s/ f l a shpl a yer /
1
>
Adobe Fl a sh Pl a yer
</ a>
</ di v>
</ body>
</ ht ml >
The downl oad page cal l ed swf obj ec t is usi ng a J avaScript l i brary that makes embed-
di ng Flash obj ects i n our web page easier Q . The web page can be found at Googl e
Code (http:/ / c0de. g00gl e. c0m/ p/ swf0bj ect/ ) i f you'r e i nterested i n l ear ni ng mor e
about it. Next you defi ne a vari abl e cal l ed f l ashvar s to hol d the necessary confi gura-
tion i tems ©. Then you use a little J STL expressi on l anguage to hel p bui l d a ful l y qual-
i fi ed l i nk for di e AI R appl i cati on addi ng tiiat to the f l as hvar s . The badge i nstal l er
seems to r equi r e a ful l y qual i fi ed l i nk to di e AI R installer, so we are for ced to use this.
The beauty of usi ng di e J STL i nstead of hard codi ng di e URL, is that no matter wher e
you depl oy tiiis appl i cati on, that l i nk wi l l always work; you don't have to update it for
each envi r onment you depl oy to.
Next you tel l di e badge i nstal l er whi ch i con to display i n di e badge so tiiat you can
customi ze the badge wi ti i your own appl i cati on's br andi ng. You tiien create the badge
W O O FlexBugs AIR application
I I ||| + Bhttp:/ / localhost:80SQ/ flexbugs/ down[oad.jsp C | (O,' Gc
FlexBugs Download
Cl i ck on the badge bel ow to install the Fl exBugs appl i cati on
F le xB u fi s
Figure 9.6 The install badge in action
www.it-ebooks.info
Summary 1 9 1
using the swf obj ec t library by calling the embedSWF functi on Q and pass arguments
telling it first which SWF fi l e to create tire badge from. Next you tell tire badge which
di v el ement in tire J SP to replace with tire content of the badge, tire size of the badge
and tire mi ni mum version of Flash that the application supports. I f you were provid-
i ng an installer to tire user to install the AI R framework from, you could specify that
argument here as well. Last you provi de default i nformati on in the div that lets tire
user know that this page requires Flash to use tire installer badge, and a link to down-
load the Flash runtime Q .
Now that you have all of tire pieces in place, open a command prompt and navigate
to tire root of tire proj ect and build tire application by typingmvn c l ea n i nst a l l . When
that is done, change directories into the f l ex- bugs- web proj ect and start up tire J etty
container by running mvn j et t y: r un- wa r . When tire container has finished loading,
open a browser and navigate to http:/ / localhost:8080/ ilexbugs/ downloadjsp and you
should see a screen similar to that shown in fi gure 9.6.
When you click tire install badge it should prompt you to install tire AI R application.
Summary
You now have successfully broken free of the browser and created an application that
power users can use standalone. Even though it took a l ot of configuration, you'l l
notice that you never had to change much of tire application code to get this to work.
There are not many programmi ng languages or frameworks that will allow you to so
easily reuse tire code to create both a web-based client and a desktop client. This is
one of tire attractive features of both tire Flex framework and the Adobe AI R frame-
work. You'l l discover that many of tire Flex applications can be translated into AI R
applications with minimal effort.
The Adobe AI R SDK offers much more functionality than you can accomplish with
the Flex framework alone, so if you're goi ng to create an AI R application, don't limit
yourself to tire Flex components and APIs. The AI R application framework offers you
the ability to store i nformati on in an embedded database so that you could potentially
create an offl i ne capable version of tire application that could sync up the local data-
base with tire master database when tire network becomes available again.
You also have the ability to read and write files to tire filesystem and even defi ne
new fi l e associations so that they automatically open with tire application. A fi ne exam-
pl e of this is the Balsamiq application (http:/ / www.balsamiq.com/ ), which we've been
using throughout the book to create our wireframes for tire sample application. Thi s
application allows you to save and export tire wireframes in various formats, and even
defines a fi l e association such that whenever you try to open a fi l e with the extension
.bmml, it will by default launch tire Balsamiq application.
I n tire next chapter we're goi ng to show you how to test the application to ver-
i fy that it does what you expect it to do. We'l l introduce you to the FlexLTnit4
library and also the mock-as3 library for mocki ng tire dependencies. Now, let's get
on to tire testing.
www.it-ebooks.info
mtirmyour\
Flexmpp ma tio,
Thi s chapt er covers
• U n i t t e s t i n g w i t h F l e x l l n i t
• M o c k t e s t i n g w i t h m o c k -a s 3
• L e v e ra g i n g t h e h a m c re s t -a s 3 m a t c h e rs
• G e n e ra t i n g a t e s t re p o rt
Every good programmi ng book includes a discussion of unit testing. Whether you
fol l ow the practice of test-driven devel opment, which the autiiors advocate, or write
your tests after di e fact, an automated suite of unit tests is a valuable accompani-
ment to your application. A comprehensive suite of unit tests proves to your cus-
tomer that the code you wrote does what it's supposed to do. I t also provides
developers making changes to your code both confi dence that di e changes will not
break anything and up-to-date documentation in the for m of unit tests. Written
documentation can easily get out of sync with di e i mpl emented code; a good suite
of passing unit tests should always be in sync with di e code. You can tiiink of your
unit tests as a for m of executable documentation that developers can use in the
years to come.
192
www.it-ebooks.info
Unit testing and TDD 193
10.1 Uni t t est i ng and TDD
I f you'r e not fami l i ar wi th the practi ce of Test Dri ven Devel opment (TDD), fi gure 10.1
shows the basic workfl ow. I n a nutshel l , you start by wri ti ng a fai l i ng uni t test, then
wri te onl y enough i mpl ementati on code to make it pass. When you get a passing test,
you start the process over agai n.
Wr i ti ng code tiiis way has a coupl e of i nteresti ng side effects. The most obvi ous
one is di at your code is mor e l i kel y to be wri tten i n a testable manner, because you'r e
starting wi th the tests first. A not so obvi ous effect of practi ci ng TDD is that you add
onl y code that is absol utel y necessary, and less specul ati ve codi ng occurs. Ther e are a
great many books about test-driven devel opment available, i ncl udi ng Test Driven:
Practical TDD and Acceptance TDD for J ava Developers, by Lasse Koskel a (http:/ / manni ng.
com/ koskel a/ ).
I t's still easy to pr oduce code tiiat you don't need i n your appl i cati on. Because you
di dn't l et the tests dri ve di e code, you'l l have extraneous code, but it wi l l be wel l
tested extraneous code. One good way to ensure that you have onl y code and features
that are rel evant and r equi r ed i n your appl i cati on is to practi ce a mor e r efi ned tech-
ni que of test-driven devel opment cal l ed Presenter First, di e mai n moti vati on behi nd
the Model Vi ew Presenter pattern we i ntroduced i n chapter 4. The tiiinking behi nd di e
Presenter First appr oach is that your Presenter tests map closely to your user stories,
and i f you wri te onl y tests that map to your user stories, you'l l avoi d much of di e gol d
pl ati ng that we devel oper s are often gui l ty of—sneaki ng i n features tiiat we thi nk
woul d be useful , but don't appear i n any of di e requi rements set for th by di e cus-
tomer. For a mor e thor ough expl anati on of the Presenter First appr oach to devel op-
ment, read di e arti cl e i n Better Software magazi ne at http:/ / www.atomi cobj ect.com/
fi l es/ Bi gCompl exTested_F eb07. pdf
Test fails j m Write code
r
Test passes
Refactor
V*
M
®
Figure 10.1
TDD workflow
www.it-ebooks.info
1 9 4 CHAPTER 1 0 Testing your Flex application
I n this chapter we use the uni t testi ng fr amewor k Fl exUni t, and mor e speci fi cal l y tire
latest i ncarnati on of the Fl exUni t4, whi ch bri ngs the fr amewor k mor e i n l i ne wi th cur-
rent uni t testi ng frameworks avai l abl e for J ava such as J Unit4. Features i ntr oduced
wi th this newest versi on of Fl exUni t i ncl ude:
• No need to i nheri t f r om the TestCase base class
• The addi ti on of annotati ons for addi ng metadata to your test cases
• Easier asynchronous testi ng
• I ntr oducti on of Hamcr est matchers
For a compr ehensi ve listing of all the new features i n Fl exUni t4, check out the docu-
mentati on at http: / / docs.fl exuni t.org/ i ndex.php?ti ti e=Fl exUni t4FeatureOvervi ew. We
won't get i nto a l engthy discussion on F l exUni t and how to use tire F l exUni t frame-
work; instead, we'l l discuss the features as we i ntr oduce them i n our exampl es.
One of tire mai n purposes of uni t testi ng is to try to narrow your scope of testi ng as
much as possi bl e, whi ch is why it's cal l ed uni t testing. To do that you can use a mock
testi ng fr amewor k to r emove any external dependenci es i n the class you'r e testing. By
i nj ecti ng these mocks i nto your class dur i ng uni t testing, you'r e abl e to test how your
class interacts wi th its external dependenci es wi thout rel yi ng on tire exi stence of those
external dependenci es. The mock testi ng fr amewor k we'l l be uti l i zi ng i n this chapter
is cal l ed mock-as3. The mock-as3 pr oj ect is hosted via Googl e Code at http:/ / code.
googl e. com/ p / mock-as3 / .
NOTE The mock-as3 fr amewor k is no l onger bei ng mai ntai ned but has been
r epl aced by tire Mockol ate fr amewor k whi ch can be found at http:/ / gi thub.
com/ dr ewbour ne/ mockol ate.
To get started uni t testi ng i n our Fl ex appl i cati on, we'l l need to make some changes to
tire proj ect. Let's get started.
10.2 Updat i ng t he proj ect
Befor e we can start wri ti ng our first uni t test, we'l l need to update tire pom. xml for
our f l ex- bugs- l i b pr oj ect to add the necessary uni t testi ng l i brari es as dependenci es
and also tire uni t testi ng support for tire F l exMoj os pl ugi n that we'r e usi ng for our
builds. The fol l owi ng l i sti ng shows tire updates that we need to add to our pom. xml .
Li s t i n g 1 0 . 1 Up d a t e d p o m . xm l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<pr oj ec t xsi : sc hema Loc a t i on=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0
ht t p: / / ma ven. a pa c he. or g/ xsd/ ma ven- 4. 0. 0. xsd"
xml ns=" ht t p: / / ma ven. a pa c he. or g/ POM/ 4. 0. 0"
xml ns: xsi =" ht t p: / / www. w3. or g/ 2001/ XMLSc hema - i nst a nc e" >
<bui l d>
<sour c eD i r ec t or y>sr c / ma i n/ f l ex</ sour c eD i r ec t or y>
<t est Sour c eD i r ec t or y>sr c / t est / f l ex</ t est Sour c eD i r ec t or y>
Test source
di r ect or y
www.it-ebooks.info
Updating the project 195
</ bui l d>
<dependenc i es>
<dependenc y>
<gr oupI d>or g. sona t ype. f l exmoj os</ gr oupI d>
<a r t i f a c t l d>f l exmoj os- uni t t est - suppor t </ a r t i f a c t l d>
<ver si on>${f l exmoj os. ver si on}</ ver si on>
<t ype>swc </ t ype>
<sc ope>t est </ sc ope>
</ dependenc y>
<dependenc y> <
<gr oupI d>c om. a dobe. f l exuni t </ gr oupI d>
<a r t i f a c t l d>f l exuni t </ a r t i f a c t l d>
<ver si on>4. 0- bet a - 2</ ver si on>
<t ype>swc </ t ype>
<sc ope>t est </ sc ope>
</ dependenc y> <
<dependenc y> <
<gr oupI d>or g. ha mc r est </ gr oupI d>
<a r t i f a c t l d>ha mc r est - a s3</ a r t i f a c t l d>
<ver si on>l . 0</ ver si on>
<t ype>swc </ t ype>
<sc ope>t est </ sc ope>
</ dependenc y> <
<dependenc y> <
<gr oupI d>moc k- a s3</ gr oupI d>
<a r t i f a c t I d>moc k- a s3</ a r t i f a c t l d>
<ver si on>l . 0. 0</ ver si on>
<t ype>swc </ t ype>
<sc ope>t est </ sc ope>
</ dependenc y> <
n Fl exMoj os
t est i ng suppor t
A Fl exUni t
dependency
A Hamcrest
mat cher
dependency
A Mock-as3
dependency
</ dependenc i es>
<r epor t i ng>
<pl ugi ns>
<pl ugi n> <1—I
<gr oupI d>or g. a pa c he. ma ven. pl ugi ns</ gr oupI d>
<a r t i f a c t l d>ma ven- sur ef i r e- r epor t - pl ugi n</ a r t i f a c t l d>
</ pl ugi n> <1—I
</ pl ugi ns>
</ r epor t i ng>
<pr oper t i es>
<f l exmoj os. ver si on>3. 4. 2</ f l exmoj os. ver si on>
</ pr oper t i es>
</ pr oj ec t >
0 Test r epor t
pl ugi n
The first secti on of tl i e pom. xml that needs to be modi fi ed is di e secti on that tells
Maven wher e your test sources are. You over r i de di e defaul t l ocati on of s r c / t es t / j ava
www.it-ebooks.info
1 9 6 CHAPTER 1 0 Testing your Flex application
wi th the l ocati on of s r c / t es t / f l ex O to mor e cl osel y fol l ow the conventi on you'r e fol -
l owi ng for your source code. Next you add a dependency on the F l exMoj os uni t testi ng
support l i brary Q . Then you add dependenci es on di e Fl exUni t4 di e Hamcrest
matcher l i brary and di e mock-as3 l i brary Q . You may also noti ce that you've
defi ned di e scope of these dependenci es as havi ng test scope. That way they wi l l not be
i ncl uded i n di e arti fact that ul ti matel y is depl oyed to your appl i cati on server when you
depl oy your appl i cati on. The last thi ng you added to di e pom. xml is the r epor ti ng
pl ugi n whi ch gi ves you the ability to gener ate test reports for your uni t tests.
The dependenci es for di e uni t testi ng support and Fl exUni t4 exist on the
Sonatype Maven reposi tory; however di e Hamcrest and mock-as3 dependenci es do
not. You can ei ti i er downl oad tiiose l i brari es and install them manual l y usi ng the mvn
i nst a l l : i nst a l l - f i l e pl ugi n or use di e Maven reposi tory we have set up for the
sampl e code i n our book usi ng the Googl e Code reposi tory.
Now that you've got the pr oj ect set up and ready for testing, you'l l start l ooki ng at
how to uni t test your Fl ex appl i cati on. To illustrate this you'r e goi ng to test di e
Ma st er Pr esent er , Ma st er Vi ew, and I ssueModel . These classes are si mpl e enough for
us to keep our exampl es short and to di e poi nt, yet tiiey contai n enough functi onal i ty
to pr oper l y illustrate most of the situations you'l l need to test. To start you'l l begi n
wi th testi ng the Ma st er Pr esent er .
10.3 Test i ng t he Present er
We've chosen to start our uni t testi ng exampl es wi th testi ng the Presenter, because, as
we stated earlier, di e Presenter typically maps closest to your user stories, and di e Pre-
senter wi l l often be di e most compl ex part of di e MVP triad because it has mor e
responsi bi l i ty than di e oti i er two parts. First you create the uni t test class for your
Ma st er Pr esent er . Create the package structure for di e or g. f oj . pr esent er package
under di e sr c / t est / f l ex fol der i nsi de di e f l ex- bugs- l i b proj ect. Next create the
Ma st er Pr esent er Test . a s class i nsi de this or g. f oj . pr esent er package. The first part
of the code for di e Ma st er Pr esent er Test class is shown i n listing 10.2.
Li s t i n g 1 0 . 2 M a s t e r Pr e s e n t e r Te s t . a s
pa c ka ge or g. f oj . pr esent er {
publ i c c l a ss Ma st er Pr esent er Test {
publ i c va r t a r get : Ma st er Pr esent er ;
publ i c va r moc ker y: Moc ker y;
publ i c va r vi ew: Ma st er Vi ew;
publ i c va r model : I ssueModel ;
publ i c va r moc kResponder : I Responder ;
publ i c va r di spa t c her : Event D i spa t c her ;
[ Bef or e( a sync , t i meout =5000) ]
publ i c f unc t i on set Up( ) : voi d {
^ ^ Test i ng
t ar get
Mocks and
mock cont r ol
>
^ ^ p Event Di spat cher
set Up met hod
www.it-ebooks.info
Testing the Presenter 197
moc ker y = new Moc ker y( ) ;
moc ker y. pr epa r e( Ma st er Vi ew) ;
moc ker y. pr epa r e( I ssueModel ) ;
di spa t c her = Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) ;
Async . pr oc eedOnEvent ( t hi s, moc ker y, Event . COMPLETE, 5000) ;
For those fami l i ar wi th J ava and J Uni t tiris shoul d l ook fami l i ar. You name your test
class wi dr the conventi on of <Cl assName>Test because tiris is tire defaul t pattern that
Maven wi l l use to l ook for test classes when r unni ng your tests duri ng tire bui l d pro-
cess. You start wi th defi ni ng a few pri vate member vari abl es for tire class you'r e tryi ng
to test O , tire mock contr ol and the mock obj ects you'l l need to i nteract wi th and
your good fr i end tire event di spatcher ©. Because most of your classes wi l l use tire
event di spatcher f r om the E ventDi spatcher F actor y, you'l l also need to use tiris i n
your tests to ensure that your events are pr oper l y di spatched and handl ed.
Next you create a setup method that wi l l be run at tire begi nni ng of each test i n
your class Q . You named your method setup mer el y out of habi t—you coul d name it
whatever you l i ke. I n the previ ous versi on of F l exUni t you had to over r i de tire setup
method f r om the base class; now tire fr amewor k uses tire [B ef or e] annotati on to
know whi ch method to use for its setup. You also add mor e metadata to tire annota-
ti on to tel l F l exUni t that tiris test wi l l use some asynchronous functi onal i ty and that it
shoul d ti me out after 5 seconds, meani ng the test wi l l fai l i f it runs l onger. Thi s illus-
trates one of tire potenti al pi tfal l s of testi ng wi th Fl exUni t. I f your uni t tests are run-
ni ng l ong, you may end up wi th false posi ti ve fai l ures and you'l l fi nd that peri odi cal l y
you'l l have tests that wi l l ti me out and fai l for no reason.
I nsi de tire setup method you set up a mock contr ol by i nstanti ati ng a new Mockery
class. Then you tel l tire mock contr ol to pr epar e tire mocks by cal l i ng pr epar e () for
each class that you'l l be mocki ng. The last step is to tel l the test to wai t unti l tire mock
contr ol has fi ni shed pr epar i ng by cal l i ng tire proceedOnEvent method and setti ng tire
event you want to pr oceed on to the compl ete event f r om your mockContr ol .
Then you defi ne the counterpart to your setup method, tire teardown method Q .
As you di d for tire setup, you fol l ow tire conventi on of cal l i ng tiris method tearDown
out of habi t. The [Af t er ] annotati on tells the fr amewor k to run this after every test
method run. The onl y tiring that you do i nsi de your teardown method is to call ver -
i f y on your mocks to ensure that everythi ng you expected tire mocks to call was
i ndeed cal l ed.
[ Af t er ]
publ i c f unc t i on t ea r D own( ) : voi d {
moc ker y. ver i f y( model , vi ew) ;
1 >
t ear Down met hod
www.it-ebooks.info
1 9 8 CHAPTER 1 0 Testing your Flex application
10.3.1 Test i ng ref resh i ssues
Now that you've got the skel eton for your Mast er Pr esent er Test wri tten, l et's start
wi th your fi rst test. The fi rst pi ece of functi onal i ty you'r e goi ng to test woul d probabl y
come f r om a user story, the fi rst part of whi ch woul d read somethi ng l i ke tiiis:
In order to ensure that the issues I'm viewing are up to date, when I click the Refr esh
button, the appl i cati on shoul d retri eve di e issues f r om di e server and refresh the
data grid with the results.
The i mpor tant part of tiiis story is the when. The acti on i denti fi ed i n di e when state-
ment wi l l need to be tested by your Presenter tests. The when tiiat you wi l l be testi ng is
the part of the story that states when I click the Refresh button, the application should retrieve
the issues from the server.
Li st i ng 1 0 .3 shouldCallGetlssuesFromModel
[ Test ] <i —O Test annot at i on
publ i c f unc t i on shoul dCa l l Get l ssuesFr omModel ( ) : voi d {
model = moc ker y, st r i c t ( I ssueModel ) a s I ssueModel ; I M Creat e
f
vi ew = moc ker y. st r i c t ( Ma st er Vi ew) a s Ma st er Vi ew; \ mocks
moc ker y. moc k( model ) . met hod( " get l ssues" ) . wi t hAr gs( I Responder ) . onc e; <1—i
t a r get = new Ma st er Pr esent er ( vi ew, model ) ; <]—, Mock expect at i on ©
1
va r event : UI Event = new UI Event (
ui Event . REFRESH_I SSUES_BUTTON_CLI CKED I ® Creat e t ar get
© Creat e and di spat ch event
di spa t c her . di spa t c hEvent ( event ) ; ^
r
}
You start by annotati ng your test method wi ti i the [Test ] annotati on ©. Fl exUni t4
utilizes this [Test ] annotati on to know whi ch methods are your test meti i ods. Next
you create your mocks by cal l i ng di e st r i c t method on your mock contr ol © passing
i n the class tiiat you want to mock. You use strict mocks her e so that i f any meti i ods are
cal l ed on your mocks tiiat you don't expl i ci dy set up, your mock contr ol wi l l fai l the
test i n the teardown when you call ver i f y. You tiien set up the expectati on on your
mock ©. The expectati on syntax for mock-as3 is fai rl y sel f-expl anatory, and most of
di e time wi l l l ook si mi l ar to this.
Let's stop to anal yze this l i ne of code. The fi rst met hod you'r e goi ng to mock is
on di e model , whi ch is di e mock for di e I ssueModel class. You'r e expecti ng your code
to call the get l ssues meti i od, and you'r e goi ng to pass i n an ar gument of type
I Responder and expect it onl y once. You coul d as easily put a concr ete val ue or obj ect
i n tiiis expectati on, and di e mock fr amewor k woul d test di e equal i ty of what di e
meti i od is cal l ed wi th. I n tiiis instance you can't easily try to per for m an exact match on
the I Responder ; you'r e mor e i nterested i n wheti i er or not the method is cal l ed.
Next you create your target by cal l i ng di e constructor and passing i n di e mocks
tiiat you created ©. Last you si mul ate di e behavi or tiiat your vi ew wi l l exude. You cre-
ate a new event of type REFRESH_ I SSUES_ BUTTON_ CLI CKED and di spatch it 0 .
www.it-ebooks.info
Testing the Presenter 1 9 9
For your code to compi l e, you need to change tire constructor for your Ma st er -
Pr esent er class to al l ow i nj ecti on of both tire Vi ew and the Model .
Li s t i n g 1 0 . 4 Up d a t e d Mast erPresent er
publ i c f unc t i on Ma st er Pr esent er !
vi ew: Ma st er Vi ew = nul l ,
model : I ssueModel = nul l ) {
i f ( model != nul l ) {
t hi s. _i ssueModel = model ;
} el se {
t hi s. _i ssueModel = new I ssueModel ( ) ;
}
t hi s. _vi ew = vi ew;
}
You first have to add i n tire ability to pass i n an I ssueModel to tire Ma st er Pr esent er as
wel l as the Ma st er Vi ew Q . You also are defaul ti ng it to nul l , whi ch means that you
don't need to change any of tire code that you wr ote earl i er that doesn't pass i n this
extra parameter. That's one of tire ni ce thi ngs about bei ng abl e to speci fy defaul t
parameters. Next you add a bl ock of code to set the i ssueModel to ei ther tire val ue
passed i nto tire constructor, or instantiate a new one i f nothi ng was passed i n ©. Last
you set tire vi ew that was passed i n
Now you can run the uni t test and it shoul d pass. Open a command l i ne and navi-
gate to tire fl ex-bugs-l i b fol der and type mvn t est . After all of tire messages scroll by,
you shoul d see tire results f r om tire tests bei ng run.
10.3.2 Issues resul t event t est
Now you can test the second hal f of the user story f r om the previ ous secti on. To
fi nd tire next when i n that user story, you coul d rewri te tire story to r ead mor e
l i ke this:
In order to ensure that the issues I'm viewing are up-to-date, when I click the Refresh
button, the applica tion should retrieve the issues from the server and when the result comes
back from the server, refresh the data grid with the results.
I n an i deal wor l d you woul d be abl e to capture the r esponder obj ect passed i nto your
mock i n tire test you wrote; unfortunatel y, as of this wri ti ng, tire mocki ng fr amewor k
that we'r e usi ng doesn't support that. To over come this you need to scope the meth-
ods tlrat your resul t events call to the publ i c scope so that you can call it directly. List-
i ng 10.5 shows tire test for tire result f r om tire call to the get l ssues method on tire
I ssueModel .
I A Const r uct or
If paramet ers
Set t i ng model
^ ^ P Set t i ng vi ew
www.it-ebooks.info
200 CHAPTER 1 0 Testing your Flex application
Li st i ng 1 0 .5 shouldSetlssuesPropertyOnView
[ Test ]
publ i c f unc t i on shoul dSet l ssuesPr oper t yOnVi ew ( ) : voi d {
model = moc ker y. st r i c t ( I ssueModel ) a s I ssueModel ;
vi ew = moc ker y. st r i c t ( Ma st er Vi ew) a s Ma st er Vi ew;
< i —O Test annot at i on
f
Creat e
mocks
va r i ssues : I Col l ec t i onVi ew = new Ar r a yCol l ec t i on ( ) ; < —© Mock resul t dat a
moc ker y. moc k( vi ew) . pr oper t y( " i ssues" ) . wi t hAr gs( I Col l ec t i onVi ew) . onc e;
t a r get = new Ma st er Pr esent er ( vi ew, model ) ;
6
Mock pr oper t y
access
Creat e
va r r esul t Event : Resul t Event =
w
t ar get
new Resul t Event ( Resul t Event . RESULT, f a l se, t r ue, i ssues) ;
t a r get . get l ssuesResul t ( r esul t Event ) ;
} Si mul at e r esul t event
n
n
You start as you di d i n the last test by annotati ng di e meti i od wi ti i the [ Test ] annota-
tion Q . Next create your mocks by cal l i ng st r i c t on the mock control create an
Ar r a yCol l ec t i on that wi l l be i ncl uded i n the r esul t Event Not onl y can you mock
method calls on your mocks, but you can also mock pr oper ty access. You mock out
access to di e set pr oper ty i ssues Q . I n tiiis case we'r e saying that the i ssues pr oper ty
wi l l be set wi ti i some i nstance of I Col l ec t i onVi ew. Wi th all of the expectati ons set,
you can now instantiate your Presenter © wi th your mocks. Last you create a Resul t -
Event Q to si mul ate the model cal l i ng di e event handl er and call di e get l ssues-
Resul t passing i n the Resul t Event .
10.3.3 Test i ng i ssue removed
The next tiling you want to test is what happens when an issue is del eted. Thi s feature
may be descri bed someti i i ng like the fol l owi ng:
In order to remove issues that may be invalid or incorrect, when the user clicks the remove
issue, the application should delete the selected issue.
Agai n, the i mpor tant part of the user story is what's descri bed i n di e when part of the
descri pti on. I n this case you want to si mul ate some other part of di e appl i cati on dis-
patchi ng an event i ndi cati ng that the Del ete Issue button has been cl i cked.
Li st i ng 1 0 .6 shouldCallRemovelssueOiiModel
[ Test ]
publ i c f unc t i on shoul dCa l l Removel ssueOnModel ( ) : voi d {
va r sel ec t edl ssue: I ssue = new I s s ued;
sel ec t edl ssue. i d = 123;
model = moc ker y. st r i c t ( I ssueModel ) a s I ssueModel ;
vi ew = moc ker y. st r i c t ( Ma st er Vi ew) a s Ma st er Vi ew;
moc ker y. moc k( model ) . met hod( " r emovel ssue" )
. wi t hAr gs( sel ec t edl ssue. i d, I Responder ) . onc e;
t a r get = new Ma st er Pr esent er ( vi ew, model ) ;
1>
Test annot at i on
Mock
obj ect s
1 >
Mock expect at i on
< —© Inst ant i at e t ar get
www.it-ebooks.info
Testing the Presenter 201
va r event : UI Event = new UI Event ( UI Event . REMOVE_I SSUE_BUTTON_CLI CKED ) ;
event . da t a = sel ec t edl ssue;
di spa t c her . di spa t c hEvent ( event ) ; Creat e and di spat ch event
n
Thi s test fol l ows the same pattern as the fi rst one you wrote. You start by annotati ng
your test wi th the [ Test ] annotati on O - Next you create an i ssue l ocal vari abl e that
you'l l uti l i ze i n your mock expectati on. Then you create your mocks by cal l i ng the
st r i c t method on the mock contr ol After you've created your mocks you can
defi ne your expectati on of the r emovel ssue method on di e model bei ng cal l ed
Thi s expectati on wi l l take a val ue i n tryi ng to match the val ue of the i d pr oper ty on
the issue you created i n di e test, as wel l as an ar gument of type I Responder . Next you
instantiate your test target Q . I n this test you'r e passing al ong data wi ti i the event that
you need to di spatch Q , so you instantiate a new event and set its da t a pr oper ty to di e
i ssue you created i n your test and di spatch it.
10.3.4 Remove i ssue resul t t est
Now di at you have the fi rst part of di e Remove Issue functi onal i ty compl ete, you need
to test what happens when you recei ve the Resul t Event f r om the I ssueModel . Thi s
test wi l l be si mi l ar to the way you tested di e resul t for the Refr esh Issues button bei ng
pressed earlier.
Li st i ng 1 0 .7 shouldResetGridAndFireSelectedlssueChangedEvent
[ Test ( a sync , t i meout =8000) ] <s —0 Test annot at i on
publ i c f unc t i on shoul dReset Gr i dAndFi r eSel ec t edl ssueCha ngedEvent ( ) : voi d {
model = moc ker y. st r i c t ( I ssueModel ) a s I ssueModel ;
vi ew = moc ker y. st r i c t ( Ma st er Vi ew) a s Ma st er Vi ew;
h e
Creat e
mocks
moc ker y. moc k( vi ew) . met hod( " r eset l ssuesGr i d" ) .
wi t hNoAr gs. onc e;
moc ker y. moc k( model ) . met hod( " get l ssues" ) .
wi t hAr gs( I Responder ) . onc e;
Async . pr oc eedOnEvent ( t hi s,
di spa t c her ,
UI Event . SELECTED _I SSUE_CHANGED ,
t a r get = new Ma st er Pr esent er ( vi ew, model ) ;
A Mock
' expect at i ons
8000);
J
J
Expect ed
event
Inst ant i at e
t ar get
I
va r r esul t Event : Resul t Event = new Resul t Event ( Resul t Event . RESULT) ;
t a r get . r emovel ssueResul t ( r esul t Event ) ;
Cal l t he t ar get
The first tiling you may noti ce is that di e [ Test ] annotati on Q l ooks mor e l i ke the
setup method you defi ned i n l i sti ng 10.2, wi th the extra metadata stating that tiiis
method wi l l use di e Async . pr oc eedOnEvent meti i od and tiiat it shoul d ti me out
after 8 seconds. Next you create your mocks as befor e, by cal l i ng di e st r i c t meti i od
on the mock control s Q , al ong wi th setti ng the mock expectati ons that you'l l call
the r eset l ssuesGr i d meti i od on the vi ew (you wi l l need to defi ne tiiis method to
www.it-ebooks.info
202 CHAPTER 1 0 Testing your Flex application
get the test to compi l e), and that you'l l call the get l s s u es meti i od on di e model
to refresh di e data gr i d
The call to get l s s u es wi l l occur as a result of di e SELECTED_ISSUE_CHANGED event
di at you'r e expecti ng to be di spatched i n the event handl er, and you defi ne that
expectati on next Q . Thi s call to tire proceedOnEvent method allows you to defi ne an
expectati on on the test method that wi l l fai l unless the Presenter dispatches the event
you pass i n as an ar gument to the proceedOnEvent method. You'l l noti ce that we'r e
usi ng tire di spatcher f r om the E ventDi spatcher F actor y i n this expectati on as wel l .
Thi s is because your appl i cati on wi l l use this to di spatch its events, and i n or der for
your test to wor k as expected, it wi l l need to uti l i ze tire same event di spatcher that the
appl i cati on wi l l use.
The next step is to instantiate your Presenter passing i n tire mocks you created at
tire begi nni ng of this uni t test Q ; after that, you create a Resul tE vent Q to call the
method that you'r e testi ng and i nvoke it.
Now all that's l eft to do is to run tire tests agai n. Open a command l i ne and navi-
gate to tire f l ex- bu gs - l i b pr oj ect and run tire mvn t es t command. When the smoke
clears, you shoul d be pr esented wi th a message tel l i ng you that you now have four
passing tests. You have mer el y scratched the surface wi th uni t testi ng the Presenters i n
this appl i cati on; tire exampl es we presented shoul d be enough fi r epower for you to
conti nue to wri te all tire tests necessary for tire Presenters. We'r e now goi ng to move
al ong to testi ng your Vi ew components.
10.4 Test i ng t he Vi ew
Now that we've shown how to test your Presenters, it's time to move on and uni t test
your Vi ew components. When we say uni t test your View components, we'r e not tal ki ng
about i n browser functi onal testing. For that l evel of testi ng you'l l want to l ook at
ei ther tire FunFX (http:/ / funfx. r ubyfor ge. or g/ ) testi ng fr amewor k or the Sel eni um-
Fl ex-API (http:/ / c0de. g00gl e. c0m/ p/ sfapi / ). I nstead we'r e tal ki ng about testi ng tire
publ i c API exposed by your Vi ew components to tire rest of tire appl i cati on. Agai n,
you'l l start by creati ng the test class.
Li st i ng 1 0 .8 MasterViewTest
pa c ka ge or g. f oj . vi ew {
publ i c c l a ss Ma st er Vi ewTest {
pr i va t e va r t a r get : Ma st er vi ew;
pr i va t e va r event D i spa t c her : Event D i spa t c her ;
J
Test t ar get
Event
di spat cher
[ Bef or e ( a sync , ui ) ] met hod
J
set Up
publ i c f unc t i on set Up( ) : voi d {
t a r get = new Ma st er Vi ew() ; Q I ni ti al i ze
t a r get , i ni t i a l i ze () ; <—1 t ar get
event D i spa t c her = Event D i spa t c her Fa c t or y. get Event D i spa t c her ( ) ;
www.it-ebooks.info
Testing the View 203
}
}
}
You start this test by defi ni ng a coupl e of pri vate fi el ds for your test target Q and your
event di spatcher Q . Then you defi ne a set up meti i od Q to be cal l ed befor e each test
that runs. I nsi de of di e setup meti i od you instantiate a new Ma st er Vi ew and i ni ti al i ze
it by cal l i ng the i ni t i a l i ze meti i od Q . You do this because MX ML components have
a l i fecycl e of tiieir own, and when your appl i cati on starts and components are added
to your appl i cati on, Fl ex wi l l call these l i fecycl e methods and gener ate events. I n
or der for your component to pr oper l y i ni ti al i ze itself and all of the chi l d components,
you need to manual l y call di e i ni t i a l i ze method.
One tiling you may noti ce is that di e test for your Vi ew component doesn't
i ncl ude any mocks. Because tiiis Vi ew component doesn't have any external depen-
denci es, this test wi l l be mor e of a stateful test as you assert that the state of di e
components contai ned wi ti i i n your vi ew change as you expect them to when cal l i ng
the publ i c meti i ods.
10.4.1 Test i ng t he i ssues set propert y
The fi rst thi ng you'l l be testi ng i n the Ma st er Vi ew is the set pr oper ty for the issues
data gri d. By defaul t any chi l d components added to your MX ML component have
publ i c access appl i ed to them, so you coul d easily onl y al l ow your Presenter to access
the chi l d components di recdy because it has a r efer ence to the Vi ew. The not- so- good
news is not onl y is tiiis not easily testable, it vi ol ates the Law of Demeter (http:/ /
c2. com/ cgi / wi ki ?LawOfDemeter ) by al l owi ng your Presenter to call meti i ods and
pr oper ti es on the chi l d components of your Vi ew.
Li st i ng 1 0 .9 issuesPropertySetsDataProviderOnDataGrid
[ Test ]
publ i c f unc t i on i ssuesPr oper t ySet sD a t a Pr ovi der OnD a t a Gr i d( ) :
va r da t a Pr ovi der : Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on( ) ;
va r i ssuel : I ssue = new I s s ued;
i ssuel . i d = 1;
da t a Pr ovi der . a ddl t em( i ssuel ) ;
va r i ssue2: I ssue = new I s s ued;
i ssue2. i d = 5;
da t a Pr ovi der . a ddl t em( i ssue2) ;
t a r get . i ssues = da t a Pr ovi der ;
a sser t Tha t ( t a r get . ma st er Vi ewD a t a Gr i d. da t a Pr ovi der , <1—
equa l To( da t a Pr ovi der ) ) ; |
}
The code for your first vi ew test is shown i n listing 10.9. Start your test by creati ng an
Ar r a yCol l ec t i on wi th a coupl e of I ssue obj ects to call the issues set pr oper ty wi th Q .
>i d {
O Dummy dat a
Cal l i ssues
© set pr oper t y
Assert t he st at e
www.it-ebooks.info
204 CHAPTER 1 0 Testing your Flex application
Then you call the issue set pr oper ty and set it to the Ar r a yCol l ec t i on you created ©.
Next you assert drat tire da t a Pr ovi der pr oper ty of tire ma st er Vi ewD a t a Gr i d is equal
to dre Ar r a yCol l ec t i on you passed i n ©. Thi s last l i ne shows the Hamcrest matcher
syntax, and how readabl e it makes your assertions. You can cl earl y gather f r om that
l i ne of code what it you expect to happen.
10.4.2 Test i ng reset l ssueGri d f unct i on
Ther e is one other publ i c method that you want to test for tire MasterVi ew, the
r es et l s s u es Gr i d method. Thi s method wi l l make sure that there is no sel ected i tem
on tire data gr i d by resetti ng its sel ected i ndex pr oper ty to -1.
Li s t i n g 1 0 . 1 0 resetlssuesGridRemovesAllDataFromDataGrid
[ Test ]
publ i c f unc t i on r eset l ssuesGr i dRemovesAHD a t a Fr omD a t a Gr i d( ) : voi d {
va r da t a Pr ovi der : Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on! ) ; <3
va r i ssuel : I ssue = new I s s ued;
i ssuel . i d = 1;
da t a Pr ovi der . a ddl t em( i ssuel ) ;
va r i ssue2: I ssue = new I s s ued;
i ssue2. i d = 5;
da t a Pr ovi der . a ddl t em( i ssue2) ; ^
0 Dummy
dat a
t a r get . i ssues = da t a Pr ovi der ;
t a r get . ma st er Vi ewD a t a Gr i d. sel ec t edl ndex = 1;
< i —© Set i ssues
< —© Select i ssue
t a r get . r eset l ssuesGr i d () ; <1—© Cal l r eset l ssuesGr i d
a sser t Tha t ( t a r get . ma st er Vi ewD a t a Gr i d. sel ec t edl ndex, equa l To( - l ) ) ;
Asser t gr i d reset
You start this test by creati ng an Ar r a yCol l ec t i on to simulate your data gr i d hav-
i ng data ©, then set tire i ssues pr oper ty of your vi ew to the sampl e data you
created ©. Next you sel ect an i tem on the gr i d by setti ng tire sel ec t edl ndex
pr oper ty of tire datagri d to 2 ©. Then you call tire method you'r e testi ng © and
assert that the sel ec t edl ndex of tire D a t a Gr i d is set back to -1 ©. Al though we
di scourage r eachi ng i nto tire insides of the Vi ew's chi l d components to di rectl y
modi fy properti es i n your pr oducti on code, you don't have a choi ce when it comes
to testi ng tire Vi ew.
10.4.3 Test i ng ref resh i ssues but t on cl i ck
Now that you have tire publ i c API tested, you still need to test that certai n events are
fi r ed when thi ngs such as button clicks occur. The first of these tests, testi ng for tire
Refr esh Issues button click, is shown i n listing 10.11.
www.it-ebooks.info
Testing the View 205
Li s t i n g 1 0 . 1 1 ref reshButtonClickTriggersUIEvent
J [ Test ( a sync ) ]
publ i c f unc t i on r ef r eshBut t onCl i c kTr i gger sUI Event ( ) : voi d {
Async . pr oc eedOnEvent ( t hi s,
event D i spa t c her ,
UI Event . REFRE SH_I S SUE S_BUTTON_C LI CKED , 5000)
Test
annot at i on
pr oceedOnEvent
t a r get . r ef r eshl ssuesBut t on. di spa t c hEvent (
new MouseEvent ( MouseEvent . CLI CK) ) ;
1>
Si mul at e
mouse cl i ck
Thi s is a fai rl y si mpl e test because you don't have to do any ki nd of setup to run it. You
start by annotati ng the test wi th di e [ Test ] annotati on and add di e extra bi t of meta-
data to tel l F l exUni t that this test wi l l uti l i ze the asynchronous features Q . Next you
set the expectati on for the REFRESH_ I SSUES_ BUTTON_ CLI CKED event Q . Last you simu-
late your button click by havi ng the r ef r eshl ssuesBut t on di spatch a MouseEvent of
type CLI CK ©. That's all tiiere is to it. Next we'r e goi ng to test somethi ng mor e com-
pl ex, the i tem click on di e D a t a Gr i d.
10.4.4 Test i ng Dat aGri d i t em sel ect
The last test we'r e goi ng to wri te for the Vi ew befor e we move on to wri ti ng tests for
the model is for when a user clicks an i tem i n di e D a t a Gr i d. Thi s test wi l l r equi r e a bi t
mor e setup tiian the last test you wrote, as you need to have data i n your D a t a Gr i d for
the event handl er to work.
Li s t i n g 1 0 . 1 2 selectingDataGridltemTriggersUIEvent
< i —O Test annot at i on
J
Expect ed
event
[ Test ( a sync ) ]
publ i c f unc t i on sel ec t i ngD a t a Gr i dl t emTr i gger sUI Event ( ) : voi d {
Async . pr oc eedOnEvent ( t hi s,
event D i spa t c her ,
UI Event . SELECTED _I SSUE_CHANGED , 5000) ;
va r da t a Pr ovi der : Ar r a yCol l ec t i on = new Ar r a yCol l ec t i on( ) ;
va r i ssuel : I ssue = new I s s ued;
i ssuel . i d = 1;
da t a Pr ovi der . a ddl t em( i ssuel ) ;
va r i ssue2: I ssue = new I s s ued;
i ssue2. i d = 5;
da t a Pr ovi der . a ddl t em( i ssue2) ;
t a r get . i ssues = da t a Pr ovi der ;
t a r get . ma st er Vi ewD a t a Gr i d. di spa t c hEvent (
new Li st Event ( Li st Event . I TEM_CLI CK, f a l se, f a l se, 1, 2) ) ;
Si mul at e It emCl i ck
A Sample
dat a f or
Dat aGr i d
i c k ^b
www.it-ebooks.info
206 CHAPTER 1 0 Testing your Flex application
Agai n you start by annotati ng your test wi th tire [ Test ] annotati on and addi ng tire
a sync par ameter Q - Next set your expectati on that the SELECTED _ I SSUE_ CHANGED
event wi l l be di spatched Q . Now you need to create an Ar r a yCol l ec t i on and popu-
late it wi th a coupl e of I ssue obj ects, al l owi ng you to set the da t a Pr ovi der pr oper ty
on tire D a t a Gr i d © so that tire D a t a Gr i d wi l l contai n tire i tem that you say you'r e
goi ng to click. Last you si mul ate the user cl i cki ng an i tem i n tire D a t a Gr i d by havi ng it
di spatch a Li st Event of type I TEM_ CLI CK ©. The other parameters i n tire constructor
for the Li st Event deter mi ne four things: whether tire event shoul d bubbl e up
thr ough tire parent contai ners, whether or not it's cancel l abl e, tire col umn that you
cl i cked, and whi ch r ow you cl i cked. I n this i nstance we'r e si mul ati ng tire user cl i cki ng
tire first col umn of tire second r ow of tire D a t a Gr i d.
Now you shoul d be abl e to run tire tests agai n by openi ng up a command l i ne, nav-
i gati ng to your pr oj ect fol der and typi ng mvn t est . After all of the messages scrol l by
you shoul d be pr esented wi th a message saying that all tests passed. I f not, the results
of tire uni t tests are l ocated i n tire target/ surefi re- reports di rectory. Now that we've
got tire Vi ew tests worki ng, l et's move on to tire Model tests.
10.5 Test i ng t he Model
Now tlrat we've got the Presenter tests as wel l as tire Vi ew tests wel l under way, it's
time to l ook at wri ti ng tests for tire Model . The tests you'l l be wri ti ng for the Model
wi l l be somewhat similar to those you used to test tire Presenter i n tlrat we'l l be test-
i ng the i nteracti on between tire Model and tire Remot eSer vi c e by uti l i zi ng mock
obj ects and setti ng expectati ons on tire executi ons per f or med on them. You'l l start
as you di d for the Presenter and Vi ew tests by creati ng the test class.
Li s t i n g 1 0 . 1 3 I s s u e M o d e l Te s t . a s
pa c ka ge or g. f oj . model {
publ i c c l a ss I ssueModel Test {
pr i va t e va r t a r get : I ssueModel ;
pr i va t e va r ser vi c e: Moc kl ssueSer vi c e;
pr i va t e va r t oken: Async Token;
pr i va t e va r r esponder : I Responder ;
pr i va t e va r moc ker y: Moc ker y;
Pri vat e
f i el ds
[ Bef or e( a sync , t i meout =5000) ]
publ i c f unc t i on set Up( ) : voi d {
moc ker y = new Moc ker y( ) ;
moc ker y. pr epa r e( Moc kl ssueSer vi c e) ;
moc ker y. pr epa r e( Async Token) ;
moc ker y. pr epa r e( I Responder ) ;
n Set up
met hod
Async . pr oc eedOnEvent ( t hi s, moc ker y, Event . COMPLETE, 5000) ;
www.it-ebooks.info
Testing the Model 207
[ Af t er ]
publ i c f unc t i on t ea r Down( ) : voi d {
moc ker y. ver i f y( ser vi c e, t oken) ;
}
}
}
This test class starts much like the Presenter test. You defi ne private fields for di e tar-
get class you're testing, the mocks that you'l l need to interact with, and your mock
control Q . Inside your setup method, you instantiate your mock control and prepare
the various mocks tiiat you'l l be using, and set di e expectation to allow the test to con-
tinue only when the COMPLETE event is dispatched, ensuring that your mocks are ready
to be used ©. Last you defi ne your tearDown meti i od and put a call to di e ver i f y
meti i od on your mock control inside
10.5.1 Mock i ng and Remot eObj ect
Before you can start writing your tests for the I ssueModel, there is a caveat regard-
i ng di e RemoteObject class. As we've menti oned before, ActionScript is a fairly pow-
erful dynamic language. For tiiose familiar with Groovy or Ruby you'l l likely be
familiar with the concept of having di e ability to create fl uent domai n specific lan-
guages (DSLs) by leveraging di e method missing functionality. ActionScript also has
this ability, and the Abstr actSer vi ce class, which all of your remoti ng components
HTTPServi ce, WebServi ce, and RemoteObject derive from, takes advantage of tiiis to
allow you to call the remote obj ect methods as if they were defi ned by these remot-
i ng components.
A c ti o n S c ri p t d yn a m i c c la sse s, p ro xi e s, a n d m e th o d m i ssi n g
T o le a rn m o re a b o u t h o w t o u s e d yn a m i c c l a s s e s a n d i m p le m e n t s o m e t h i n g li k e
m e t h o d j n l s s i n g i n A c t i o n S c ri p t , t h e re i s a g o o d a rt i c l e o n t h e F l e x O n R a l l s b lo g a t
h t t p : / / f l e x o n ra l l s . n e t / ? p = 9 5 , w h i c h s h o u l d g e t y o u s t a rt e d .
The probl em witii this arises when you try to mock calls to these dynamic metiiods
that don't exist in di e RemoteObject class. I t woul d appear tiiat there is a limitation on
how the mocki ng framework instruments and creates mock objects—only di e metii-
ods that exist in the class defi ni ti on that you're mocki ng are able to be called. I f di e
meti i ods don't exist, di e meti i od call will be captured by di e cal l Pr oper t y method
and exhibit di e same dynamic behavior tiiat it woul d in your producti on code, which
is not what you want. To get past this, defi ne a stub class tiiat will extend di e Remote-
Obj ect class. Inside this class you will stub out di e meti i ods that your remote service
exposes, then you'l l mock this Mockl ssueServi ce class inside of your tests so you can
properl y set and verily your expectations.
Teardown
© met hod
www.it-ebooks.info
208 CHAPTER 1 0 Testing your Flex application
Li s t i n g 1 0 . 1 4 M o c k l s s u e Se r v i c e . a s
pa c ka ge or g. f oj . model {
i mpor t mx. r pc . Async Token;
i mpor t mx. r pc . r emot i ng. Remot eObj ec t ;
publ i c c l a ss Moc kl ssueSer vi c e ext ends Remot eObj ec t {
publ i c f unc t i on get Al l ( ) : Async Token {
r et ur n nul l ;
}
publ i c f unc t i on get ( i d: *) : Async Token {
r et ur n nul l ;
}
publ i c f unc t i on sa ve( i ssue: *) : Async Token {
r et ur n nul l ;
}
publ i c f unc t i on r emove( i d: *) : Async Token {
r et ur n nul l ;
}
Ext ends
Remot eObj ect
A St ubbed
met hods
Start your class defi ni ti on by extendi ng Remot eObj ec t so you can use tiiis to create a
mock and pass it to your I ssueModel when you instantiate it i n the test O - Next stub
out the methods tiiat you call on your Remot eObj ec t i nsi de di e I ssueModel , and
stub them to return nul l I t doesn't matter what you put i n these meti i ods
because you'l l be usi ng the mock fr amewor k to defi ne your expectati ons.
Li s t i n g 1 0 . 1 5 updated IssueModel c o n s t r u c t o r
publ i c f unc t i on I ssueModel ( i ssueSer vi c e: Remot eObj ec t = nul l ) {
i f ( i ssueSer vi c e != nul l ) {
_i ssueSer vi c e = i ssueSer vi c e;
} el se {
va r def a ul t Cha nnel Set : Cha nnel Set =
Cha nnel Set Fa c t or y. get D ef a ul t c ha nnel ( ) ;
_i ssueSer vi c e = new Remot eObj ec t ( ) ;
_i ssueSer vi c e. dest i na t i on = " i ssueSer vi c e" ;
_i ssueSer vi c e. c ha nnel Set = def a ul t Cha nnel Set ;
You updated di e constructor on di e I ssueModel class to enabl e i nj ecti ng the mock
Remot eObj ec t via the constructor.
www.it-ebooks.info
Testing the Model 209
10.5.2 Test i ng get l ssues
Now we'r e ready to wri te the I ssueModel tests. Let's start by testi ng tire get l s s u es
method, whi ch is probabl y tire most cal l ed method i n tire I ssueModel .
Li s t i n g 10.16 callsGetAHOnRemoteService
[ Test ]
publ i c f unc t i on c a l l sGet AHOnRemot eSer vi c e( ) : voi d {
ser vi c e = moc ker y. st r i c t ( Moc kl ssueSer vi c e) a s Moc kl ssueSer vi c e;
t oken = moc ker y. st r i c t ( Async Token) a s Async Token;
r esponder = moc ker y. st r i c t ( I Responder ) a s I Responder ;
moc ker y. moc k( ser vi c e) . met hod( " get Al l " )
. wi t hNoAr gs. r et ur ns( t oken) . onc e;
moc ker y. moc k( t oken) . met hod( " a ddResponder " )
. wi t hAr gs( r esponder ) . onc e;
t a r get = new I ssueModel ( ser vi c e) ;
t a r get . get l ssues( r esponder ) ; J
Mocks O
Mock
expect at i on
Cal l
get l ssues
You start by creati ng the mocks you need for this test, a mock of your Mockl ssue-
Ser vi ce tlrat you defi ned, a mock AsyncToken, and a mock I Responder Q . Next you
defi ne your expectati ons on tire mocks, starting wi th tire expectati on to call tire
get Al l method wi th no arguments, and returni ng tire mock AsyncToken you created.
Then you expect tlrat the mock AsyncToken's addResponder method wi l l be cal l ed
wi th the mock I Responder you created Q and use to also call tire method you'r e test-
i ng Q . Let's l ook at testi ng tire get l s s u e method.
10.5.3 Test i ng get si ngl e i ssue
The next method you'l l test on tire I ssueModel is tire get l s s u e method, whi ch takes
i n an issue I D as the fi rst par ameter to l ook up an issue by its I D. I t's onl y slightly mor e
i nvol ved than tire test you wrote, but still easy to fol l ow.
Li s t i n g 10.17 callsGetOnRemoteService
[ Test ]
publ i c f unc t i on c a l l sGet OnRemot eSer vi c e( ) : voi d {
ser vi c e = moc ker y. st r i c t ( Moc kl ssueSer vi c e) a s Moc kl ssueSer vi c e;
t oken = moc ker y. st r i c t ( Async Token) a s Async Token;
r esponder = moc ker y. st r i c t ( I Responder ) a s I Responder ;
Mocks O
va r i d: Number = 42; < —© ID paramet er
moc ker y. moc k( ser vi c e) . met hod( " get " ) . wi t hAr gs( i d) . r et ur ns( t oken) . onc e;
moc ker y. moc k( t oken) . met hod( " a ddResponder " ) . wi t hAr gs( I Responder ) . onc e;
h
t a r get = new I ssueModel ( ser vi c e) ;
t a r get . get l ssue( i d, r esponder ) ;
Mock expect at i ons O
Cal l get l ssue
www.it-ebooks.info
210 CHAPTER 1 0 Testing your Flex application
You start this test the same way you di d di e get l s s u es test, by creati ng all of the mocks
di at you need Q . You tiien defi ne a l ocal vari abl e to contai n the i d par ameter Q tiiat
we'l l call the meti i od we'r e testi ng wi th. Next defi ne your expectati ons on the mocks
Q , whi ch l ook si mi l ar to the get l s s u es test expectati ons, except that this time you'r e
expecti ng the get method on your RemoteObj ect to be cal l ed wi th di e i d par ameter
you defi ned previously. I n di e last step you instantiate your I ssueModel wi th your
mock servi ce and call the get l s s u e meti i od Q .
You now have a good start on di e uni t tests for this proj ect. I f you'r e feel i ng ambi -
tious conti nue down di e r oad of wri ti ng mor e tests for the proj ect. When you'r e fi n-
i shed come back and we'l l set up a conti nuous i ntegrati on server usi ng Hudson. Or
come back after you've got Hudson set up. I t's your choi ce.
10.6 Cont i nuous i nt egrat i on wi t h Hudson
When a team of two or mor e of devel oper s works together, an i mmedi ate need arises
for fr equent feedback on how tilings are goi ng, as changes are commi tted between
team member s. Thi s is wher e di e practi ce of Conti nuous I ntegr ati on (CI ) comes i n to
play. Tool i ng, l i ke Hudson, becomes a thi rd party and i mparti al member of a team. A
good CI server provi des teams wi ti i essential feedback thr ough the orchestrati on of
critical pr oj ect events as they pertai n to the bui l di ng and stability of di e source code.
I t also can pr ovi de a uni que l ook i nto the heal ti i of an appl i cati on.
I n this secti on, a Hudson CI server wi l l be confi gur ed to:
• Li sten for changes i n di e versi on control system
• Automati cal l y bui l d di e pr oj ect f r om di e top- l evel POM when changes are
di scovered
• Execute and r epor t on uni t test executi on
• Fail bui l ds upon bui l d errors or fai l ed tests
• Send emai l out to team member s upon fai l ed or cor r ected bui l ds
Setti ng up a CI server wi th even the most basic confi gur ati on yi el ds several benefi ts.
How a team confi gur es and uses a CI server depends on what di e appl i cati on does and
what ki nd of feedback is necessary to ensure that everythi ng is i n a heal ti i y state. Every
step, f r om code bei ng checked i nto di e versi on contr ol system to di e fi nal ver i fi cati on
of the depl oyment, and everyti i i ng i n between, is i mportant.
Several pl ugi ns can be confi gur ed wi ti i Hudson for di ffer ent purposes. To
understand what ki nd of CI confi gur ati on best suits a team's needs a team may
consi der j otti ng down a list of questi ons that may be i mpor tant to know every day
duri ng devel opment.
• What does di e appl i cati on do?
• What are di e user stories? (test cover age?)
• Does di e source code compi l e when i ntegrated?
• Do all di e uni t tests run successfully?
www.it-ebooks.info
Continuous integration with Hudson 211
• Is the code quality acceptabl e? (Hudson has pl ugi ns for code quality tool s l i ke
PMD, Fi ndBugs, and oti i er analysis tool s.)
• Is there an unheal thy vol ume of TODO and FI XME annotati ons i n the code and
what are tiiey? (Hudson has a task scanner pl ugi n tiiat per for ms static analysis
and creates visibility for di ese i n J ava code comment annotati ons al ong wi th
unheal thy threshol ds setti ngs.)
• Does the appl i cati on depl oy successfully?
• How do you veri l y di e appl i cati on and di e envi r onment(s) it has to run inside?
Now tiiat you have a feel for why you woul d want to have a CI envi r onment let's move
on to getti ng a sampl e Hudson i nstance set up for demonstrati on.
10.6.1 Downl oadi ng and i nst al l i ng Hudson
I nstal l i ng Hudson coul dn't be mor e trivial. Hudson is a si mpl e J ava web appl i cati on
and downl oads as a WAR fi l e. To downl oad Hudson, open your browser and navi gate
to http:/ / hudson-ci .org. Ther e you wi l l find the latest and greatest l i nk for downl oad-
i ng di e most current rel ease.
Hudson requi res J RE 1.5 or l ater and can be started standal one, wi ti i out an appl i -
cati on server, by i nvoki ng the command j ava - j ar hudson.war, wher e the hudson.war
file was i nstal l ed. Thi s wi l l fi r e up Hudson i nsi de of an embedded Wi nstone servl et
contai ner on por t 8080 by defaul t.
Hudson can also be i nstal l ed i nto a fi xed servl et contai ner tiiat supports Servl et 2.4/
J SP 2.0 or later, such as Glassfish, Tomcat, J Boss, and J etty.
I f pr obl ems arise dur i ng i nstal l ati on, consul t the Hudson websi te for hel p. Let's
move on to confi gur i ng the server.
10.6.2 Conf i guri ng Hudson
I f Hudson is i nstal l ed cor r ecdy you shoul d be abl e to see di e start screen. For tiiis sam-
pl e you'r e usi ng the embedded Wi nstone server. Open a web browser and navi gate to
http:/ / l ocal host:8080.Wl i en di er e, Hudson wi l l present an i ni ti al start page wi th no
j obs confi gur ed as seen i n fi gur e 10.2.
First confi gur e Hudson gl obal l y by sel ecti ng the Manage Hudson l i nk. Ther e you
can gl obal l y confi gur e Ant, Maven, and J DK versi ons. Confi gur i ng thi ngs gl obal l y wi l l
make them avai l abl e for all j obs you create. Fi gure 10.3 displays di e Hudson manage-
ment sel ecti on screen.
F r om the management screen sel ect the Conf i gur e Syst eml i nk at di e top of di e
list of opti ons. I t's also possi bl e to manage pl ugi ns, vi ew system i nfor mati on, and vi ew
l ogs f r om tiiis top- l evel screen. When you'r e i n the confi gur ati on screen you can
begi n to add di e versi on of Maven and J ava that you'd l i ke to use gl obal l y. Fi gure 10.4
displays the confi gur ati on screen.
Consi der di e list of goal s you want to accompl i sh for the demonstrati on. F r om the
Hudson confi gur ati on screen you want to confi gur e a versi on of Maven, a J DK, and
emai l noti fi cati on. Finally, you wi l l save it f r om there.
www.it-ebooks.info
212 CHAPTER 1 0 Testing your Flex application
¿ Dashboard [Hudson]
Hudson
Hudson 0I SA6LE AUTO BE FRESH
•¡Sf New J ob
Wel come to Hudson! Pl ease create new i obs to aet started.
[ g ad d descri pti on
j Hanaae Hudson
&Y»I<J Hi rtffrt
Build Queue
Mo builds in the queue.
O ui Id Executor 5tMus
t Status
1 Idle
Í Idle
Pagft genftrated: Nov 28, 2009 9:25:44 PM Hudson 1.336
Figure 10.2 Hudson start screen
Confi gur i ng Maven is as easy as sel ecti ng a versi on and i nstructi ng Hudson to automat-
ically install as seen i n fi gur e 10.5 or poi nti ng Hudson to an i nstal l ed Maven l ocati on.
Use tire defaul t to install Maven automati cal l y and enter a name for tire install some-
tiring meani ngful for tire versi on. Choose tire versi on and i nstal l ati on wi l l occur. To
M i Marita mrfHWl llkldi«»]
I t i
H u d s o n 1
Manage Hudson
d config files directly on diik.
Figure 10.3 The Hudson management selection screen
www.it-ebooks.info
Continuous integration with Hudson 213
Ij (i, Hudson
Hudson
Hudson
f t ' Men
j Manage Hudson
Build Hirtnrv
Build Queue
No builds in the queue.
Build Executor Status
9 Status
1 Idle
2 Idle
E l
Home directory
System Message
#of executors
Quiet period
SCM checkout retry count
C:\Documents and Settings\ballmon\,Hudson
O
m
• ©
©
Enable security
l~~ Prevent Cross Site Request Forgery exploits
& Help make Hudson better by sending anonymous usage statistics and crash reports to the
Hudson project.
Global properties
f
-
Environment variables
Maven
Maven installation I ^
List of Maven instillations on this system, &oth rnav&n I and 2 ire
J Up ported.
Figure 10.4 Hudson configuration screen
sel ect a versi on of Maven f r om a l ocal i nstal l ati on, desel ect the I nstall automati cal l y
checkbox. Fi gure 10.6 displays the result.
Enter the MAVEN_HOME, as seen in fi gur e 10.6, by poi nti ng to the di r ector y wher e
Maven is i nstal l ed. That's it I As you can see it's possi bl e to conti nue addi ng mor e
Maven installations by sel ecti ng the Add Maven button.
Maven"
Maven installation n a m e
|maven- 2.2.1
I* Install automatically
I nstal l f rom Apache
Version | 2,2.1 3
A d d I n sta lle r
Add Maven
©
D e le te I n sta lle r
D e le te M a v e n
List of Maven installations on this system. Both maven 1 and 2 are
supported.
Figure 10.5 Maven automatic installation selection
www.it-ebooks.info
214 CHAPTER 1 0 Testing your Flex application
Maven
M a van installation
"ame jmaven- 2.2.1
MAVEFJ _HOME | c:\java\maven\apache-maven-2.2.l|
Install automatically
Delete heaven
fii : 1 Maven
Lift of Maven Installations on this system, both miutn 1 and 2 ¿re
supported,
Figure 10.6 Maven local installation
Next, confi gur e tire J DK versi on used to compi l e tire J ava source code. I t's possi bl e
tlrat tire Maven POM fi l es wi l l over r i de this but tire Hudson bui l d server must contai n
tire versi on r equi r ed by tire POM. The J DK confi gur ati on works i denti cal l y to tire
Maven confi gur ati on.
Finally, you can set up the mai l settings by speci fyi ng a Si mpl e Mai l Transfer Proto-
col (SMTP) server, a defaul t domai n suffi x, a system admi n emai l address, and Hudson
URL, as seen i n fi gur e 10.7.
Havi ng emai l confi gur ed wi l l al l ow Hudson to communi cate to teams when bui l d
fai l ures or correcti ons occur. Now that Hudson is ready, l et's move on to creati ng a j ob
for tire Fl exBugs appl i cati on.
10.6.3 Conf i guri ng a Hudson j ob
Confi gur i ng a j ob for Hudson is as si mpl e as confi gur i ng Hudson itself. I n fact,
Hudson has good support for Maven proj ects and handl es mul ti modul e proj ects
wi th el egance by al l owi ng you to dri l l down i nto tire speci fi c modul es to gai n fi ne-
gr ai ned visibility.
E- mai l Notif ication
SMTP server |http ;/ / myMailServer.com ®
Default user e-mail suffix | ©
System Admin E- mail Address lhudson@myM3ilServer.com ©
Hudson URL jhttp ;/ / localhost:8080| @
Ad va n ce d ...
Test con figu ra tion by sen d in g e-m ail to S ystem Adm in
Ad d ress
S a ve
Figure 10.7 Hudson email notification
www.it-ebooks.info
Continuous integration with Hudson 215
To create a j ob i n Hudson, sel ect di e New J ob l i nk on the l eft side of the screen.
Hudson wi l l present opti ons for what type of j ob to create wi th di e ability to enter a
name for t hej ob and to copy confi gur ati on f r om another j ob, i f one exists. Fi gure 10.8
displays this i ni ti al screen.
To demonstrate Hudson you wi l l create a j ob for di e Fl exBugs appl i cati on and
sel ect a Maven 2 proj ect. After you sel ect di e OK button, Hudson wi l l present di e j ob
confi gur ati on screen. Thi s is wher e you wi l l confi gur e access to the source contr ol sys-
tem and oti i er settings that wi l l accompl i sh your basic goal s for bui l di ng and pr ovi di ng
feedback to di e team when changes are checked i nto di e source contr ol system.
On di e j ob confi gur ati on screen you wi l l mai nl y go wi th di e defaul t settings and
start by poi nti ng Hudson to your source contr ol management system. Fi gure 10.9 dis-
plays the settings that wi l l accompl i sh this wi th settings to check for changes every 5
mi nutes. Thi s wi l l cause a bui l d to occur.
The next tiling to do is confi gur e t hej ob wi th the needed Maven goal s. Fi gure 10.10
displays tiiis part of the screen. I t's good to note tiiat you can poi nt Hudson to a P OM
i n any di rectory or even to a Maven P OM oti i er than somethi ng named pom. xml . The
MAVEN_ OPTS may need to be confi gur ed to i ncrease di e memor y size for r unni ng
i nsi de the standal one Wi nstone server, for exampl e, - Xms256m - Xmx768m - XX: Ma x-
Per mSi ze=512m.
For Fl exBugs you need to call di e cl ean install goal s at di e top- l evel POM. Thi s wi l l
i nvoke di e Maven bui l d for all modul es as usual. You also added di e -e for outputti ng
Hudson I T
Hudson
Hudson
J ob na me |Fl ex.Bugs
~ Monitor an external job
TJ iis type of job allows you to record the execution of a process run outside Hudson,
even on a remote machine. This is designed so that tou can use Hudson as a dashboard
of your existing automation system. See the documentation for more details.
' Uuild a f ree- styl e sof tware proj ect
This is the central feature of Hudson. Hudson will build vour project, combining any SCM
with any build system, and this can be even used for something other than software
build,
' Build mul ti - conf i gurati on proj ect (al pha)
Suitable for projects that need a Forge number of different configurations, such as testing
on multiple environments, platform-specific builds, etc.
Build a maven? proj ect
Build a maven2 project. Hudson takes advantage of your POM files and drastically
reduces the configuration.
ra
Page generated: Nov 2®, 2009
c
32:33 PM Hudson ver, l .336
Mew J ob
/ Manage Hudson
~ Build Histor*
Build Queue
No builds in tbe queue.
Build Executor Status
# Statu*
1 Idle
Z Idle
Figure 10.8 Hudson job configuration start screen
www.it-ebooks.info
216 CHAPTER 1 0 Testing your Flex application
Source Code Management
C None
^ CVS
** Subversion
Modules
Repository URL |https:/ / flexonje va.googlecode.corr^svrv'f lex-bugs/ trunk ©P @
Local module directory (optional) | ifî)
Add mo«« locations... ®
Use update
If checked, Hudson will use 'svn update' whenever possible, making the build faster. But this causes the artifacts
from the previous build to remain when a new build starts.
Repository browser
(Auto) j J
Build Tri ggers
Advanced... |
& Build whenever a SNAPSHOT dependency is burlt
I
-
Build after other projects are built
I
-
Build periodically
& Poll SCM
Schedule
V5 • * * * 9$
Figure 10.9 Source code management section
stack trace i nfor mati on and also set up emai l noti fi cati on. The emai l noti fi cati on wi l l
use tire defaul t mai l settings you established when confi gur i ng Hudson gl obal settings.
After these settings are saved you can start tire bui l d by sel ecti ng tire Bui l d Now l i nk.
Build
Root POM I p o m . x m l
m
Goals and options |
m
Advanced... |
Build Setti ngs
I
-
E- mail Notification ©
Post- bui l d Acti ons
I
-
Archive the artifacts ®
Aggregate downstream test results 6
Build other projects 9
I
-
Deploy artifacts to Maven repository ©
Savtt |
Figure 10.10 The build instructions and email notification settings
www.it-ebooks.info
Summary 217
F r om there you have a bui l d started tiiat wi l l check out di e source code and bui l d the
enti re appl i cati on whi l e pr ovi di ng feedback on di e status and emai l s on bui l d fai l ures
or correcti ons.
That's all there is to confi gur i ng a CI server f r om the gr ound up! As you can see
Hudson provi des all ki nds of opti ons and vari ous ways to execute a j ob.
10.7 Summary
I n this chapter we i ntr oduced you to uni t testi ng usi ng Fl exUni t4 and di e mock-as3
mock testi ng fr amewor k. We also rei terated the reasoni ng behi nd di e Model Vi ew
Presenter pattern that we i ntr oduced i n chapter 4. We cover ed many of di e common
patterns that you woul d have needed to test i n your sampl e appl i cati on. Wi th di e
knowl edge pr esented i n this chapter, you shoul d be abl e to conti nue wri ti ng tests for
the rest of the functi onal i ty i n the appl i cati on.
Finally, you set up and confi gur ed a CI server for pr ovi di ng critical feedback on
how tilings are goi ng as code is i ntegrated i nto the source code reposi tory. Hudson is
a great choi ce for teams needi ng a rel i abl e CI server. Hudson has numer ous built-in
capabi l i ti es and a vi brant user communi ty wi ti i pl ugi ns for al most anythi ng.
I n chapter 11 we'r e goi ng to take a l ook at how you can qui ckl y get a Fl ex appl i ca-
ti on i ntegrated wi th di e Grails fr amewor k. We'l l qui ckl y i ntr oduce a si mpl e contact
management appl i cati on, and i ntegrate it wi th Grails as wel l asJ MS.
www.it-ebooks.info
Thi s chapt er covers
• I n t e g ra t i n g F l e x w i t h G ro o v y a n d G ra i l s
• I n s t a l l i n g t h e G ra i l s F l e x P l u g i n
• E x p o s i n g a G ra i l s s e rv i c e t o F l e x
• I n t e g ra t i n g F l e x w i t h J M S
Not all real-world devel opment is against an existing application. Every once in a
while you have fun devel opi ng new code. What do you do when you want to rapidly
prototype a data-driven application with Flex? Wi th the Flex part it's easy enough to
devel op a UI, but what about di e backend? You could always devel op a J ava-based
backend using di e same meti i ods and techniques we described throughout tiiis
book, or you could take advantage of another framework, such as Grails, to quickly
get your data-driven backend off di e ground.
.1 Why Groovy and Grai l s?
Groovy has been affectionately called J ava 2.0 by many in di e J ava world, so it
should be no surprise tiiat you can integrate with Groovy and Grails as easily—and
in some aspects more easily—as in previous chapters.
218
www.it-ebooks.info
Downloading and installing Grails 219
G ro o vy i s J a va 2 . 0
" G ro o v y i s a lo t li k e J a v a 2 . 0 , i f s o m e o n e s e t o u t t o c o m p l e t e l y re w ri t e t h e J a v a
l a n g u a g e t o d a y . R a t h e r t h a n re p la c i n g J a v a , G ro o v y c o m p l e m e n t s i t, p ro vi d i n g a
s i m p le r, s l i c k e r s y n t a x w h e re t h e t y p e c h e c k i n g i s d o n e d y n a m i c a l l y a t ru n t i m e .
Yo u c a n u s e G ro o v y t o w ri t e J a v a a p p l i c a t i o n s o n t h e fly, t o g l u e t o g e t h e r J a v a
m o d u le s , o r e v e n t o e x t e n d e x i s t i n g J a v a a p p l i c a t i o n s —y o u c a n e v e n u s e G ro o v y
t o u n i t t e s t y o u r J a v a c o d e . A n d t h e b e a u t y o f i t i s, G ro o v y le t s y o u d o a ll t h e s e
t h i n g s f a s t e r—s o m e t i m e s a lo t f a s t e r—t h a n y o u w o u l d i f y o u w e re w ri t i n g p u re
J a v a c o d e . "
A n d re w G l o v e r fro m h i s F lu e n t ly G ro o v y s e ri e s o n I B M D e v e l o p e rWo rk s (h t t p : / /
w w w . i b m . c o m / d e v e l o p e rw o rk s / e d u / j -d w -j a v a -j g ro o v y -i . h t m l )
You may be wonderi ng "Why Flex and Grails?" To which we respond, "Why not?" I n
this final chapter we're goi ng to demonstrate how you can quickly build and proto-
type data-enabled Flex applications, leveraging di e rapid devel opment provi ded by
Groovy and Grails coupl ed witii the powerful Grails plugin for Flex. Wheti i er your
intent is to spike out a particular pi ece of functionality or to build a compl ete applica-
tion, there are few options tiiat will allow you to devel op as rapidly as Grails.
We'r e goi ng to assume tiiat you are at least somewhat familiar with botii Groovy
and Grails, but if you've never seen or done any devel opment using either, you should
still be able to fol l ow along. We'l l show idiomatic Groovy code but won't go into too
much detail about what the code does as that is beyond di e scope of tiiis chapter. I f
you want to learn more about Groovy we suggest starting with the Groovy homepage
(http:/ / groovy.codehaus.org) or by readi ng Groovy in Action, Second Edition by Dierk
Koeni g (http:/ / www.manning.com/ koenig2/ ), published by Manni ng Publications.
I n this chapter we'l l be building a simplified contact management application called
Flex Contacts. You'l l build a single Master-Detail screen tiiat you can use to track your
contacts as shown in fi gure 11.1
Before you start writing the application, you'l l need to install Grails.
11.2 Downl oadi ng and i nst al l i ng Grai l s
Installing Grails is a ratiier simple task. Poi nt your browser to the Grails proj ect
downloads page (http:/ / grails.org/ Download) and downl oad di e appropriate distri-
bution for your platform. This chapter was written using Grails 1.1.2, which was
the latest stable distribution available at the time of writing. There is no reason to
install Groovy separately because it's i ncl uded witii the Grails distribution. Grails is
available in two main forms, a binary distribution and a source distribution. Down-
load di e binary distribution in either Zip or Tar/ GZ format, dependi ng on your
operati ng system.
After you've downl oaded the binary distribution for Grails, unzip the Grails distri-
bution to a fol der such as c : \ dev\ gr a i l s- l . 1. 2. Then create a GRAI LS_HOME environ-
ment variable and poi nt it to the same folder. As a last step, append GRAI LS_HOME\ bi n
www.it-ebooks.info
220 CHAPTER 11 Flex on Grails
f l i l f l I ".i n :n.m
I ^ I"' +^ - . Kh,i
K
III alai :-'"t' Ill-Ill'1111,11- III-i '¿. Kq]- ~
Fiex Contacts on Grails
Li i l Namt Hi mI«v
Anamsn iil Man Ji mum
Allrncn l|l Any Dr h 1-111
• elttt Ili Hi ll
HI .1
f l j f l l ?
tonIllHf •
I •-> ll
111 ll
Accrei s: "»
f
St
city: Mnmn
STji t: MI
zip cod«; I'I-IIH
Contact Saw* I.II.II i ll
Figure 11.1 The sample application
to your PATH vari abl e so that you can run the Grails executabl e f r om the command
l i ne. When you've fi ni shed, open up a command l i ne and type gr ai l s - ver s i on and
you shoul d see output si mi l ar to tiris sni ppet.
C: \ dev> gr a i l s - ver si on
Wel c ome t o Gr a i l s 1. 1. 2 - ht t p: / / gr a i l s. or g/
Li c ensed under Apa c he St a nda r d Li c ense 2. 0
Gr a i l s home i s set t o: C: \ dev\ gr a i l s- l . 1. 2
Ba se D i r ec t or y: C: \ dev
Congratul ati ons! You've got Grails i nstal l ed and confi gur ed. Now l et's move on to cre-
ati ng the Grails appl i cati on.
11.3 Creat i ng t he Grai l s appl i cat i on
Her e's wher e you see one of tire first exampl es of Grai l s' convention over configuration
way of doi ng things. To create your Grails appl i cati on, you must open a command l i ne
and navi gate to tire fol der wher e you want to create your Grails appl i cati on, for exam-
pl e c : \ dev\ pro j ect s \ and type tire fol l owi ng command.
www.it-ebooks.info
Creating the Grails application 221
C: \ dev\ pr oj ec t s\ > gr a i l s c r ea t e- a pp f l ex- c ont a c t s
Wi th that one si mpl e command Grails has enough i nfor mati on to gener ate your proj -
ect for you. No hard to r emember or crypti c command l i ne parameters, one si mpl e
conci se command and Grails creates the pr oj ect structure and installs all the neces-
sary dependenci es. You don't even have to install a database server or servl et con-
tai ner to run the appl i cati on; that's all i ncl uded out of the box when you create your
Grails appl i cati on. I f you thi nk tiiat was easy, wai t unti l you see how easily you can add
functi onal i ty to your Grails appl i cati on usi ng pl ugi ns. But first, l et's conti nue bui l di ng
the Grails appl i cati on by starting wi th defi ni ng di e domai n model .
11.3.1 Creat e t he Cont act domai n model
Next you'l l create di e domai n class tiiat wi l l be responsi bl e for hol di ng contact i nfor-
mati on. For this you'l l need onl y one domai n obj ect cal l ed Cont a c t . Create di e Con-
t a c t obj ect by issuing di e fol l owi ng command:
C: \ dev\ pr oj ec t s\ f l ex- c ont a c t s\ > gr a i l s c r ea t e- doma i n- c l a ss c ont a c t
Thi s wi l l create the Cont a c t domai n model class i n di e gr a i l s- a pp/ doma i n fol der
wi ti i i n your fl ex- contacts proj ect. I n the Cont a c t domai n model , you'r e goi ng to add a
few si mpl e properti es for persi sti ng the contact i nfor mati on such as fi rst name, last
name, and address i nfor mati on, as wel l as si mpl e val i dati on constraints. Her e is what
your compl eted Contact.groovy fi l e wi l l l ook l i ke.
Li s t i n g 1 1 . 1 Co n t a c t . g r o o v y f i l e
c l a ss Cont a c t {
st a t i c c ont st r a i nt s = {
f i r st Na me( bl a nk: f a l se, mi nLengt h: 4, ma xLengt h: 15)
l a st Na me( bl a nk: f a l se, mi nLengt h: 4, ma xLengt h: 25)
a ddr ess( bl a nk: f a l se)
c i t y( bl a nk: f a l se)
st a t e( bl a nk: f a l se, l engt h: 2)
zi pCode( bl a nk: f a l se, mi nLengt h: 5, ma xLengt h: 10)
}
St r i ng f i r st Na me
St r i ng l a st Na me
St r i ng a ddr ess
St r i ng c i t y
St r i ng st a t e
St r i ng zi pCode
St r i ng t oSt r i ngO {
r et ur n f i r st Na me +
The Cont a c t class contai ns fi el ds tiiat you'l l need to hol d tilings l i ke fi rst name, last
name, and address ©. You've also defi ned a few constraints O so tiiat you can val i date
<—
O Const r ai nt s
<—
© Propert i es
+ l a st Na me
t oSt r i ngO
www.it-ebooks.info
222 CHAPTER 11 Flex on Grails
that you get all the i nfor mati on you need f r om the fr ontend. You've also i mpl emented
a t oSt r i ngO © method to pr ovi de a mor e meani ngful i mpl ementati on than the
defaul t. Now let's create di e servi ce tiiat you'l l be exposi ng to the Fl ex appl i cati on.
11.3.2 Creat e t he Cont act Servi ce
To expose your Grails appl i cati on to the Fl ex fr ontend, create a servi ce tiiat wi l l
expose the functi onal i ty for your appl i cati on to per f or m CRUD operati ons on your
Cont a c t domai n obj ect. To do this you issue di e fol l owi ng command on di e com-
mand l i ne:
C: \ dev\ pr oj ec t s\ f l ex- c ont a c t s> gr a i l s c r ea t e- ser vi c e c ont a c t
Thi s wi l l create a class named Cont a c t Ser vi c e, shown i n listing 11.2, i n the grails-
app/ servi ces fol der. The Cont a c t Ser vi c e wi l l contai n the meti i ods you'l l be exposi ng
to Fl ex to consume as a r emote servi ce. I nsi de di e ContactServi ce.groovy fi l e you'l l
i mpl ement a few si mpl e meti i ods to enabl e your Fl ex appl i cati on to get a list of all the
contacts i n the database, get a speci fi c contact, save a contact, and del ete a contact
f r om di e database.
Li s t i n g 1 1 . 2 Co n t a c t Se r v i c e . g r o o v y f i l e
c l a ss Cont a c t Ser vi c e {
st a t i c expose = [
1
f l ex- r emot i ng
1
]
bool ea n t r a nsa c t i ona l = t r ue
def get Cont a c t s( ) {
r et ur n Cont a c t . l i st ( )
}
def get ( i d) {
r et ur n Cont a c t . get ( i d)
}
def upda t e( Cont a c t c ont a c t ) {
c ont a c t . sa ve( )
}
def r emove( Cont a c t c ont a c t ) {
c ont a c t . del et e( f l ush: t r ue)
}
O Expose t o Fl ex
<
A Transact i onal
< - J pr oper t y
A Servi ce
met hods
Most of the Cont a c t Ser vi c e class shoul d l ook fami l i ar to you. The onl y l i ne tiiat
may l ook odd is tiiat whi ch contai ns the code st a t i c expose = [
1
fl ex- r emot i ng
1
]
O - Thi s si ngl e l i ne of code is all you need to expose tiiis servi ce to Fl ex so that you
can call any of the servi ce meti i ods f r om your Fl ex appl i cati on. You also make all of
the servi ce methods © i n your servi ce transacti onal by setti ng the transacti onal
pr oper ty to t r ue ©. The Fl ex pl ugi n for Grails, whi ch we'l l install i n a bit, fol l ows
the Grails phi l osophy of conventi on over confi gur ati on i n that it abstracts much of
www.it-ebooks.info
Getting rich with Flex 223
the confi gur ati on that you woul d have needed to bui l d had this been a J ava appl i ca-
ti on l ever agi ng ei ther BlazeDS or Li veCycl e Data Services to expose this functi onal i ty.
11.3.3 Boot st rap sampl e dat a
The last step bui l di ng tire Fl ex cl i ent is to bootstrap your appl i cati on wi th sampl e data
so tlrat you have contact i nfor mati on i n tire database when you fi rst run it. Thi s wi l l
also al l ow you to see tlrat the Fl ex r emoti ng is wor ki ng correctl y. To do this you add
the code shown next to tire B oot st r ap. gr oovy fi l e i n the gr ai l s- app/ conf fol der of
your appl i cati on.
Li s t i n g 1 1 . 3 Bo o t St r a p . g r o o v y f i l e
c l a ss Boot st r a p {
def i ni t = {ser vl et Cont ext - >
Cont a c t c ont a c t l = new Cont a c t ( f i r st Na me: " J er emy" ,
l a st Na me: " Ander son" , a ddr ess: "123 Ma i n St " ,
c i t y: " J eni son" , st a t e: "MI ", zi pCode: " 49428" )
c ont a c t l . sa ve( )
Cont a c t c ont a c t 2 = new Cont a c t ( f i r st Na me: "BJ ",
l a st Na me: " Al l mon" , a ddr ess: "234 Any St " ,
c i t y: " D el a wa r e" , st a t e: "OH", zi pCode: " 43015" )
c ont a c t 2. sa ve( )
}
def dest r oy = {
}
}
Bootstrappi ng data i n Grails allows you to have data i nj ected i nto the appl i cati on each
ti me you restart it. You do this by creati ng a coupl e of Contact obj ects O i n your Boot-
Strap.groovy fi l e and call save () on them to persist them to tire database. Thi s is a
hel pful feature of Grails as you move thr ough devel opment and beats havi ng to manu-
ally enter contacts every time. You woul d typically use this fi l e for bootstr appi ng any
ki nd of i ni ti al data i n your appl i cati on, such as states and state codes. Now you'r e
ready to begi n devel opi ng the Fl ex fr ontend for tire Grails appl i cati on you created.
11.4 Get t i ng ri ch wi t h Fl ex
Now tlrat you have created your Grails appl i cati on you can move on to the task of cre-
ati ng tire Fl ex cl i ent that wi l l i ntegrate wi th Grails. You'l l start by i nstal l i ng the Fl ex
pl ugi n for Grails, then add tire Fl ex appl i cati on to tire Grails proj ect.
11.4.1 Inst al l i ng t he Fl ex pl ugi n
F r om tire r oot of tire pr oj ect di rectory enter tire fol l owi ng command to install tire Fl ex
pl ugi n for tire Grails appl i cati on:
C: \ dev\ pr oj ec t s\ f l ex- c ont a c t s\ > gr a i l s i nst a l l - pl ugi n f l ex
Sample
dat a
www.it-ebooks.info
224 CHAPTER 1 1 Flex on Grails
Thi s command wi l l pul l down all of di e Fl ex l i brari es your appl i cati on needs to be
abl e to compi l e the Fl ex appl i cati on. Thi s may take ti me because the pl ugi n has to
pul l down many dependenci es. After all di e messages have scrol l ed by the pl ugi n
shoul d be successfully i nstal l ed. Li ke many oti i er features i n Grails devel opment,
enabl i ng an appl i cati on for Fl ex i ntegrati on is extremel y si mpl e and decl arati ve. No
confi gur ati on fi l es need to be created, though some confi gur ati on fi l es are con-
tai ned wi ti i i n the web- a pp/ WEB- I NF fol der i f you need to fine-tune di e Fl ex com-
pi l er settings.
11.4.2 Creat i ng t he domai n cl asses i n Fl ex
You can begi n the Fl ex devel opment by creati ng a domai n obj ect i n Acti onScri pt. Thi s
obj ect wi l l act a,s a, data transfer obj ect of sorts, al l owi ng you to deal wi ti i ful l - fl edged
obj ects when your servi ce returns data to di e cl i ent. Thi s appr oach avoi ds havi ng to
deal wi th the pseudopr oxy obj ects tiiat Fl ex woul d wrap your obj ects i nto i f it di dn't
have anythi ng to translate it i nto.
When you i nstal l ed the Fl ex pl ugi n i n di e previ ous step, it created a flex fol der
under web- a pp/ WEB- I NF. I nsi de tiiis fol der resi des anoti i er fol der cal l ed user-classes,
whi ch contai ns a file that clues you i nto wher e you'r e supposed to pl ace your Acti on-
Scri pt classes, appropri atel y cal l ed add_your_as_and_swc_fi l es_here. Create a file i n
di e user-classes fol der cal l ed Contactas.
Li s t i n g 1 1 . 4 Co n t a c t . a s
pa c ka ge {
[ Bi nda bl e]
[ Remot eCl a ss( a l i a s = " Cont a c t " ) ]
publ i c c l a ss Cont a c t {
publ i c f unc t i on Cont a c t ! ) {
}
publ i c va r i d: *;
publ i c va r ver si on: *;
publ i c va r f i r st Na me: St r i ng
publ i c va r l a st Na me: St r i ng
publ i c va r a ddr ess: St r i ng
publ i c va r c i t y: St r i ng
publ i c va r st a t e: St r i ng
publ i c va r zi pCode: St r i ng
The code shoul d resembl e di e cl i ent side domai n classes tiiat you created earl i er for
your Fl exBugs appl i cati on. Take note of the annotati ons at the top of the file, [ Bi nd-
a bl e] © and [ Remot eCl a ss] Q . The [ Bi nda bl e] annotati on lets Fl ex know that
whenever one of the values changes i n this obj ect, it shoul d noti fy anythi ng else that is
bound to this obj ect to l et it know that it shoul d update itself. We di dn't uti l i ze data
J
81
Bi ndabl e
lP
Hi
r p
r
Remot eClass
Hi bernat e speci f i c
pr oper t i es
1
Publ i c
pr oper t i es
www.it-ebooks.info
Getting rich with Flex 225
bi ndi ng i n our oti rer appl i cati on but for this qui ck exampl e we di d, i n or der to keep
the exampl es shorter.
I n case you have for gotten, tire [ Remot eCl a ss] annotati on allows a Fl ex class to be
mapped to a server-side class. The Cont a c t . a s class is mapped to the Cont a c t . gr oovy
domai n class you created earlier. Because you'r e usi ng a package structure i n this triv-
ial exampl e, you don't need to ful l y qual i fy it her e; i f your domai n obj ect i n Grails fel l
under a speci fi c package, you woul d have to ful l y qual i fy that obj ect i n this annotati on
for it to wor k correctl y.
You need to add a coupl e of Hi bernate- speci fi c properti es Q to your Cont a c t
domai n class for your appl i cati on to behave as i ntended, al ong wi th all tire nor mal
publ i c properti es Q that you need to i ncl ude for tire data fi el ds you want to be abl e to
be persist.
11.4.3 Creat i ng t he Fl ex appl i cat i on
Now tlrat you've got your domai n obj ect created for the cl i ent side, you'l l need to cre-
ate a fi l e to contai n the mai n Fl ex appl i cati on itself, whi ch wi l l be cal l ed mai n. mxml
and is created i n tire web- app fol der of your Grails appl i cati on.
You'l l break this down i nto bite-sized chunks tlrat shoul d be easi er to di gest than i f
you wer e si mpl y pr esented wi th the end state of tire appl i cati on. First you'l l start by
creati ng tire Appl i c a t i on obj ect. As i n the oti rer sampl e appl i cati on, your Fl ex appl i -
cati on wi l l have tire Appl i c a t i on el ement as its r oot node of tire MXML fi l e as shown
i n this sni ppet.
<?xml ver si on=" 1. 0" enc odi ng=" ut f - 8" ?>
<mx: Appl i c a t i on xml ns: mx=" ht t p: / / www. a dobe. c om/ 2006/ mxml "
xml ns: l oc a l =" *"
l a yout =" ver t i c a l "
c r ea t i onCompl et e=" c ont a c t Ser vi c e. get Cont a c t s( ) "
vi ewSour c eURL=" sr c vi ew/ i ndex. ht ml " >
</ mx: Appl i c a t i on>
Now tlrat you've got tire base appl i cati on started, you'r e ready to start l ayi ng out tire
basic l ayout.
DEFINING THE LAYOUT
L ook at fi gur e 11.1 agai n, and take note that you've got three mai n contai ners i n use
for this appl i cati on. You've got the header at tire top contai ni ng tire text Flex Contacts
on Grails, and two panel s contai ni ng the master vi ew and tire details view. Let's create
the basic l ayout for your appl i cati on. To do that you'r e goi ng to l everage a coupl e of
l ayout components: HBox and Pa nel . We'l l break up the Mai n. mxml and l ook at each
secti on i ndi vi dual l y.
Li s t i n g 1 1 . 5 M a i n . m x m l ( a )
<mx: HBox wi dt h=" 100%" > <1—,
<mx: Text f ont Si ze=" 24 " t ext =" Fl ex Cont a c t s on Gr a i l s "/ > A Header cont ai ner
</ mx: HBox>
www.it-ebooks.info
226 CHAPTER 11 Flex on Grails
<mx: HBox wi dt h=" 100%" hei ght =" 100%" >
<mx: Pa nel wi dt h=" 65%" t i t l e=" Cont a c t s" hei ght =" 100%" >
</ mx: Pa nel >
<mx: Pa nel wi dt h=" 35%" t i t l e=" Edi t Cont a c t " hei ght =" 100%" >
</ mx: Pa nel >
</ mx: HBox>
Master
view
« N M
© vi
<
~ 1 Det ai
© vi ew
Thi s listing shows the code used to gener ate di e l ayout of our appl i cati on. I n the snip-
pet we saw previ ousl y you speci fi ed tiiat your appl i cati on use vertical as its mai n l ayout
method so your components wi l l fl ow verti cal l y down as you add di em to di e appl i ca-
tion. Her e you start by addi ng an HBox contai ner © contai ni ng a si ngl e Text compo-
nent. Thi s Text component contai ns the text for our title that appears i n di e header.
Next you wrap two Pa nel contai ners i n another HBox so tiiey'll show up side by side i n
di e appl i cati on. These two Pa nel components wi l l house the master vi ew © and detai l
vi ew ©.
CREATI NG THE MASTER VIEW
I nsi de di e fi rst Pa nel contai ner you'l l create di e master vi ew usi ng di e D a t a Gr i d com-
ponent, whi ch allows you to display tabul ar data rati i er painlessly.
Li s t i n g 1 1 . 6 M a i n . m x m l ( b )
<mx: D a t a Gr i d i d=" c ont a c t sGr i d"
wi dth=" 100%" O Dat aPr ovi der
hei ght =" 100%"
da t a Pr ovi der =" {c ont a c t sLi st }"
i t emCl i c k=" doSel ec t ( Cont a c t ( event . c ur r ent Ta r get . sel ec t edl t em) )
J
<mx: c ol umns>
<mx: D a t a Gr i dCol umn da t a Fi el d=" i d" hea der Text =" I D " wi dt h=" 50" / > <
<mx: D a t a Gr i dCol umn da t a Fi el d=" f i r st Na me"
hea der Text =" Fi r st Na me" wi dt h=" 100" / > _ ^ _ . .
DataGrid
<mx: D a t a Gr i dCol umn da t a Fi el d=" l a st Na me" .
• , „ „ , col umns
hea der Text =" La st Na me" wi dt h=" 100" / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" a ddr ess" hea der Text =" Addr ess" / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" c i t y" hea der Text =" Ci t y" wi dt h=" 120" / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" st a t e" hea der Text =" St a t e" wi dt h=" 70" / >
<mx: D a t a Gr i dCol umn da t a Fi el d=" zi pCode" hea der Text =" Zi pCode"
wi dt h=" 100" / >
</ mx: c ol umns> <
</ mx: D a t a Gr i d>
<mx: Cont r ol Ba r >
<mx: But t on l a bel =" D el et e Cont a c t "
ena bl ed=" {c ont a c t sGr i d. sel ec t edl t em != nul l }" Cont r ol Bar
c l i c k=" del et eCont a c t ( sel ec t edCont a c t ) " / >
<mx: But t on l a bel =" Ref r esh" c l i c k=" c ont a c t Ser vi c e. get Cont a c t s( ) " / >
</ mx: Cont r ol Ba r >
-I
Thi s por ti on of the listing shows the code to create di e contacts D a t a Gr i d as wel l as to
defi ne di e col umns to be di spl ayed. You may have noti ced di e i tems contai ned wi thi n
di e curly braces {}; tiiis is how to speci fy data bi ndi ng i n a Fl ex appl i cati on. You've
www.it-ebooks.info
Getting rich with Flex 227
bound di e dat aPr ovi der pr oper ty O °f the DataGr i d to di e con t act s L i s t vari abl e,
whi ch you'l l defi ne later. Thi s is wher e you'l l store the results f r om your RemoteObj ect
medi od call to get all the contacts. Noti ce that all of your col umn names Q shoul d
match what you defi ned i n di e Contact obj ect you created earlier. Thi s allows Fl ex to
automati cal l y fi gur e out whi ch data fi el d to map to whi ch col umn.
A Contr ol Bar © wi l l contai n all of the buttons needed to i nteract wi th this control .
CREATI NG THE DETAIL VIEW
Now di at the master vi ew has been created, it's on to di e detai l view. The detai l vi ew
wi l l pr ovi de a mechani sm for edi ti ng and updati ng your contacts. Al though we coul d
have al l owed edi ti ng ri ght i n the DataGr i d itself, it woul dn't have made for a good
exampl e and doesn't show off di e power of data bi ndi ng i n Fl ex.
Li s t i n g 1 1 . 7 M a i n . m x m l ( c )
<mx: For m i d=" c ont a c t For m" wi dt h=" 100%" >
<mx: For mI t em l a bel =" I D : " wi dt h=" 100%" >
<mx: Text t ext =" {sel ec t edCont a c t . i d}" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Fi r st Na me: " wi dt h=" 100%" >
< —O The Form
<mx: Text l nput i d=" f i r st Na me"
</ mx: For mI t em>
<mx: For mI t em l a bel =" La st Na me:
t ext =" {sel ec t edCont a c t . f i r st Na me}" / >
wi dt h=" 100%" >
<mx: Text l nput i d=" l a st Na me" t ext =" {sel ec t edCont a c t . l a st Na me}" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Addr ess: " wi dt h=" 100%" >
<mx: Text l nput i d=" a ddr ess" t ext =" {sel ec t edCont a c t . a ddr ess}" / >
</ mx: For mI t em>
<mx: For mI t em l a bel ="Ci t y: " wi dt h=" 100%" > Form l t em s 0
<mx: Text l nput i d=" c i t y" t ext =" {sel ec t edCont a c t . c i t y}" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" St a t e: " wi dt h=" 100%" >
<mx: Text l nput i d=" st a t e" t ext =" {sel ec t edCont a c t . st a t e}" / >
</ mx: For mI t em>
<mx: For mI t em l a bel =" Zi p Code: " wi dt h=" 100%" >
<mx: Text l nput i d=" zi pCode" t ext =" {sel ec t edCont a c t . zi pCode}" / >
</ mx: For mI t em> <—
</ mx: For m>
<mx: Cont r ol Ba r >
<mx: But t on l a bel =" New Cont a c t "
ena bl ed=" t r ue" c l i c k=" sel ec t edCont a c t = new Cont a c t ! ) " / >
<mx: But t on l a bel =" Sa ve Cont a c t "
c l i c k=" upda t eCont a c t ( sel ec t edCont a c t ) " / >
<mx: But t on l a bel =" Reset " c l i c k=" r eset For m( ) " / >
</ mx: Cont r ol Ba r >
O Cont r ol Bar
Her e is the code for the detai l vi ew i n whi ch you l everage anoti i er contai ner obj ect,
the Form component O - Unl i ke its HTML counterpart, the Form component i n Fl ex is
strictiy a contai ner. You don't need to have your fi el ds wr apped i n a Form component
to post data to the server side.
www.it-ebooks.info
228 CHAPTER 11 Flex on Grails
I nsi de di e Form component you defi ne a series of Forml tem components Q drat
contai n tire GUI for m components used for data entry. These shoul d be fai rl y self-
expl anatory. Take note of tire data bi ndi ng syntax i n tire text attributes for these com-
ponents. Thi s i ndi cates that you'l l be bi ndi ng tire text values of these components to a
vari abl e cal l ed sel ect edCont act . As a last step, you add another Contr ol Bar © as you
di d for tire master vi ew to contai n any buttons needed to contr ol tire appl i cati on.
11.4.4 Addi ng t he Remot eServi ce
Fl ex has a few components that enabl e it to communi cate wi th tire server side, namel y
HTTPSer vi ce, WebSer vi ce, and RemoteSer vi ce. I n a nutshel l WebSer vi ce faci l i tates
easy communi cati on wi th SOAP-based web services. HTTPSer vi ce allows you to con-
sume and call other web services usi ng a variety of pr otocol s such as XML and J SON
and is tire best choi ce i f you'r e tryi ng to i nteract wi th some sort of RESTful resource.
RemoteSer vi ce l everages Adobe's bi nary AMF ) pr otocol , whi ch tends to gi ve tire best
per for mance of the three.
Li s t i n g 1 1 . 8 Ad d i n g t h e Re m o t e Se r v i c e
<mx: Remot eObj ec t i d=" c ont a c t Ser vi c e" dest i na t i on=" c ont a c t Ser vi c e" >
<mx: met hod na me=" get Cont a c t s"
r esul t =" ha ndl eGet Cont a c t s( event . r esul t ) "
f a ul t =" showFa ul t ( event ) " / >
<mx: met hod na me=" upda t e" f a ul t =" showFa ul t ( event ) " / >
<mx: met hod na me=" r emove" f a ul t =" showFa ul t ( event ) " / >
</ mx: Remot eObj ec t >
As stated previ ousl y you'r e goi ng to use tire RemoteObj ect component to faci l i tate
communi cati on wi th the server side, and you've defi ned tire methods that you'l l be
cal l i ng so you can defi ne tire cal l back methods that you'l l be usi ng to handl e tire
results comi ng back f r om the server, as wel l as any faults.
11.4.5 Put t i ng i t ai l t oget her
You'r e al most done. You now put it all together and add methods that you'l l call to
handl e events f r om the UI .
Li s t i n g 1 1 . 9 M a i n . m x m ( d )
<l oc a l : Cont a c t i d=" sel ec t edCont a c t "
f i r st Na me=" {f i r st Na me. t ext }
l a st Na me=" {l a st Na me. t ext }"
a ddr ess=" {a ddr ess. t ext }"
c i t y=" {c i t y. t ext }"
st a t e=" {st a t e. t ext }"
zi pCode=" {zi pCode. t ext }" / >
<mx: Ar r a yCol l ec t i on i d=" c ont a c t sLi st " / >
<mx: Sc r i pt >
<! [ CD ATA[
Cont act
www.it-ebooks.info
Install the GrailsJ MS and ActiveMQplugins 229
i mpor t mx. r pc . event s. Fa ul t Event ;
i mpor t mx. c ont r ol s. Al er t ;
pr i va t e f unc t i on doSel ec t ( c : Cont a c t ) : voi d {
sel ec t edCont a c t = c ;
pr i va t e f unc t i on ha ndl eGet Cont a c t s( l i st : *) : voi d {
c ont a c t sLi st . r emoveAl l ( ) ;
f or ea c h ( va r c : Cont a c t i n l i st ) {
}
J
Remot eObj ect
event handl er
c ont a c t sLi st . a ddl t em( c ) ;
}
J
Remot eObj ect
f aul t handl er pr i va t e f unc t i on showFa ul t ( f a ul t : *) : voi d {
Al er t . show( f a ul t . messa ge) ;
}
pr i va t e f unc t i on del et eCont a c t ( sel ec t edCont a c t : Cont a c t ) : voi d {
c ont a c t Ser vi c e. r emove( sel ec t edCont a c t ) ;
c ont a c t Ser vi c e. get Cont a c t s( ) ;
}
pr i va t e f unc t i on upda t eCont a c t ( c ont a c t : Cont a c t ) : voi d {
c ont a c t Ser vi c e. upda t e( sel ec t edCont a c t ) ;
c ont a c t Ser vi c e. get Cont a c t s( ) ;
}
Event handl ers Q
pr i va t e f unc t i on r eset For m( ) : voi d {
va r t mpObj : Cont a c t = Cont a c t ( c ont a c t sGr i d. sel ec t edl t em) ;
c ont a c t Ser vi c e. get Cont a c t s( ) ;
c ont a c t sGr i d. sel ec t edl t em = t mpObj ;
doSel ec t ( Cont a c t ( c ont a c t sGr i d. sel ec t edl t em) ) ; <1—
}
] ]>
</ mx: Sc r i pt >
Most of what is shown i n the listing shoul d make sense. Her e you defi ne a Cont a c t
obj ect i n MXML rati i er tiian Acti onScr i pt O Noti ce that you'r e also per for mi ng data
bi ndi ng back to the for m components, creati ng a two-way bi ndi ng between di e
sel ec t edCont a c t vari abl e and the detai l for m. Next defi ne the event handl er © and
faul t handl er Q for di e Remot eObj ec t tiiat you defi ned i n listing 11.8. Last you have
all the event handl ers for di e components i n di e master vi ew and detai l vi ew Q .
Now that you've compl eted this part of di e appl i cati on, you can start up your Grails
appl i cati on by executi ng gr ai l s run- app and navi gati ng to the appl i cati on. After your
appl i cati on is runni ng, fi re up your browser and navi gate to http:/ / l ocal host:8080/ fl ex-
con tacts/ mai n.mxml and you shoul d see someti i i ng r esembl i ng fi gur e 11.1. You've got
a functi onal Fl ex appl i cati on r unni ng on Grails. Over the next few secti ons you'r e
goi ng to modi fy this si mpl e exampl e to l everage J MS and Acti veMQ.
Next you'r e goi ng to demonstrate di e ability of your Grails appl i cati on to push data
out to di e Fl ex appl i cati on usi ng Fl ex components that i ntegrate wi th J MS to pr oduce
and consume messages. Thi s wi l l al l ow you to r emove di e Refr esh button and some of
the pl umbi ng i nvol ved to refresh di e Fl ex D a t a Gr i d when a user adds, edits, or del etes
11.5 Inst al l t he Grai l s JMS and Act i veMQ pl ugi ns
www.it-ebooks.info
230 CHAPTER 1 1 Flex on Grails
a contact. Thi s hel ps cl ean up the cl i ent by r educi ng tire amount of vi ew l ogi c and
compl exi ty. To install tire Grails J MS pl ugi n f r om tire r oot of tire pr oj ect di rectory use
this sni ppet:
$ gr a i l s i nst a l l - pl ugi n j ms
Then do the same for tire Acti veMQ pl ugi n:
$ gr a i l s i nst a l l - pl ugi n a c t i vemq
After these pl ugi ns are i nstal l ed you'r e ready for devel opment. The beauty of Grails
conventi ons is that they hi de most of tire compl exi ty of plugging in new external frame-
works such as J MS and Acti veMQ. I t's wor th menti oni ng that tire J MS and Acti veMQ
pl ugi ns are still fai rl y new but seem to do tire j ob for tire most common situations.
Now that you have tire pl ugi ns for maki ng tire appl i cati on J MS-enabled, you can move
on to updati ng tire Grails appl i cati on code. Onl y a few thi ngs need to happen to pro-
vi de a J MS servi ce to tire Fl ex cl i ent and these are descri bed next.
11.6 Add t he Act i veMQ Spri ng bean
Ther e's one confi gur ati on detai l you need to tend to. You need to confi gur e tire J MS
pl ugi n to l everage tire Acti veMQ broker. You can do this ei ther by addi ng a Spri ng
bean to the resources.xml or by addi ng the bean usi ng tire Gr oovy DSL approach. The
sni ppet that fol l ows demonstrates addi ng the bean by usi ng tire DSL appr oach of add-
i ng your connecti on factory as a bean i n tire resources.groovy confi gur ati on fi l e
l ocated i n tire gr ai l s- app/ conf / spr i ng fol der of tire appl i cati on.
/ / Pl a c e your Spr i ng D SL c ode her e
bea ns = {
c onnec t i onFa c t or y( or g. a pa c he. a c t i vemq. Ac t i veMQConnec t i onFa c t or y) {
br oker URL = " vm: / / l oc a l host "
}
}
The code shown her e is the Gr oovy way to confi gur e Spri ng beans i n Grails, and
defi nes a connect i onF act or y bean of type Acti veMQConnecti onF actor y and initial-
izes its brokerURL pr oper ty to poi nt at vm: / / l ocal host . Now that you got tire confi gu-
rati on out of tire way you can move on to tweaki ng the Contact domai n class.
c l a ss Cont a c t i mpl ement s Ser i a l i za bl e {
}
To store messages on a message queue the obj ects need to i mpl ement tire S er i al i zabl e
i nterface. You need to update tire Contact class to i mpl ement tire S er i al i zabl e inter-
face as shown previously.
11.7 Subscri be t he Fl ex cl i ent t o t he Grai l s JMS servi ce
Now you'r e ready to confi gur e the Fl ex fr amewor k as a J MS consumer. First you'l l start
wi th the BlazeDS confi gur ati on.
www.it-ebooks.info
Subscribe the Flex client to the GrailsJ MS service 231
11.7.1 Updat e t he servi ces-conf i g.xml
You need to confi gur e Fl ex wi ti i a cont act sTopi c i n di e top-l evel BlazeDS confi gura-
ti on fi l e. When di e Fl ex pl ugi n is i nstal l ed it pl aces di e servi ces- confi g.xml i nsi de di e
/ web- app/ WEB- I NF/ fl ex di rectory. Let's edi t it by addi ng di e Fl ex message servi ce
i nsi de di e services el ement. The ful l servi ces- confi g.xml is i ncl uded i n di e next listing
for clarity and to show tiiat the or der of di e bean defi ni ti ons has si gni fi cance. I nsi de
the services el ement di e Grails servi ce comes first fol l owed by di e J MS confi gur ati on.
Li s t i n g 1 1 . 1 0 s e r v i c e s -c o n f i g . x m l
<?xml ver si on=" 1. 0" enc odi ng=" UTF- 8" ?>
<ser vi c es- c onf i g>
<ser vi c es>
<ser vi c e i d=" gr a i l s- r emot i ng- ser vi c e"
c l a ss=" f l ex. messa gi ng. ser vi c es. Remot i ngSer vi c e" >
<a da pt er s>
<a da pt er - def i ni t i on i d=" j a va - obj ec t "
c l a ss=" f l ex. messa gi ng. ser vi c es. r emot i ng. a da pt er s. J a va Ada pt er "
def a ul t =" t r ue" / >
</ a da pt er s>
</ ser vi c e>
<ser vi c e i d=" gr a i l s- ser vi c e"
c l a ss=" or g. c odeha us. gr oovy. gr a i l s. pl ugi ns. f l ex.
Gr a i l sBoot st r a pSer vi c e" / >
<ser vi c e i d=" messa ge- ser vi c e" I A JMS servi ce
r
c l a ss=" f l ex. messa gi ng. ser vi c es. Messa geSer vi c e"
messa geTypes=" f l ex. messa gi ng. messa ges. Async Messa ge" >
<a da pt er s>
<a da pt er - def i ni t i on i d=" j ms"
c l a ss=" f l ex. messa gi ng. ser vi c es. messa gi ng. a da pt er s. J MSAda pt er "
def a ul t =" t r ue" / > ,
ur
. .
JMS adapt er
</ a da pt er s>
<dest i na t i on i d=" c ont a c t sTopi c " >
<pr oper t i es>
<j ms>
<dest i na t i on- j ndi - na me>c ont a c t s</ dest i nât i on- j ndi - na me>
<messa ge- t ype>j a va x. j ms. Obj ec t Messa ge</ messa ge- t ype>
«c onnec t i on- f a c t or y>Connec t i onFa c t or y</ c onnec t i on- f a c t or y>
<del i ver y- mode>NON_PERSI STENT</ del i ver y- mode>
<messa ge- pr i or i t y>D EFAULT_PRI ORI TY</ messa ge- pr i or i t y>
<a c knowl edge- mode>AUTO_ACKNOWLED GE</ a c knowl edge- mode>
<t r a nsa c t ed- sessi ons>f a l se</ t r a nsa c t ed- sessi ons>
<i ni t i a l - c ont ext - envi r onment >
<pr oper t y>
<na me>Cont ext . PROVI D ER_URL</ na me> y
<va l ue>vm: / / l oc a l host </ va l ue> JMS conf i gur at i on © f
</ pr oper t y>
<pr oper t y>
<na me>Cont ext . I NI TI AL_CONTEXT_FACTORY</ na me>
<va l ue>or g. a pa c he. a c t i vemq. j ndi .
Ac t i veMQI ni t i a l Cont ext Fa c t or y</ va l ue>
</ pr oper t y>
www.it-ebooks.info
232 CHAPTER 11 Flex on Grails
<pr oper t y>
<na me>t opi c . c ont a c t s</ na me>
<va l ue>c ont a c t s</ va l ue>
</ pr oper t y>
</ i ni t i a l - c ont ext - envi r onment >
</ j
ms
> JMS conf i gur at i on ( ]
</ pr oper t i es>
</ dest i na t i on>
</ ser vi c e>
<def a ul t - c ha nnel s>
<c ha nnel r ef =" gr a i l s- a mf " / >
</ def a ul t - c ha nnel s>
</ ser vi c es>
<c ha nnel s>
<c ha nnel - def i ni t i on i d=" gr a i l s- a mf "
c l a ss=" mx. messa gi ng. c ha nnel s. AMFCha nnel " >
<endpoi nt ur l =" ht t p: / / {ser ver . na me}: {ser ver . por t }/ {c ont ext . r oot }/
messa gebr oker / a mf "
c l a ss=" f l ex. messa gi ng. endpoi nt s. AMFEndpoi nt " / >
</ c ha nnel - def i ni t i on>
</ c ha nnel s>
</ ser vi c es- c onf i g>
The bul k of the servi ces- confi g.xml fi l e was gener ated when you i nstal l ed tire Fl ex
pl ugi n; however you need to add a new servi ce secti on for tire J MS servi ce that you'l l
be usi ng Q , and a secti on stating that you'd l i ke tire servi ce to use tire J MS adapter
Q . You also need to confi gur e tire J MS topi c that you'l l be communi cati ng wi th
To see all tire opti ons you've defi ned, r efer to tire BlazeDS user documentati on at
http:/ / l i vedocs. adobe. eom/ bl azeds/ l / bl azeds_devgui de/ . Now let's move on to
modi fyi ng our Cont act Ser vi ce to uti l i ze your messagi ng.
11.7.2 Modi f yi ng t he Cont act Servi ce
The exi sti ng Cont act Ser vi ce class is rel ati vel y si mpl e. Her e is tire updated Cont act -
Ser vi ce class wi th tire addi ti ons for publ i shi ng the updated contact list.
Li s t i n g 1 1 . 1 1 Co n t a c t Se r v i c e u p d a t e d
c l a ss Cont a c t Ser vi c e {
st a t i c expose = [
1
f l ex- r emot i ng
1
]
bool ea n t r a nsa c t i ona l = t r ue
def get Cont a c t s( ) {
r et ur n Cont a c t . l i st ( )
}
def get ( i d) {
r et ur n Cont a c t . get ( i d)
}
def upda t e( Cont a c t c ont a c t ) {
c ont a c t , s a ved 0 publ i shCont act s
publ i shCont a c t s( )
}
J ?
www.it-ebooks.info
Subscribe the Flex client to the GrailsJ MS service 233
def r emove( Cont a c t c ont a c t ) {
c ont a c t . del et e( f l ush: t r ue)
publ i shCont a c t s( )
}
def pr i va t e voi d publ i shCont a c t s( ) {
t r y {
sendPubSubJ MSMessa ge( " c ont a c t s" ,
} c a t c h ( Exc ept i on e) {
l og. er r or ( " Fa i l ed t o publ i sh c ont a c t s. " ,
}
J
get Cont a c t s ( ) ) ;
e) ;
publ i shCont act s
sendPubSubJMSMessage
J
You add di e publ i shCont a c t s ( ) 0 meti i od to publ i sh updates to the topi c you con-
fi gur ed i n di e ser vi c es- c onf i g. xml fi l e. The sendPubSubJ MSMessa ge © takes two
arguments. The fi rst ar gument is di e J ND I desti nati on name defi ned i n your topi c,
and the other is the list of contacts. Next, you wi re up the upda t e and r emove methods
to publ i shCont a c t s when tiiey are i nvoked. Oti i er methods can be cal l ed dependi ng
on your needs. Because a topi c supports di e publ i sh/ subscri be model , it is used for
one- to- many messagi ng whi ch works wel l wi th di e Contacts appl i cati on. For one-to-
one or poi nt- to- poi nt messagi ng you woul d use a queue i nstead. To l earn mor e about
the J MS pl ugi n, visit di e Grails websi te at http:/ / www.grails.org/ J MS- l -Plugin.
11.7.3 Updat e t he Mai n.mxml
The fi nal tiling to do befor e r el aunchi ng di e contacts appl i cati on is to update di e Fl ex
cl i ent mai n. mxml fi l e. You wi l l add di e J MS servi ce to di e mi x and make oti i er mi nor
changes. Let's start wi th di e Appl i c a t i on el ement.
Li s t i n g 1 1 . 1 2 M a i n . m x m l ( e )
<mx: Appl i c a t i on xml ns: mx=" ht t p: / / www. a dobe. c om/ 2006/ mxml "
xml ns: l oc a l =" *"
l a yout =" ver t i c a l "
vi ewSour c eURL=" sr c vi ew/ i ndex. ht ml " creat i onCompl et e
c r ea t i onCompl et e=" c ont a c t Ser vi c e. get Cont a c t s( ) ; j msConsumer . subsc r i be( ) " >
J
<mx: Consumer i d=" j msConsumer "
dest i na t i on=" c ont a c t sTopi c "
messa ge=" ha ndl eGet Cont a c t s( event . messa ge. body) "
f a ul t =" showFa ul t ( event ) " / >
" 4
Consumer
</ mx: Appl i c a t i on>
The Fl ex Consumer obj ect © is used to connect to the c ont a c t sTopi c . When di e
appl i cati on initializes, you need to subscribe to di e c ont a c t sTopi c . To do so you con-
fi gur e di e c r ea t i onCompl et e event defi ni ti on © to call subsc r i be on the j ms-
Consumer . The consumer listens for changes f r om the Acti veMQ br oker and uses di e
www.it-ebooks.info
234 CHAPTER 11 Flex on Grails
ha ndl eGet Cont a c t s method to consume the data. Thi s method updates di e contact
list when tiiere are updates.
F r om here, di e appl i cati on wi l l wor k fi ne as is. Ther e are some thi ngs to cl ean
up because we'r e now maki ng the appl i cati on J MS aware and tiiey are unneces-
sary overhead.
Li s t i n g 1 1 . 1 3 M a i n . m x m l ( f )
pr i va t e f unc t i on del et eCont a c t ( sel ec t edCont a c t : Cont a c t ) : voi d {
c ont a c t Ser vi c e. r emove( sel ec t edCont a c t ) ;
}
pr i va t e f unc t i on upda t eCont a c t ( c ont a c t : Cont a c t ) : voi d {
c ont a c t Ser vi c e. upda t e( sel ec t edCont a c t ) ;
}
<mx: Cont r ol Ba r >
<mx: But t on l a bel =" D el et e Cont a c t "
ena bl ed=" {c ont a c t sGr i d. sel ec t edl t em != nul l }"
c l i c k=" del et eCont a c t ( sel ec t edCont a c t ) " / >
</ mx: Cont r ol Ba r >
You r emove the calls to the get Cont a c t s () method on your Remot eObj ec t when
del et eCont a c t and upda t eCont a c t are i nvoked. These calls wer e necessary, pr i or to
enabl i ng J MS, for di e D a t a Gr i d to be r efr eshed whenever di e contact list was updated.
You can also r emove di e Refr esh button. The Fl ex consumer wi l l get updates every few
seconds and wi l l i nvoke di e meti i od tiiat wi l l update di e D a t a Gr i d so there's no mor e
need for these extra calls to the server side. The consumer itself can be fur ther confi g-
ured i f di ffer ent timing or other opti ons are needed.
To illustrate di e push of i nfor mati on f r om the server to the cl i ent, start di e
Grails appl i cati on by openi ng a command l i ne and navi gati ng to the pr oj ect fol der.
Type di e command gr a i l s r un- a pp, whi ch wi l l start di e embedded j etty contai ner
to run the appl i cati on. Now open two browsers and poi nt them both to the Fl ex
appl i cati on at http:/ / l ocal host:8080/ fl ex- contacts/ mai n.mxml . Then as you make
updates i n the one wi ndow, you shoul d see the contacts bei ng updated i n di e other
browser wi ndow—no mor e havi ng to manual l y refresh di e appl i cati on to pi ck up
other user's changes.
11.8 Summary
I n this fi nal chapter we showed you how to rapi dl y pr ototype data- enabl ed Fl ex
appl i cati ons usi ng Gr oovy and Grails i n combi nati on wi th the Fl ex pl ugi n for Grails.
You started by defi ni ng the domai n i n Grails and exposi ng some services for your
Fl ex appl i cati on to use, and the Fl ex appl i cati on itself. You then went one step fur-
ther and enabl ed your appl i cati on to use J MS and Acti veMQ for real - ti me updati ng
of your UI .
www.it-ebooks.info
index
S ym b o ls
[After]
FlexUnit annotation 197
[Before]
FlexUnit annotation 197
[Bindable] 224
[RemoteClass] 224-225
[Test]
FlexUnit annotation 198, 200
{server.name} 97
{server.port} 97
@Entity 22
@OneToOne annotation 23
©RemotingDestination 102, 140
@RemotingExclude 103
@RemotingInclude 102
@Secured annotation 135
@WebService annotation 24
A
AbstractService 207
AC_OETagsjs 44
Access Control Lists. See ACL
Acegi 10
ACL 123
Action Message Format. See AMF
ActionScript
based on ECMAScript 5
dynamic classes 207
and mc.drawWedge 148
no class declaration 162
properties 75
Active Directory 123
Adobe AI R. Si»AI R
Adobe Integrated Runtime. See AI R
ADT 177
building AI R installer 182
generating a certificate 178
AdvancedDataGrid 53
AI R 6
adding icons 178
application distribution 186
assembly descriptor 182
and Desktop 2.0 11
how application relates to view component 170
packaging 180
properties 179
AI R application
creating 174
differs from Flex application 176
installer 176
AI R Developer Tool. See ADT
AI R installer
creating an assembly 182
security 177
air-app.xml 179
Alert 68, 130, 132, 139
Almost Plain Text. See APT
AMF 10, 91, 228
remote service 103
remoting destinations 102
AMFChannel 109, 113, 117, 125
AMFEndpoint 113
annotations
[After] 197
[Before] 197
[Bindable] 224
[RemoteClass] 225
[Test] 198, 200, 205
235
www.it-ebooks.info
236 I NDEX
Ant
Hudson version 211
AOP 133
pointcut 134
Apache Commons Builder 21
Apache Maven. See Maven
AppFuse 13
BaseAction 29
custom Maven archetypes 17
customizing the menu 30
default application 20
security 137
SiteMesh filter 44
with Spring and Hibernate 20
two users created 132
userDao object 140
Application 45, 173, 225
Application tag
bug in Spark version 174
applicationContext.xml 100
ApplicationResources.properties 33
APT 16
archetypexreate plugin 16
ArrayCollection 73, 162, 203
aspect-oriented programming. SeeAOP
Async.proceedOnEvent 201
asynchronous functionality 197
asynchronous messaging 112
AsyncResponder 68, 74, 79, 130, 142
AsyncToken 69, 79, 104, 130, 209
authentication 124-133
authorization 133-139
Autodesk Project Dragonfly 166
Balsamiq 191
BlazeBench 92
BlazeDS 10,43
adding to POM 93
basic anatomy 92
benchmarking 107
benchmarks 92
configuration 94
configuring 96
connecting to J ava 104
documentation 97
instead of web services 92
logging 105
remoting destinations 101
setting up for messaging 113
setting up logging 106
blazeds-core 93
Bootstrap.groovy 223
Button 55, 77
click 77
c
CA 177
callProperty 207
certificate
self-signed 185
self-signed or digital 177
certificate authority. See CA
ChannelSet 117, 124, 130, 139
ChannelSetFactory 124, 130, 138
creating 117
CI
configuring server 210
questions 210
ComboBox 161
dataProvider 73
selectedltem 77
Comment
data object 66
CommentManager 103, 136
CommentModel
creating 80
updating 85
CommentPresenter
updating 83
comments
editing 83
comments view 54
creating Presenter 77
CommentsListPresenter
creating 77
updating 142
CommentsListView
updating 87
CommentsView 57, 81
See also comments view
common classes
extracting 172
common library
creating 169
CommonsLoggingTarget 105, 107
components
laying out 55
pop-up 57
configurations
sharing 100
console appending 106
ConsoleAppender 106
Consumer 118, 233
ContactService
modifying 232
Continuous Integration. See CI
www.it-ebooks.info
I NDEX 237
ControlBar 53, 77, 81, 221
convention over configuration 13, 220
paradigm 43
ConversionPattern 106
createSlices mediod 158
creationComplete 70, 76, 82, 153
crossdomain.xml 97
CRUD 23
CURRENT_USER_UPDATED 142
CursorManager 68, 79
custom event
creating 63
DAO 13, 24
building 23
Data Access Object. See DAO
data binding 50, 62
in Flex 226
DataGrid 154, 204, 226
dataProvider 68
display tabular data 53
populating 72
DataGridColumn 72
Dégrafa 5, 148
adding dependency on 172
common concepts 149
documentation 150
Pie Chart 150
uses 11
visualization components 165
dependency injection. See DI
detail view
component based off of Panel layout 54
enhancing 72
See also DetailView
DetailPresenter 72
changedlssue 75
savelssue 74
savelssueResult 75
updating 142
DetailView 57
form for updating 53
init 77
updating 76
See also detail view
development environment 13
DI 13
Spring provides 21
-Dmaven.test.skip=true 164
domain classes
creating in Flex 224
Domain Model. See Model
domain specific languages 207
download badge, creating 189
downloadjsp 189
DropShadowFilter 154
dynamic classes 207
dynamic language, dangerous 164
dynamically adding properties 164
ECMAScript 5
EllipticalArc 155
embedSWF 191
endpoint
must be unique 114
event
bubbling 64
dispatching 64
dispatching and handling 63
type 63
Event class 63, 126
addEventListener 78
EventDispatcher 64
addEventListener 67, 73
EventDispatcherFactory 64, 117
include in tests 197
EventFactory 117
exec-maven-plugin 181
FaultEvent 69, 80
Feathers, Michael 61
Fill object 155
Flash Builder 147
Flash Player 10
heart and soul of Flex 6
Flash Player Security
and RPC 97
flashvars 190
Flex
application
porting to a desktop environment 11
building interface 9
configure framework as a J MS consumer 230
connecting to POJ O 102
creating domain classes 224
DataGrid 4
enabling security 132
how application relates to view component 170
integrating with J ava 10
laying out components 55
modifying client for messaging 117
MXML files and ActionScript classes 5
specifying data binding 226
www.it-ebooks.info
238 I NDEX
Flex (continued)
stateful experience 4
vising Degrafa 148
ViewS tack
See ViewS tack
web services 62
Flex 3
open source 5
Flex application
differs from AI R application 176
Flex Data Services 92
Flex Messaging API 112
Flex Mojos 38
See also FlexMojos
Flex SDK 4
free and open source 6
FlexBugs
Maven multimodule project 16
flexbugs.air 184
flexbugsjsp 44
flex-bugs-blaze-config 95
FlexMojos
unit testing support 194,196
flex-spring-servlet.xml 101, 115, 132, 140
FlexUnit 194
asynchronous 205
proceedOnEvent 197
setUp 203
tearDown 207
[Test] annotation 201, 205
testing pitfall 197
FlexUnit4 194
add dependencies 196
FNA 39
FooterView, creating 51
Form 54, 227
Formltem 54, 228
Fowler, Martin 62
functional testing 202
FunFX 202
FXG, Adobe graphics library 149
GenericHibernateDao 23
GenericManager 27
GeometryGroup 149, 154
getlssue
testing 209
global-method-security 138
Glover, Andrew 219
Google Code 190
gradients 150
Grails 11,218
ActiveMQ plugin 229
convention over configuration 220
expose service 222
grails create-domain-class 221
grails create-service 222
install Flex plugin 223
install J MS plugin 230
installing 219
J MS plugin 229
plugins 221
running application 229
graph model
creating 163
See also GraphModel
GraphModel
implementing 163
GraphPresenter 161
GraphView
adding a label and combo box 151
Presenter 161
updating 159
Grigg, Derrick 150
Groovy
much like J ava 2.0 218
specification 11
Group 49, 127, 131, 173
Flex component 155
Growl, Flex application 165
halo components 155
Hamcrest 194, 204
manually install dependencies 196
matcher library 196
HBox 155, 161
HDividedBox 57
header
updating 131
Header.mxml 49, 131
Hello World! 44
Hibernate 20, 24, 36, 225
hibernate.cfg.xml 36
HorizontalLayout 49, 127, 153
HTTPChannel 117
HTTPProxyAdapter 98
HTTPProxyService 97
HTTPService 62,207
Hudson 210-217
configure Maven 211
configuring aj ob 214
email notification 211
installing 211
plugins 210
Humble Dialog Box 61
www.it-ebooks.info
I NDEX 239
I
icons
AI R applications 178
index.template.html 44
installer badge 186
IResponder 69, 76, 104, 198, 209
isNaN 74
Issue 66
IssueManager 137
IssueManagerlmpl 102
IssueModel 70, 208
changing 118
getlssues method 209
updating 75
ItemRenderer 55, 151, 154
for pie chart legend 155
J
J ava
connecting with BlazeDS 104
J ava 2.0 218
J ava Community Process. SeeJ CP
J ava Development Kit. See J DK
J ava Message Service. SeeJ MS
J ava services
exposing to Flex remoting 100
J ava Standard Tag Library. SeeJ STL
J ava Web Archive. See WAR
J AVA_HOME 14
java.lang.OutOfMemoryError 45
J CP 11
J DK 14
installing 14
version 211, 214
J MS 10, 113
configuration 231
jmsConsumer 233
J SON 162
J SR241 11
jsr250-annotations 138
J STL 31
vs. hard coding 190
J Unit 197
J Unit4 194
Law of Demeter 203
layout components 225
layout containers, nesting 55
LDAP 123
Lightweight Directory Access Protocol. See LDAP
List 55, 82
selectedlndex 82
ListEvent 206
LiveCycle Data Services 10
log4j
and BlazeDS 105
configuring for BlazeDS file logging 105
loglj.xml 105
logging 105
affects performance 108
categories 107
login manager
creating 130
login panel
creating 126
LOGI N_BUTTON_PRESSED 129
LoginCommand 135
LoginModel 130, 139
LoginPanel 128
LoginPresenter
updating 141
LoginPresenter class
creating 128
LOGOUT_BUTTON_PRESSED 129
M
M2_HOME 15
Macromedia 3
Main.mxml 45
MainCanvas 172-173, 176
master view
enhancing 66
updating 70
See also MasterView
master/ detail view 46
Master-Detail 219
MasterPresenter 67, 196, 199
getlssues 68
getlssuesResult 68
MasterPresenterTest 196
MasterView 57
creating view component 52
initialize 203
refreshList 72
removeSelectedlssue 72
See also master view
Maven 7
archetype 94
BlazeDS J ARs 93
book 43
build lifecycle 43
convention over configuration 13
dependencies 99, 172, 184, 194
eclipse:eclipse 16
www.it-ebooks.info
240 I NDEX
Maven (continued)
Flex Mojos plugin 38
heap space 45
Hudson version 211
idea:idea plugin 16
installing 15
jetty:run-war 19
mvn archetype-create 39
resources.xml 95
Maven assembly
install and deploy 96
Maven module
building BlazeDS configuration 94
MAVEN_HOME 213
MAVEN_OPTS 45, 215
maven-assembly-plugin 95, 182
maven-clean-plugin 184
maven-dependency-plugin 42, 100, 187
copy-dependencies 44
copy-swf 44
generate-resources 43
process-classes 44
unpack-config 43
maven-resources-plugin 183
Message 119
MessageBroker 115
MessageDestination 115
MessageEvent 118
Message PerformanceUtils 110
messages
pushing 115
MessageService 115
bidirectional messaging 112
MessageTemplate 115
messaging
asynchronous 112
BlazeDS support 92
modifying client for 117
mock testing framework
mock-as3 194
mock-as3
expectations 200
manually install dependencies 196
verify 198
See also Mockolate framework
mockControl 197
Mockery 196
MocklssueService 207-208
Mockolate framework 194
mocks
calls 207
control 207
stricts 198
Model 61, 69
testing 206, 210
Model-View-Controller. See MVC
Model-View-Presenter. See MVP
MouseEvent 205
MVC 28
mvn archetypexreate 174,177
mvn install 45
mvn install:install-file 177
mvn jetty: run-war 36
MVP 9, 193
design pattern
Struts 2 28
Passive View pattern 61
MXML
and ActionScript 5-6
syntax 5
my-polling-amf 114
MySQL 13
create database 15
installing 15
user and password 18
N
navigation components 48
Nexus 96
0
object relational mapping framework 21
object-oriented programming. See OOP
ObjectProxy 66, 68, 80
OOP 4
packages 63
packaging
Flex and J ava similar 49
Panel 70, 76
component 53
Passive View 61-62
PatternLayout 106
performance testing 110
personalization 124, 139-145
pie chart
adding to the application 159
colors in legend 159
creating 150-159
legend 155
model 158
slice
See PieChartSlice
See also PieChart
www.it-ebooks.info
I NDEX 241
PieChart
createSlices 158
model 158
Presenter 156
view 152
PieChart.mxml 152
PieChartEvent 151
PieChartPresenter 164
PieChartSlice 154
plain old J ava object. See POJ O
pointcut 134
POJ O 13
connecting from Flex 102
polling
simple vs. long 114
polling mechanism
selecting 114
POM 13
artifactld 41
configure top-level 98
groupld 41
packaging 41
version 42
pom.xml
flex-bugs 40
flex-bugs-web 42
modules 98
pop-up component 57
PopupManager 85
centerPopUp 85
createPopUp 85
Presenter
for the GraphView 161
Master View 67
testing 196-202
Presenter First 193
project object model. See POM
properties
dynamically adding 164
proxy-config.xml 96-97
Raible, Matt 13
record-message-sizes 110
record-message-times 110
Refresh Issues button
testing click 204
REFRESH_GRAPHS 162
refreshComments 80
RegularRectangle 155
Remote Class 104
RemoteObject 91, 139, 207, 227
instead of WebService 105
RemoteService 206
remoting-config.xml 133
resources.xml 95, 187, 230
RESTful 10, 228
ResultEvent 68-69, 79, 139, 142, 201
RIA 4
rich internet application. See RIA
RichText 8
ROLE_ADMI N 132, 136
ROLEJ J SER 132, 136
RollingFileAppender 105
RPC
and Flash Player Security 97
Scalable Vector Graphics. See SVG
SDK
See also Flex SDK
secured-annotations 138
security
overriding default settings 137
simplest form 124
security constraints
closer to code 134
security.xml 134, 137
Selenium-Flex-API 202
sendPubSubJ MSMessage 233
Serializable 230
interface 21
service
building 24
service-oriented architecture. SeeSOA
services-config.xml 70, 96, 107, 113, 231
set property
testing 203
Shockwave Component. See SWC
SimpleText 50
singleton 65
SiteMesh 44
small web format. See SWF
SmartSVN 172
SMTP server 214
SOA 92
SOAP 10
SOAPProxyAdapter 98
SolidFill 155
Sonatype 14, 177
Nexus 96
Sonatype Maven repository 196
Spacer 50, 155
Spring
framework 20
wiring together with 27
Spring bean
adding to Grails 230
www.it-ebooks.info
242 I NDEX
Spring BlazeDS Integration 98
add schema changes 101
Flex remoting 102
new logging object 105
no remoting-config.xml file 103
reduces complexity 94
Spring Integration Security 135
Spring Security 10, 124, 133
advantage 124
installed on AppFuse 137
SpringSource
Spring Blaze DS Integration 98
streaming, vs. polling 114
StreamingAMFChannel 117
StreamingHTTPChannel 117
strict mocks 198
Stroke
Degrafa object 149
Struts 2 17,28
language support 34
MVC design pattern 28
tag libraries 32
wiring view components 35
stub class 207
Style 8
Subversion 172
Surface 154
base comonent in Degrafa 149
SVG 150
SWC 169
creating a project 170
SWF 5
adding a wrapper 44
associate file with Flash Player 41
swfobject 190
Tamarin 7
target/ surefire-reports 206
TDD
basic workflow 193
Test Driven Development. See TDD
textAlign 51
Thawte 178
TitleWindow 58, 86-87
ToggleButton 50
ToggleButtonBar 48
tweening 150
u
UlComponent 64
UIEvent
data 64
unit testing 192
mock testing framework 194
and TDD 193-194
unit testing framework. See FlexUnit4
USER_LOGGED_I N 142
userDao 138, 140
UserEvent class
creating 125
UserService
adding to LoginModel 140
VDividedBox 57
View
testing 202
ViewStack 47, 57
in login panel 126
navigation 48
w
Walls, Craig 133
WAR 18
Ward, J ames 92
web services
integrating with 9
major styles 62
web.xml 101
WebService 60, 62, 70, 80, 85, 105, 207
destinations 70
loadWSDL 70
wsdl 70, 81
Wikimedia Commons 178
WindowedApplication 176
Winstone 211
wireframe 83, 191
wrapper
HTML 44
www.it-ebooks.info