00001 <?xml version="1.0" encoding="ISO-8859-1"?>
00002
00003 <!-- The JWAA Outer Pages contain the website documentation; the pages
00004 that must be accessible without going through the login portal.
00005 xmlns="http://www.w3.org/1999/xhtml"
00006 xmlns:jwaa="http://virtualschool.edu/jwaa.dtd"
00007 -->
00008 <pages
00009 title="JWAA Web Application Architecture"
00010 >
00011
00012 <page id="OUTER" name="JWAA" requiresRole="none"
00013 title="Java Web Application Architecture (JWAA)"
00014 >
00015 <child idref="INSTALLATION"/>
00016 <child idref="DOCUMENTATION"/>
00017 <child idref="SOURCE"/>
00018 <child idref="CHANGES"/>
00019 <child idref="LICENSE"/>
00020 <child idref="PORTAL"/>
00021
00022 <img align="right" src="/jwaa/pix/mvc.gif" alt="" width="117" height="114"/>
00023
00024 <p>
00025 JWAA is a small but powerful architecture for writing web-based
00026 applications in
00027 <a idref="XHTML">XHTML</a>,
00028 <a idref="Velocity">Velocity</a> and <a idref="Java">Java</a>.
00029 JWAA is portable, <a idref="LICENSE">open source</a> (free)
00030 code that is available for <a href="#download">download here</a>.
00031 </p>
00032
00033 <p>
00034 JWAA features a fully object-oriented approach. Applications
00035 are networks of <i>page</i> objects that reference other pages
00036 via standard object referencing semantics, not with text strings
00037 buried in HTML text. JWAA brings the power of object-oriented
00038 programming to bear on the web.
00039 </p>
00040
00041 <br clear="all"/>
00042
00043 <h2>Reduced Navigation</h2>
00044
00045 <p>
00046 JWAA represents pages as XML files, not as conventional HTML files.
00047 XML's well-known abilities as a general purpose data representation
00048 language are used to express entire web applications in only a few
00049 files. For example, the JWAA website is defined by three XML files:
00050 <a idref="application.xml">application.xml</a>,
00051 <a idref="outerPages.xml">outerPages.xml</a> and
00052 <a idref="innerPages.xml">innerPages.xml</a>.
00053 The number of files is determined your application.xml
00054 file, not by HTML-imposed restrictions.
00055 </p>
00056
00057 <h2>Automatic reloading</h2>
00058
00059 <p>
00060 JWAA monitors all input files for changes and automatically
00061 reloads them when they change. Any errors are reported via
00062 the browser when the XML file is first loaded, not buried
00063 in an obscure log file.
00064 </p>
00065
00066 <h2>Invalid link detection</h2>
00067
00068 <p>
00069 Invalid links are automatically detected and reported when each
00070 application is first loaded. The id of each page is automatically
00071 recorded in a dictionary and can be referenced by idref attributes
00072 as described below. The dictionary can be expanded to add links to
00073 external pages via dictionary elements in the application.xml file.
00074 Dictionary entries are referenced by providing idref attributes
00075 to the usual <a> and <img> XHTML commands.
00076 </p>
00077
00078 <h2>Persistent forms</h2>
00079
00080 <p>
00081 HTML lets you define forms that the user can type information into,
00082 but no way to store or process this information. That requires
00083 installing and learning languages, tools and environments that
00084 bear no resemblance to HTML. The learning process is <i>discontinuous</i>.
00085 </p>
00086
00087 <p>
00088 JWAA supports <a idref="FORMS">persistent forms</a> by default.
00089 Like blackboards or paper, forms retain what the user writes
00090 in them until it is explicitly changed or erased. Persistent forms
00091 are a key building block for building form-based database-centric
00092 applications such as wikis, quizzes, interview forms, and
00093 so forth, often without any custom programming at all.
00094 The default behavior is easily overridden.
00095 </p>
00096
00097 <p>
00098 This feature was developed within the <a idref="ALE">Action Learning
00099 Environment</a>, a JWAA application. It has been ported to JWAA on
00100 as an experiment to investigate whether it makes sense to support
00101 persistent forms at a lower level.
00102 </p>
00103
00104 <h2>Self documenting</h2>
00105
00106 <p>
00107 Other environments provide a bare foundation to build on from
00108 first principles. JWAA provides a finished environment to live
00109 in and learn from while you remodel it to suit. Building a new
00110 application is a matter of copying the application that provides
00111 this tutorial and changing it to suit, learning new skills as you go.
00112 </p>
00113
00114 <h2>Continuous learning</h2>
00115
00116 <p>
00117 Ordinary HTML pages are static data files that are served
00118 by a separate program such as Apache. That's fine until
00119 the pages must support dynamic features when the learning
00120 curve becomes discontinuous since new and unfamilar tools
00121 must be installed and learned (perl or java, servlet
00122 engines, etc).
00123 </p>
00124
00125 <p>
00126 JWAA provides a uniform and comprehensive XML-based environment
00127 in which the transition from static to dynamic pages is continuous.
00128 Simple static pages differ from advanced dynamic ones only in that
00129 they don't use features that the same environment provides.
00130 </p>
00131
00132 <h2>Automatic session management via cookies and/or URL rewriting</h2>
00133
00134 <p>
00135 If the browser supports cookies, JWAA uses them to support session
00136 management. Otherwise JWAA will automatically rewrite all URLs
00137 so that session information is retained when the user clicks
00138 a URL. The code that rewrites URLs is actually provided by
00139 the servlet engine. JWAA's contribution is to guarantee that
00140 all URLs are subject to URL-rewriting, even those that
00141 are buried in hardcoded <a href="..."> strings.
00142 </p>
00143
00144 <h2>Integration <i>and</i> Separation of Concerns</h2>
00145
00146 <p>
00147 JWAA supports both. When used with the
00148 <a idref="Java+">Java+ preprocessor</a>, HTML is written as
00149 Java+ strings so that presentation and logic are combined
00150 and executable inclusions are expressed in plain Java.
00151 The HTML can also be written as XML (XHTML) files and
00152 automatically reloaded when they change, with executable
00153 inclusions written in <a idref="Velocity">Velocity</a>.
00154 Since <a idref="Java+">Java+</a> now has its own web site,
00155 this site will emphasize the XML-based approach.
00156 </p>
00157
00158 <h2>Consistent Look and Feel</h2>
00159
00160 <p>
00161 Navigation bars, background colors, and headers/footer
00162 information on this and all other pages in this website
00163 constitute this application's look and feel. The look
00164 and feel is defined by <a idref="Velocity">Velocity</a>
00165 macros such that the look and feel is centrally defined
00166 and easily changed. These macros are, by default,
00167 automatically reloaded when the file that defines
00168 them is changed.
00169 </p>
00170
00171 <h2>Model-View-Controller Paradigm plus Fields</h2>
00172
00173 <p>
00174 JWAA pages are objects that supports a user's interaction with
00175 internal objects, called Models (or JavaBeans). Model objects
00176 manage the application's persistent state, typically but not
00177 necessarily as records in a database. By convention, model
00178 objects' fields are not primitive Java datatypes like Strings.
00179 Rather <b>fields</b> are the atoms from which models are composed.
00180 Fields encapsulate the logic for validating user inputs, reporting
00181 any problems by collaborating via the user interface. Fields are an
00182 unusually powerful unit of reuse because they are tangible, concrete
00183 and highly visible right in the application's user interface.
00184 JWAA includes a comprehensive library of ready-to-use fields for
00185 building model objects in Java.
00186 </p>
00187
00188 <h2>Small, Fast, Secure</h2>
00189
00190 <p>
00191 With Java+, applications are constructed entirely at compile
00192 time and are remarkably small. JWAA's core functionality (minus
00193 documentation and demos) is only 67kb while JSP is many times
00194 larger. No compilers are needed on deployment servers, so speed,
00195 space and security are substantially improved.
00196 </p>
00197
00198 <h2>Open Source</h2>
00199
00200 <p>
00201 JWAA is <a idref="LICENSE">open source</a> (free) software, written
00202 entirely in Java so it is automatically portable to any platform.
00203 </p>
00204
00205 <a name="download"></a>
00206 <h2>Download Instructions</h2>
00207
00208 <p>
00209 The JWAA distribution is <a href="/jwaa/jwaa.tgz">jwaa.tgz</a>.
00210 This is a gzipped tar file with the documentation, sources, compiled
00211 binary, plus all required libraries except for four prerequisites
00212 that can be downloaded from the provided links.
00213 </p>
00214
00215 <ul>
00216 <li>Web server (<a idref="Apache">Apache</a>)</li>
00217 <li>Relational Database (<a idref="MySQL">MySQL</a>)</li>
00218 <li>Java Software Development Kit (<a idref="Java">java.sun.com</a>)</li>
00219 <li>Servlet engine (<a idref="Jetty">Jetty</a> or <a idref="Tomcat">Tomcat</a>).</li>
00220 </ul>
00221
00222 <p>
00223 See the <a idref="INSTALLATION">installation instructions</a>
00224 for how to proceed once you have the prerequisite software.
00225 </p>
00226
00227 <h2>JWAA Applications</h2>
00228
00229 <p>
00230 <a idref="Mybank">Mybank</a> is an ambitious digital rights
00231 management system based on <a idref="JWAA">JWAA</a> and
00232 <a idref="Java+">Java+</a>.
00233 </p>
00234
00235 <p>
00236 <a idref="ALE">ALE</a> (Action Learing Environment) pioneered the
00237 XML-based approach that was subsequently absorbed into its JWAA
00238 substrate.
00239 </p>
00240
00241 <p>
00242 <a idref="ILE">ILE</a> (Interactive Learning Environment) is
00243 an ancestor of ALE that involved porting JWAA from Java to Ruby.
00244 This project is now inactive because a servlet engine problem
00245 that surfaced during the move to a new collocation provider.
00246 </p>
00247
00248 </page>
00249
00250 <page id="DOCUMENTATION" name="Documentation" requiresRole="none"
00251 title="Building web applications with JWAA" >
00252 <child idref="APPLICATIONS"/>
00253 <child idref="LOOKANDFEEL"/>
00254 <child idref="FORMS"/>
00255 <child idref="VELOCITY"/>
00256 <child idref="JAVA"/>
00257
00258 <p>
00259 This documentation is divided into sections according to
00260 different levels of programming expertise:
00261 </p>
00262
00263 <ol>
00264
00265 <li>
00266 <a idref="APPLICATIONS">Application Builders</a> write the
00267 static HTML content of an application by authoring them
00268 in XHTML gathered into Jwaa's XML format.
00269 </li>
00270
00271 <li>
00272 <a idref="LOOKANDFEEL">Look and Feel Specialists</a>
00273 define the look and feel for an application by revising the Velocity
00274 macros and CSS (Cascading Style Sheets) that are provided.
00275 </li>
00276
00277 <li>
00278 <a idref="VELOCITY">Interaction Specialists</a>
00279 make pages interactive by adding statements in the Velocity
00280 programming language.
00281 </li>
00282
00283 <li>
00284 <a idref="JAVA">Java Programmers</a>
00285 use this section for extending the Java backend of this system.
00286 </li>
00287
00288 </ol>
00289
00290 </page>
00291
00292 <page id="APPLICATIONS" name="Applications" requiresRole="none"
00293 title="Building a new JWAA Application" >
00294
00295 <p>
00296 JWAA is capable of running multiple applications simultaneously.
00297 Each application is defined by its own sub-directory of the
00298 jwaa/root directory. Each application directory is required to
00299 provide a <a idref="application.xml">application.xml</a> file
00300 that points to the other files that make up that application.
00301 </p>
00302
00303 <h2>The root/applicationName directory</h2>
00304
00305 <p>
00306 For example, the pages you're reading now are provided by a JWAA
00307 application named "jwaa". This application is defined by the
00308 root/jwaa directory. To build a new application, you simply
00309 copy the root/jwaa directory to a new name and modify its contents
00310 to be what you need. Don't change the jwaa directory. Leave that
00311 as it is to keep it is available for reference.
00312 </p>
00313
00314 <p>
00315 The directory name determines the internal id of the application
00316 which determines the applicaton's URL. The first two components of
00317 the url are defined by WEB-INF/web.xml as jwaa/xml. The third
00318 component is application id, which is determined by the root
00319 subdirectory name. This tutorial is stored in root/jwaa, so the
00320 tutorial application's id is jwaa. Thus the jwaa tutorial's full
00321 URL is http:
00322 </p>
00323
00324 <p>
00325 These conventions are entirely governed by configuration files
00326 (typically etc/httpd/conf/httpd.conf and jwaa/WEB-INF/web.xml)
00327 so they can be easily changed according to the usual web server
00328 and servlet engine conventions. To simplify this discussion,
00329 these documents assume that the default settings are used.
00330 </p>
00331
00332 <h2>application.xml</h2>
00333
00334 <p>
00335 Right click on <a idref="application.xml">this link</a>
00336 to open jwaa/root/jwaa/application.xml in a new browser window.
00337 Notice that it specifies other files in the application's root
00338 directory.
00339 </p>
00340
00341 <p>
00342 Notice that application.xml specifies two pages elements
00343 with the ids outer and inner. The path attribute of these
00344 elements specify the two files that define the jwaa application,
00345 outerPages.xml and innerPages.xml. This discussion will be
00346 concerned with outerPages.xml which defines the pages
00347 you're reading now. The other involves interactive features
00348 that will be described separately.
00349 </p>
00350
00351 <p>
00352 Each application's directory is contains an
00353 <a idref="application.xml">application.xml</a> file that
00354 specifies where other application components are stored. Open
00355 that file now (right click to open it in a separate browser window).
00356 Notice that three lines at the top specify the files that define
00357 the JWAA documentation and the tutorial demonstration application.
00358 </p>
00359
00360 <p>
00361 The macros element specifies the name of the file that defines
00362 the velocity macros (we'll be concerned with these in the
00363 next section), and the role element(s) designate the login ids
00364 that are able to access special administrative pages that
00365 are invisible (and unreachable) by ordinary users. We'll
00366 describe those after we cover how ordinary static HTML
00367 content pages are defined.
00368 </p>
00369
00370 <h2>Content Pages</h2>
00371
00372 <p>
00373 Traditional pages are HTML files. Jwaa pages, by contrast, are
00374 defined as elements inside XML files. Unlike HTML, each XML file
00375 file can define any number of pages. The jwaa tutorial application
00376 is defined by precisely two such files:
00377 </p>
00378
00379 <ul>
00380
00381 <li>
00382 <a idref="outerPages.xml">outerPages.xml</a> defines
00383 the pages you're reading now. They are "outer" in the sense that they
00384 lie outside of the demonstration application's login procedure.
00385 </li>
00386
00387 <li>
00388 <a idref="innerPages.xml">innerPages.xml</a> defines
00389 the pages of the demonstration application. These are "inner"
00390 in the sense that they cannot be accessed without registering
00391 and logging in to the demonstration application. Most of these
00392 pages involve forms processing and will be described separately,
00393 under <a idref="FORMS">Forms Processing</a>.
00394 </li>
00395
00396 </ul>
00397
00398 <p>
00399 Which pages are defined in which files is arbitrary and entirely
00400 up to the author's discretion. There is no significance to which
00401 XML file a page is defined in. Page identifiers are maintained in
00402 a single name space for each application, and the pages of that
00403 application can reference each other freely, without concern for
00404 which file they originated in.
00405 </p>
00406
00407 <p>
00408 For example, open <a idref="outerPages.xml">outerPages.xml</a>
00409 (right-click to open it in a separate window so you can continue
00410 reading these instructions).
00411 Notice that consists of a single large <pages>...</pages>
00412 (plural) element, that contains many <page>...</page>
00413 (singular) elements, each of which defines three attributes:
00414 </p>
00415
00416 <ul>
00417
00418 <li>
00419 id: This is a string that will identifies the page to other pages.
00420 I recommend using uppercase identifiers to make them easy to find
00421 with string searches.
00422 </li>
00423
00424 <li>
00425 name: This is the short name of the page as far as the end-user
00426 is concerned. It is visible in navigational menus, so keep it short
00427 and meaningful.
00428 </li>
00429
00430 <li>
00431 title: A longer string that will be presented at the top of each
00432 page as a <h1> header, and also as a title="" attribute in
00433 menu bars (which some browsers will present as a non-standard but
00434 useful rollover effect).
00435 </li>
00436
00437 </ul>
00438
00439 <p>
00440 The text within each page element is what'd normally goes in an
00441 XHTML <body> element. The main difference is that they are
00442 XHTML commands, not HTML commands. They must comply with the
00443 XHTML syntax requirements which are similar to HTML, but far
00444 more strict. These differences are described <a idref="XHTML">here</a>.
00445 </p>
00446
00447 <h2>Building a new application</h2>
00448
00449 <p>
00450 To build a new application, copy an existing one and modify it
00451 to suit. So begin by copying jwaa/root/jwaa to jwaa/root/myapp.
00452 In your browser's location bar, replace the second jwaa with myapp
00453 and click reload. There will be a short delay as Jwaa loads the XML
00454 files into memory, the page you're reading now will appear.
00455 Click reload and notice that the page reloads much faster.
00456 The JWAA servlet continually watches the root directory for
00457 new arrivals, so new arrivals are automatically on the air.
00458 </p>
00459
00460 <p>
00461 Open jwaa/root/myapp/outerPages.xml in your text editor
00462 and search for the string <code>id="APPLICATIONS"</code>, which
00463 defines the page you're reading now. Insert a word or two in the
00464 first paragraph, save the file, and click reload. Notice that
00465 the change appears in your browser window after a much shorter delay
00466 since only one file had to be reloaded for this change.
00467 </p>
00468
00469 <h2>Correcting errors</h2>
00470
00471 <p>
00472 The biggest difference between HTML and XHTML is that XHTML
00473 imposes strict syntax requirements. To see this in action,
00474 use your text editor to damage the file slightly (for example, by
00475 deleting the opening <p>). Save the result (but don't exit
00476 your text editor), and click reload in your browser. The browser
00477 provides an error message pinpointing the error and requiring
00478 you to fix it. Use your editor's undo function to repair
00479 the damage and reload the page in your browser to verify that
00480 the page now loads fine.
00481 </p>
00482
00483 <h2>Required Pages</h2>
00484
00485 <p>
00486 The only requirement JWAA does impose is that each application
00487 must define certain pages that the hard-coded part of the system
00488 refers to. These required identifiers are:
00489 </p>
00490
00491 <ol>
00492
00493 <li>
00494 OuterHomePage: The outer home page for the application as a whole.</li>
00495
00496 <li>
00497 InnerHomePage: The inner home page. The first page a visitor
00498 sees when they pass the login procedure.
00499 </li>
00500
00501 <li>
00502 PortalPage: The login and registration initiation page.
00503 </li>
00504
00505 <li>
00506 NotFoundPage: A page to be displayed if a requested page is not
00507 found, for example, if the user mistyped the URL.
00508 </li>
00509
00510 <li>
00511 RefusePage: A page to be displayed if the user requests a page
00512 their role doesn't allow them to see.
00513 </li>
00514
00515 </ol>
00516
00517 <p>
00518 Workable versions of these pages are all defined in innerPages.xml
00519 and will not concern us further here.
00520 </p>
00521
00522 <h2>Optimizing for Production</h2>
00523
00524 <p>
00525 The outer pages of an application don't usually change very often
00526 after they've been tested and installed, certainly not compared to
00527 inner pages that might be computed almost entirely on the fly.
00528 Furthermore outer pages are typically the ones you want to be
00529 picked up and cataloged by search engines, unlike the inner ones.
00530 </p>
00531
00532 <p>
00533 There are no firm rules as to which pages should be served dynamically,
00534 via the JWAA/Jetty servlet engine, versus which should be served
00535 statically by a web server. The practice I follow is to periodically
00536 save the application's OuterHomePage (dynamically generated) into
00537 an index.html file in the application's root directory, and to have
00538 all other pages refer to this static page instead of its dynamic
00539 address.
00540 </p>
00541
00542 <p>
00543 For example, the dynamic version of JWAA's own home page is
00544 http:
00545 is picked up by search engines, and is served as a static web
00546 page by the apache web server. The same page is also accessible
00547 as a dynamically generated page at
00548 http:
00549 version (index.html) is derived from the dynamic version by
00550 simply using the browser's saveAs function to update the static
00551 version when the dynamic version changes.
00552 </p>
00553
00554 </page>
00555
00556 <page id="LOOKANDFEEL" name="Look And Feel" requiresRole="none"
00557 title="Defining the application's Look and Feel"
00558 >
00559
00560 <p>
00561 An application's look and feel is governed by the velocity.macros
00562 file in the top level directory
00563 of your application, plus any the CSS (Cascading Style Sheet)
00564 definitions that the macros use, which are typically stored in
00565 your application's css directory in the same location.
00566 </p>
00567
00568 <p>
00569 For example, see the \#defaultLogic() and \#header macros in
00570 <a idref="velocity.macros">velocity.macros</a>.
00571 Controller automatically inserts calls to these at the
00572 beginning of each page's text and a call to the \#footer()
00573 macro at the end. Velocity simply replaces the call statements
00574 with the text defined in the macros.
00575 </p>
00576
00577 <p>
00578 Make experimental changes to these macros (keep them simple for
00579 now) and reload the browser to observe the effect. Then browse
00580 several pages and notice that changes to these macros have global
00581 effects, automatically propagating to every page in your application.
00582 </p>
00583
00584 <p>
00585 Notice that the \#header() macro includes a <link command
00586 that tells the browser to load css/innerPage.css and
00587 css/print.css. These define additional page markup conventions
00588 that I also rely on to further adjust the application's look and
00589 feel. CSS markup is a separate topic that I'm still learning
00590 myself. See the Reference list for more information on CSS.
00591 </p>
00592
00593 <h2>References</h2>
00594
00595 <ol>
00596
00597 <li>
00598 <a href="http://jakarta.apache.org/velocity/user-guide.html">
00599 Velocity User's Guide</a> is the most relevant.
00600 </li>
00601
00602 <li>
00603 <a href="http://www.w3schools.com/css/default.asp">CSS
00604 Tutorial</a> by W3Schools.
00605 </li>
00606
00607 </ol>
00608
00609 </page>
00610
00611 <page id="FORMS" name="Forms" requiresRole="none"
00612 title="Persistent Forms" >
00613
00614 <p>
00615 Forms are defined with the usual XHTML form, input and select
00616 statements... with important differences stemming from the
00617 need to not only define the form presentation (as in XHTML),
00618 but also logic for processing that form once submitted.
00619 </p>
00620
00621 <p>
00622 Persistent form support is under development and rapidly changing.
00623 I'll upgrade this documentation as the design stabilizes. See the
00624 PORTAL and UPDATE pages of <a idref="innerPages.xml">innerPages.xml</a>
00625 for how to code forms in the traditional (manual) way within JWAA.
00626 </p>
00627
00628 <h2>Persistent Form Example</h2>
00629
00630 <p>
00631 See the FORMS element in <a idref="outerPages.xml">outerPages.xml</a>
00632 for this test case for the persistent forms feature.
00633 </p>
00634
00635 <form id="DEMO_FORM">
00636 <logic>
00637 #set($op = $form.getValue("op"))
00638 #if ($op)
00639 $form.save()
00640 #if ($op eq "Prev")
00641 $self.gotoPage($self.getPrevPage().getId())
00642 #elseif ($op eq "Next")
00643 $self.gotoPage($self.getNextPage().getId())
00644 #end
00645 #end
00646 </logic>
00647
00648 <table align="center">
00649 <tr>
00650 <td>Text Fields </td>
00651 <td>
00652 <input name="textField" type="text" />
00653 </td>
00654 </tr>
00655 <tr>
00656 <td>Password Fields </td>
00657 <td>
00658 <input name="passwordField" type="password" />
00659 </td>
00660 </tr>
00661 <tr>
00662 <td>Radio Selection Fields </td>
00663 <td>
00664 <input name="radioFieldName" value="Yes" type="radio"/> Yes
00665 <input name="radioFieldName" value="No" type="radio"/> No
00666 <input name="radioFieldName" value="Maybe" type="radio"/> Maybe
00667 </td>
00668 </tr>
00669 <tr>
00670 <td>Checkbox Fields </td>
00671 <td>
00672 <input name="checkboxField" value="Yes" type="checkbox"/> Yes
00673 <input name="checkboxField" value="No" type="checkbox"/> No
00674 <input name="checkboxField" value="Maybe" type="checkbox"/> Maybe
00675 </td>
00676 </tr>
00677 <tr>
00678 <td>Single Selection Fields</td>
00679 <td>
00680 <select name="singleSelectionField">
00681 <option>Yes</option>
00682 <option>No</option>
00683 <option>Maybe</option>
00684 </select>
00685 </td>
00686 </tr>
00687 <tr>
00688 <td>Multiple Selection Fields </td>
00689 <td>
00690 <select name="multipleSelectionField" multiple="multiple">
00691 <option>Yes</option>
00692 <option>No</option>
00693 <option>Maybe</option>
00694 </select>
00695 </td>
00696 </tr>
00697 <tr>
00698 <td> Text Area Fields </td>
00699 <td>
00700 <textarea name="textareaField" rows="2" cols="15"></textarea>
00701 </td>
00702 </tr>
00703 <tr>
00704 <td>Submit Buttons </td>
00705 <td>
00706 <input name="op" value="Prev" type="submit"/>
00707 <input name="op" value="Save" type="submit"/>
00708 <input name="op" value="Next" type="submit"/>
00709 </td>
00710 </tr>
00711 </table>
00712
00713 </form>
00714
00715 <p>
00716 To try it, change the field contents, click one of the Submit
00717 buttons and notice that the changes persist when you return,
00718 just as the information on paper remains when you look at it later.
00719 </p>
00720
00721 <p>
00722 If the server is heavily loaded, what you see depends on
00723 whether you've logged (via the <a idref="PORTAL">Demo login screen</a>).
00724 Visitors who haven't logged in share the same account and
00725 their modifications to persistent forms affect the same
00726 database records, so persistent form contents will be as
00727 the last visitor set them. So if you're not logged in,
00728 persistent forms behaves like blackboards that can be
00729 read, written on, or erased by anyone that walks by.
00730 If you have logged in, forms behave like paper that is
00731 under your sole control. We assume both cases are
00732 potentially useful.
00733 </p>
00734
00735 <p>
00736 The contents of each field persist as records in a relational
00737 database (MySQL) keyed with the page id, the field name, and
00738 the user's ID. Users who have not logged in via the
00739 <a idref="PORTAL">Demo login screen</a> share the same account
00740 and have concurrent access to the same database fields. JWAA
00741 does not prevent such users from overwriting each other's work
00742 on the grounds that blackboards and paper have the same liability
00743 but are still useful in education.
00744 </p>
00745
00746 <p>
00747 The persistence feature applies only to form elements that
00748 do <i>not</i> define explicit values. It does not apply
00749 to text or password fields with value attributes, to checkbox,
00750 radio, and select fields with checked attributes and so forth).
00751 It can be turned off in forms that should not be persistent
00752 (login screens and so forth) by simply defining explicit values.
00753 </p>
00754
00755 <h2>Unresolved Issues</h2>
00756
00757 <p>
00758 I'm eager to support persistence at the lowest architectural
00759 level because persistent forms are such a powerful unit of
00760 reuse... for exactly the same reasons that paper and blackboards
00761 are so useful in education. They are lowest-level building blocks
00762 that support many concrete interactive applications. I've
00763 supported them experimentally to validate the truth of this
00764 claim in practice.
00765 </p>
00766
00767 <p>
00768 By contrast, <a idref="ALE">ALE</a> provides workflow features
00769 that model the paper workflow in classrooms. The instructor develops
00770 quizzes and passes them to students, who write answers on them and
00771 return them to the teacher, who grades them and returns them to students
00772 to read the teacher's feedback. ALE's support for such workflow
00773 has not been ported to JWAA because that is clearly inappropriate
00774 at JWAA's level.
00775 </p>
00776
00777 <p>
00778 I'm not sure of where to draw this boundary. So the persistent
00779 forms feature has been added provisionally. The goal is to
00780 investigate whether persistent forms belong at the JWAA level
00781 in the absence of ALE's workflow support. If not, I'll
00782 remove it from JWAA and support it only within ALE.
00783 </p>
00784
00785 <p>
00786 I'm not entirely satisfied with how navigational controls (the Prev,
00787 Save, and Next buttons in this example) are handled. ALE provides
00788 these automatically and consistently as part of its workflow
00789 support, so no effort is needed to present them everywhere they
00790 are needed. This can't be done at JWAA's level since the default
00791 navigational controls would clash with the user's page design.
00792 </p>
00793
00794 <p>
00795 I welcome other opinions on these issues. Share them via email with
00796 <a href="mailto:bcox@virtualschool.edu">bcox@virtualschool.edu</a>.
00797 </p>
00798
00799 </page>
00800
00801 <page id="VELOCITY" name="Velocity" requiresRole="none"
00802 title="Programming with Velocity">
00803
00804 <p>
00805 Velocity is a language for accessing objects provided
00806 to it by the Java part of the system. The following objects
00807 are automatically available to velocity code via velocity's
00808 "context". For further information see the
00809 <a idref="ObjectReferenceManual">ObjectReferenceManual</a>.
00810 </p>
00811
00812 <dl>
00813
00814 <dt>\$self</dt>
00815
00816 <dd>
00817 \$self provides access to the <a idref="Controller">Controller</a>
00818 for the page that is currently being displayed. The controller
00819 provides methods that velocity scripts use to access other objects
00820 in the page's neighborhood, such as
00821 the <a idref="PageElement">PageElement</a> that defines this page,
00822 the <a idref="PagesElement">PagesElement</a> in which this page
00823 was defined,
00824 the page's <a idref="ApplicationElement">ApplicationElement</a>,
00825 and more.
00826 </dd>
00827
00828 <dt>\$account</dt>
00829
00830 <dd>
00831 \$account provides access to information about the account
00832 that is currently logged in. From this you can determine
00833 their name, address, phone number, and similar information
00834 from the registration procedure.
00835 </dd>
00836
00837 <dt>\$dbms</dt>
00838
00839 <dd>
00840 Each application maintains a pool of connections to the
00841 application's database as a <a idref="DBPool">DBPool</a>
00842 instance. The controller automatically withdraws a database
00843 connection (a <a idref="DB">DB</a> instance) from the pool
00844 and makes that instance available to velocity code as the
00845 $dbms context variable.
00846 </dd>
00847
00848 <dd>
00849 Your code can use this variable to access the database by
00850 calling the public methods that DB provides for this purpose.
00851 The controller automatically either commits any transactions
00852 that finish successfully (and rolls back those those that
00853 fail; i.e. those that throw exceptions). Finally it returns
00854 the DB instance to the pool for reuse.
00855 </dd>
00856
00857 <dt>$form</dt>
00858
00859 <dd>
00860 The $form variable is null if the page contains no <form>
00861 element and an instance of <a idref="FormElement">FormElement</a>
00862 if it does. This may change in future releases such that form
00863 elements can be accessed via the \$self or \$self.page variables.
00864 </dd>
00865
00866 </dl>
00867
00868 <h2>Velocity Hints</h2>
00869
00870 <p>
00871 Velocity statements like \$self.application don't access
00872 the Controller's "application" field directly. Velocity
00873 automatically treats such statements as if written
00874 \$self.getApplication(), which calls the Controller's
00875 getApplication() method to return the value. In other
00876 words, fields are never accessed by Velocity code,
00877 only methods, and then only those methods that
00878 are explicitly public.
00879 </p>
00880
00881 <p>
00882 But always remember that methods are general-purpose functions
00883 that can (and often do) make permanent changes to their environment.
00884 Such methods are said to have <i>side-effects</i>. This is actually
00885 quite useful, for it is how velocity scripts affect their environment.
00886 </p>
00887
00888 </page>
00889
00890
00891 <page id="JAVA" name="Java" requiresRole="none" title="Java Programmer's Guide" >
00892 <child idref="OVERVIEW" />
00893 <child idref="MODELS" />
00894 <child idref="FIELDS" />
00895 <child idref="ROLES" />
00896
00897 <p>
00898 Simple JWAA websites can be built entirely in XML and Velocity, without
00899 exploring the Java end of this system more deeply than reading the
00900 <a idref="ObjectReferenceManual">ObjectReferenceManual</a> for Java
00901 class descriptions. However the Java source code must be documented
00902 for those who wish to explore it. And some things, such as extending
00903 the system with new persistent objects, are only really practical in
00904 Java.
00905 </p>
00906
00907 <h2>Prerequisites</h2>
00908
00909 <p>
00910 Begin by downloading and installing the following tools from the
00911 specified links:
00912 </p>
00913
00914 <ol>
00915
00916 <li>
00917 <a idref="Eclipse">Eclipse</a>: Eclipse is the main tool for
00918 reading Java source code, making changes, correcting mistakes,
00919 compiling source code to executable class files, debugging
00920 running programs, and viewing data structures
00921 while the program is running. The best version to download
00922 is version 2.1.1: the later "milestone" versions are too
00923 buggy to count on in my experience. Also avoid plugins:
00924 they are even more problematic than eclipse.
00925 </li>
00926
00927 <li>
00928 <a idref="Ant">Ant</a>: Ant is a command line tool that is
00929 used for everything Eclipse doesn't do: compiling documentation
00930 from source code (via doxygen), building jar files from
00931 individual class files, copying files from the build directory
00932 to the deployment directory, maintaining backup copies,
00933 building distribution (.tgz) files, and so forth.
00934 </li>
00935
00936 </ol>
00937
00938 <p>
00939 Install ant and eclipse where ever you please (I use /opt)
00940 and make scripts to launch them conveniently. Here's the script
00941 I use for launching eclipse (the Fixme comment marks
00942 two lines to edit to suit your system).
00943 </p>
00944
00945 <pre>
00946 #!/bin/sh
00947
00948 # Fixme
00949 ECLIPSE_DIR=/opt/eclipse-2.1.1
00950 WORKSPACE_DIR=~/workspace
00951
00952 # Launch eclipse
00953 cd $WORKSPACE_DIR
00954 $ECLIPSE_DIR/eclipse -data $WORKSPACE_DIR $* &
00955 echo $ECLIPSE_DIR starting ...
00956 </pre>
00957
00958 <p>
00959 The WORKSPACE_DIR line overrides eclipse's annoying behavior
00960 of creating a default workspace inside eclipse's program
00961 directory. "Workspace" in eclipse's term for the directory
00962 that it uses to store <b>your</b> source code. Its not eclipse's
00963 code, its <b>yours</b>, and you want to control where its stored
00964 rather than leaving that up to eclipse. My preference is for the
00965 workspace to be in my home directory which is where the default
00966 settings in the above script puts it.
00967 </p>
00968
00969 <h2>Importing JWAA into Eclipse</h2>
00970
00971 <p>
00972 Launch eclipse, pull down the Window menu, and choose
00973 Preferences. Click the triangle by Java in the left panel
00974 to open it, click Compiler, and select the "Folders" option
00975 under "Source and output folder". Leave the default source
00976 folder name ("src") and output folder name ("bin") as they
00977 are. Click "OK". Eclipse will now create new projects with
00978 src and bin folders, which matches the convention I'll use in
00979 this document.
00980 </p>
00981
00982 <p>
00983 Right click in the left panel (Package Explorer) and click
00984 "New Project". Choose "Java" in the popup panel and click Next.
00985 Type "JWAA" as the project name and click Finish. JWAA will now
00986 appear in the left panel as a new but empty project.
00987 </p>
00988
00989 <p>
00990 Right click on the JWAA project in the left pane and choose
00991 Import. Browse to the installed copy of JWAA, double-click it
00992 and JWAA should appear in the left pane with an empty checkbox.
00993 Eclipse is somewhat unreliable here; often the left pane doesn't
00994 change when you select a directory. Clicking the back button and
00995 advancing with the Next button appears to resolve it. Once JWAA
00996 appears in the left panel with the empty checkbox, click the
00997 checkbox to select it and click finish. A red checkbox signifying
00998 compile errors will appear in the left panel. The errors are OK:
00999 you haven't defined libraries yet.
01000 </p>
01001
01002 <p>
01003 Right-click on the imported project and choose Properties. In the
01004 left panel of the window that appears, click "Java Build Path".
01005 Select the Libraries pane and click "Add Jars". Click JWAA,
01006 then WEB-INF, then lib, and drag-select all of the jar files
01007 that are offered there. Click OK. A few errors will remain
01008 because you've not provided the servlet engine's libraries yet.
01009 </p>
01010
01011 <h2>Importing Jetty into Eclipse</h2>
01012
01013 <p>
01014 Repeat all of the above steps to import Jetty into a separate
01015 "Jetty" project in your workspace. Use "Add Jars" in the Jetty
01016 project until Jetty compiles without errors. Right-click on your
01017 JWAA project, choose Properties again, and this time select the
01018 "Projects" tab. Checkboxes for the JWAA and Jetty projects should
01019 appear there. Select the checkbox next to the Jetty project to
01020 specifies that Eclipse should use the bin directory of the Jetty
01021 project to resolve unsatisfied references in addition to the jar
01022 files you specified earlier. JWAA should build now without errors
01023 and the red mark in the left pane will disappear.
01024 </p>
01025
01026 <p>
01027 Recall that Jetty refers to symbolic links (or outright copies)
01028 in its webapps subdirectory to determine which servlets it should
01029 load, and it expects each such link (or copy) to contain a WEB-INF
01030 directory. When Eclipse copied Jetty to its workspace, it copied
01031 Jetty's webapps directory along with the symbolic link you made earlier.
01032 This link points to the original copy of JWAA in the document root
01033 directory. You want this copy of Jetty to load files from the
01034 copy of JWAA in your workspace. So delete the jwaa copy and replace
01035 it with a new symbolic link to the JWAA in your workspace
01036 directory, like this:
01037 </p>
01038
01039 <pre>
01040 cd ~/workspace/Jetty/webapps
01041 # notice the old jwaa copy
01042 ls -l
01043 # remove the old jwaa copy
01044 rm -rf jwaa
01045 # create a symbolic link to workspace/jwaa
01046 ln -s ~/workspace/jwaa/ jwaa
01047 </pre>
01048
01049 <p>
01050 Jetty will load jar files from the WEB-INF/lib directory and
01051 individual class files from the WEB-INF/classes directory.
01052 The WEB-INF/lib directory already contains a copy of the
01053 jwaa.jar that came with the distribution. Since you'll be
01054 making changes to the jwaa source code, you want the changed
01055 versions to be loaded, not the original distributed version.
01056 The simplest way to ensure this is to create a symbolic link,
01057 named classes, in the WEB-INF directory that points to the
01058 bin directory in which Eclipse stores its generated files,
01059 like this:
01060 </p>
01061
01062 <pre>
01063 cd ~/workspace/jwaa/WEB-INF
01064 ln -s ../bin classes
01065 </pre>
01066
01067 <h2>Launching Jetty from inside Eclipse</h2>
01068
01069 <p>
01070 Back to Eclipse now. Pull down the Run menu, choose
01071 Debug, and a window will appear. Under Main, in the
01072 Project area, click the Browse button and select the
01073 Jetty project. In the "Main class" area, choose Search,
01074 and select org.mortbay.start.Main as the main routine
01075 Eclipse should invoke to launch Jetty.
01076 </p>
01077
01078 <p>
01079 In the Arguments tab, type the full path to the jetty.xml
01080 file in Jetty's etc directory. This is
01081 /home/bcox/workspace/jetty/etc/jetty.xml in my case.
01082 </p>
01083
01084 <p>
01085 In the Classpath tab, use Add Jars to add all of the jars
01086 in Jetty's lib directory. Then use Add Projects to add
01087 all of the projects that you'll be working with, just jwaa
01088 in this case.
01089 </p>
01090
01091 <p>
01092 Finally, click Apply, then Debug. Jetty should launch
01093 without errors and display its normal startup dialog
01094 in the console window at the bottom of the screen.
01095 If any errors are displayed, it is probably because these
01096 instructions missed a required jar. Another common problem
01097 is trying to run muliple copies of jetty, which won't work.
01098 You must shut down any external copies for the new one
01099 to launch.
01100 </p>
01101
01102 <p>
01103 Jetty is now running within Eclipse, and JWAA is running as
01104 a servlet within Jetty, and all facilities of both are accessible
01105 to the Eclipse debugger. Confirm that JWAA is accessible within
01106 Jetty by opening a browser window on http:
01107 confirming that browsing to subpages work as before.
01108 </p>
01109
01110 <p>
01111 Now let's set a breakpoint. In the Java Source browser (click the
01112 J icon on the left edge, open the jwaa project (click the triangle),
01113 open its src folder, and open the edu.virtualschool.jwaa.xml folder.
01114 Double-click on Controller.java and view the source code in the middle
01115 pane. In the right pane, click on the run() method, which is the
01116 code that services each page request. Find the line that reads
01117 "send(evalText)" near the end of this method, and double-click in
01118 the blue margin next to this method. A blue dot will appear, signifying
01119 that a breakpoint has been set on this statement.
01120 </p>
01121
01122 <p>
01123 In your browser, click any link to request a new page. Eclipse will
01124 switch automatically to its Debug view with the selected statement
01125 highlighted in a smaller source window. The window above that will
01126 show a backtrace of the method calls that led to this point. Click
01127 on these and observe that the source code shown in the bottom window
01128 changes to show the clicked method. Click on the run method again
01129 and notice that all variables that were scope at the point of the
01130 breakpoint is available for browsing. For example, pageText shows
01131 the XML code for the selected page before it was processed by
01132 velocity, and evalText shows the text as processed by velocity
01133 just before the send() method sends it to the browser.
01134 </p>
01135
01136 <p>
01137 In other words, every aspect of the program is exposed to view
01138 and subject to modification: not just the source code but the
01139 actual run-time data while the code is running. It can't be
01140 any easier than that!
01141 </p>
01142
01143 </page>
01144
01145 <page id="OVERVIEW" name="Overview" requiresRole="none"
01146 title="Overview of the Java side of this system" >
01147
01148 <p>
01149 See the <a idref="ObjectReferenceManual">ObjectReferenceManual</a>
01150 for Java class descriptions. This section provides an overview of
01151 and suggestions for modifing and extending these classes.
01152 </p>
01153
01154 <h2>Startup-time Processing</h2>
01155
01156 <p>
01157 JWAA's main entry point is the init() method of
01158 <a idref="JwaaServlet">JwaaServlet</a>, a subclass of
01159 <a idref="GenericServlet">GenericServlet</a> from which it
01160 inherits most of its methods.
01161 </p>
01162
01163 <p>
01164 The JwaaServlet constructor initializes a dispatch
01165 table with a list of <a idref="MetaPage">MetaPage</a>
01166 instances, one for each GenericServlet instance in the system.
01167 With Java+, each page is an instance of Page and each defines
01168 a MetaPage as a reference point for other pages to use when
01169 emitting links to that page. When the XML feature of JWAA is
01170 used, this table contains only a single instance; an instance of
01171 <a idref="Controller">Controller</a> that is shared by all pages.
01172 This instance serves as the controller for all JWAA pages,
01173 dispatching requests in a manner similar to the usual JWAA
01174 dispatching machinery, but based on the id defined for each
01175 page in the XML files.
01176 </p>
01177
01178 <p>
01179 The init method retrieves several init parameters defined in
01180 the jwaa/WEB-INF/web.xml file and that locate the other parts
01181 of the system:
01182 </p>
01183
01184 <ul>
01185
01186 <li>
01187 url.prefix: This makes the application aware the URL prefix string.
01188 This parameter should be hand-constructed by concatenating the
01189 servlet name and url pattern (defined elsewhere in this file).
01190 By default, the servlet name is /jwaa and the url pattern is /xml
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080