* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Slide 1
Survey
Document related concepts
Transcript
NAAM ADF Development More tales from the trenches Aino Andriessen AMIS Services • • • • • • Systems integrator Co-sourcing Maintenance Oracle, Java, Open Source, ADF, DBA, SOA AMIS technology school Pagoni • http://www.amis.nl • http://technology.amis.nl/blog/ Aino Andriessen • • • • • • • Technical Consultant Technical Architect Java, ADF, PL/SQL, XML, ... SOA , Integration Software engineering Quality management Agile development • [email protected] • http://www.fttech.net Stakeholders customer developer maintenance project lead better according to... Customer better according to... Project lead better according to... Developer better according to... Maintenance better according to... Girlfriend • How can we make better ADF applications? 5 essentials • • • • • Communication Responsibility Knowledge Organization Fun • Let's start coding... • Sorry, not yet... Organization... • • • • • • • • • Project Development process Skills Project structure (file structure) Code Design and Architecture Documentation Communication Infrastructure Source control Tests Developer Developer 2 Developer 2 Developer 2 Inspection Documentation site Reports Documentation Custom Corporate Library Build automation Issue reports Delivery environments Library Public Library Production Acceptance Test Issue management Integration Development • Can we now start coding? • Almost... Development principles • OK, wake up and let's get to business... • Build an ADF - JHeadstart application • Address common and not so common issues • ADF 10g – Some 11g Demo • Regatta Management System • Application to support sailing regatta's. – maintain regatta's – registration – enter racing data – results Development Goal • Match implementation against stakeholders' concerns : – Functional – Maintainable – Stable – Budget – Organized – Fun –... Business Logic implementation • Business Logic can be implemented at many locations – ADF Faces components • • • • Managed beans Backing beans EL-expressions Attributes – Service methods – VO's • Attributes : transient, calculated • Methods – Entities • Attributes • Validators – Database • Constraints • Views • Stored procedures – ... The (ADF) challenge • Consistent and comprehensible implementation of business logic. FD • Requirements – – Maintain regatta information Allow sailors / boats to enter a regatta. • – – – – – – • Register skipper and captain (owner) with some personal details Schedule racings Easy registration of race details, only by certain people Publish results Nice look and feel Easy to use Handle handicap system Business rules – – – – – – Participant, skipper, must be older than 18 Same boat may enter only once Finishtime after starttime Participant can have only one result It should be able to reset the finish of a participants, in case of error Register if the boat didn't start or finish, using the common codes like DNF, DNS, DSQ etc. • – Extra information about this situation must be entered Races cannot be scheduled at the same time Functions / Use cases • • • • • Maintain regatta's Register for a regatta Enter racing data Publish results Supportive functions ADF 'architecture' • ADF applications tend to evolve instead of being designed. – Viewobjects are created when needed – Managed beans are created as needed – Application Modules function merely as a service-hatch • ADF doesn't force you into an organized application, except maybe the model and viewController. • ADF offers multiple solutions for the same problem and in the end all of them will eventually appear in the application. ADF architecture ADF Faces ADF model (binding) ADF BC Database ADF architecture ADF Faces Managed beans ADF model (binding) ADF BC Objects Application Modules ViewObjects Entities Database Stored Procedures Tables Views Application Integration ADF Application Webser vices Files Database Notifica tion Messa ging Function / Use Case approach • The application module, the service, is the core of the application • Each function / use case is implemented as a service. • Services can be nested ADF architecture ADF Faces Webser vices ADF model (binding) Service ADF BC Webser vices Service Service Files Database Service Notifica tion Service Messa ging RMS Services Datamodel Datamodel 2 • Views – 1 : 1 on tables : vpd, – complex queries • Stored procedures • app_owner and app_user Development Development environment • • • • • • JDeveloper 10g 10.1.3.4 JHeadstart 10g 10.1.3.3 Oracle 11g R1 OC4J 10.1.3.4 Maven 2.1 Subversion 1.5 JDeveloper Setup • External tools • Encoding UTF-8 – Preferences -> Environment • Upgrade JDev svn client to 1.5 – http://technology.amis.nl/blog/5253/upgrade-jdeveloper10g-subversion-client JDeveloper • Organize imports • Define .vm as text file – preferences -> filetypes • Default editors : source – preferences -> filetypes Project setup Projects common General code, Baseclasses Reusable's database deployment Database code, scripts (automated) Deploy to iAS ear model viewController Build deliverable, ear ADF BC's UI ADF Faces 'External' libraries lib Maven conventions - code Maven conventions - unittests General • • • • SRDemo JHeadstart framework Weblogs Documentation – Developer’s Guide For Forms/4GL Developers • Simple Emp reference project BC Creation Default - create BC's from table Default - create BC's from table BC creation 1. 2. 3. 4. 5. 6. Services Entities Associations Viewobjects Viewlinks VO usages • Apply naming conventions – Refactor if needed • Organize, organize, organize Create Entities • Create Business components from table – Refactor associations • Base on table, change later to database view Edit entities • Set Id from sequence – DBSequence is a nightmare to refactor • Control Hints – Enter once, use often Associations • Association properties – apply correct plural and singular • Define Composition Association – Developer’s Guide For Forms/4GL Developers - Chapter 6.3.3 Business rules BR Implementation Participant, skipper, must be older than 18 Entity validation Same boat may enter only once Unique key Finishtime after starttime FE or DB or 'complex' entity Participant can have only one result Unique key It should be able to reset the finish of a participants, in case of error FE function Register if the boat didn't start or finish, using the common codes like DNF, DNS, DSQ etc. Datamodel, domain Extra information about this situation must be entered FE, mandatory dependency Races cannot be scheduled at the same time Unique key? A boat either has a finishtime or a special situation Row validation Entity Business Rules • Mandatory, PK, UK • Validation – Declarative – Method – Rules • Declare in project properties – Very Reusable • [Entity constraint] – NO validation – Only present for creating table from entity Validators / Rules • Create Registered Rule in project properties – Or reuse an existing one • Implement code in validateValue method Validators • Select the Rule as attribute validation • Test Entity Validation - remarks • The setter immediate triggers the validation – actually the setAttributeInternal(...) • Validations are executed top to bottom • Row validation is performed 'independent' of attribute validation. • Declarative Date validators are limited – Use Validators • Using a select statement for validation is very limited (if it works at all) – Avoid it. • Consider Validator when the same validation is entered multiple times. • Validator exception msg not published to the front-end (as we'll see later) (J)Unittesting Entities • Create Application Module : import oracle.jbo.client.Configuration; RegistrationServiceImpl _am; public void setUp() { _am = Configuration.createRootApplicationModule ("nl.amis.demo.rms.model.services.RegistrationService" ,"RegistrationServiceLocalURL"); } public void tearDown () { Configuration.releaseRootApplicationModule(_am, true); } • Create entity : EntityDefImpl empdef = (EntityDefImpl)EntityDefImpl.findDefObject ("nl.amis.demo.rms.model.entities.CrewMember"); crewMember = (CrewMemberImpl)empdef.createInstance2 (_am.getDBTransaction(), null); • Execute test : Date testDate = (Date)Date.getCurrentDate(); try { crewMember.setBirthdate(testDate); fail(); } catch (Exception e) { e.printStackTrace(); } testDate = (Date)testDate.addMonths(-12*20); try { crewMember.setBirthdate(testDate); } catch (Exception e) { fail(); e.printStackTrace(); } Unit-testing ↑ code control ↑ code quality ↓ development time • • • • • 'Automatic' regression test TDD improves the testability of your code Unit-testing increases your ADF skills Easy debugging of BC's Automated execution at continuous integration Unittest framework • TestBase per application module – provide ServiceImpl • Utility methods – Create entity • Standardization – Authorization – Context I don't write unittests because it takes too much time I'll start the application, login, navigate to the right screen and then perform the correct actions? Then, how do you test your code? Gee, How long does that take? VO Remarks • Often screen, Use Case driven • Organize – the number may increase rapidly – Separate list-only VO's • Apply naming conventions – – – – plural Lkp Trnsnt ...By... • Don't use 'automatic BC creation from database' – Unless you like refactoring... VO remarks • Calculated attributes are not updated automatically, but need a requery – This may often result in complex code Domain driven logic • NoFinishCode – DSQ, DNF, DNS • define constants or enum • IsXXX attributes VO client interface methods • Implement VO related functions – startRace() – disqualifyParticipant() – .. • Maybe also published as Service interface method • Beware with nested applicationmodules to bind the correct method – or else the getCurrentRow does not work – NB, bindings work ok Bindings and Nested AM Viewobject validation • Override validate() method • setter method • throw JboException – define your own View object usages • Naming conventions • Organize them in services Unittesting VO's (Usages) • Basic test – executeQuery • Business Logic • Beware of detail VO's – they are direct available on the AM, but relate to their parent Programmatic viewobjects • e.g. for Webservice clients • See Developer’s Guide For Forms/4GL Developers Chapter 9 • JhsProgrammaticViewObject – getJhsProgrammaticResultSet • ! Executed many times – Override executeQuery() to actually retrieve data – Store result in JhsProgrammaticResultSet class variable – Convert using JhsProgrammaticHelper.convertBean • Match attributes with ws return object Re-use • • • • • Bases classes Validators Unittest utilities Date handling ADF Binding (model) methods – SRDemo : JSFUtils and ADFUtils • • • • • • • JHeadstart templates Business Components Task flows Beans Converters Filters ... Organize Re-use • Separate projects, libraries, and owners • Review / audit criteria Reuse BC's • • • • Separate project Create deliverable Add jar to project Import jar • Beware, sharing database connection from root application module Refactoring BC's • http://technology.amis.nl/blog/2859/fear-forrenaming-refactoring-adf-bc-objects-injdeveloper-is-not-unfounded • Renaming and moving BC's is handled quite well. • Bindings are not automatically adjusted • JHeadstart is not automatically updated – Generation errors – Just reselect the attribute / group • Try to be strongly typed Refactoring remarks • Matching subversion clients • Refactoring DBSequence attributes is a pain... • ADF does not always allow you to refactor, in case of dependencies. • Validator – Re-registration of the Rule • Beware of static 'dependencies' in the JHeadstart templates JHeadstart • One application definition vs. multiple – Can merge and split quite easily – 11g support for multiple improved • JHeadstart supports nested application modules • Apply standards and naming conventions • Configuration – tools -> preferences • e.g. item prompt – AppDef root node • AM superclass Custom Templates • Application hierarchy matches the default • Documentation of templates • Try to avoid hard-coded bindings – difficult to refactor – custom properties • Buttons can be generated – however, the binding is not Common recommendations • Understand the framework • Avoid 'bindings', use a managed bean and dependencies • Custom bindings : Disable 'Clear Page Definition' • Close pagedefs before generation Date and time • Using Java Date and Calendar and oracle.jbo.domain.Date and Timestamp can be tricky – new oracle.jbo.domain.Date() ? – new oracle.jbo.domain.Timestamp() ? – Date.getCurrentDate() ? – ((Date)Date.getCurrentDate()).timestampValue • actually java.sql.Timestamp • Current time? Date and time - Calendar Calendar c = Calendar.getInstance(); oracle.jbo.domain.Timestamp ts = new Timestamp(c.getTime()); Timestamp ts = new Timestamp(c. getTimeInMillis()); c.set(Calendar.HOUR_OF_DAY,5) Date Time - JodaTime DateTime dt = new DateTime(); Timestamp ts = new Timestamp(dt.getMillis()); DateTime dt=new Da dt.getHourOfDay(); dt.plusMinutes(10); dt.minusWeeks(5); dt.isAfter(dt2); dt.isBefore(dt2); dt.isBeforeNow();teTime(2009,6,14,13,0,0,0) Search Programmatic viewobject • Standard JHeadstart Search – Allows searching using the VO attributes – Creates 'SQL formatted' ViewCriteria • oracle.jheadstart.model.QueryCondition • unusable for Programmatic viewobject 1. Somehow retrieve actual data from viewcriteria 1. Strip the formatting 2. Provide the actual value 1. e.g. via the oracle.jheadstart.model.QueryCondition 2. Override JhsApplicationModuleImpl.advancedSearch() Store search criteria • On login requery the latest search • Extend JhsSearchBean • Override advancedSearch() – Serialize the criteria to file – Use the userId as name for the file • Constructor – Retrieve the criteria from file • http://groups.google.com/group/adfmethodology