Make JSF more type-safe with CDI and MyFaces CODI

  • 7,593 views
Uploaded on

These slides show how to use type-safe mechanisms provided by MyFaces CODI for developing JSF applications which are more type-safe and easier to …

These slides show how to use type-safe mechanisms provided by MyFaces CODI for developing JSF applications which are more type-safe and easier to maintain.

http://2012.con-fess.com/sessions/-/details/136/MyFaces-CODI-and-JBoss-Seam3-become-Apache-DeltaSpike is the next part with more details about MyFaces CODI and Apache DeltaSpike at

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
7,593
On Slideshare
0
From Embeds
0
Number of Embeds
39

Actions

Shares
Downloads
19
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. MyFaces CODI Feature TourMake JSF more type-safe with MyFaces CODI
  • 2. Join CONFESS_2012!
  • 3. Agenda• Type-safety• CODI in a Nutshell• CODI Setup• CODI Core• CODI JSF-Module• CODI Message-Module• CODI JPA-Module• CODI Bean-Validation• CODI Scripting-Module• Integration and Unit Tests with CODI
  • 4. Type-safety - Why should we care about it?• Allows to use std. IDE features like auto-completion• Specialized IDE support is always behind• No Typos• Several features allow compile-time or at least startup checks• Easier for new developers to find usages• Easier refactorings• Easier maintenance• …
  • 5. MyFaces CODI - Overview• MyFaces Extensions CDI aka MyFaces CODI is a portable CDI extension which can be used with Apache OpenWebBeans, JBoss Weld,… and in combination with other portable CDI extensions• CODI-Core is required in any case• Modules – JSF Module (for 1.2 and 2.0 and 2.1) – JPA Module – BV Module – I18n-Message Module – Scripting Module – Test Support Modules
  • 6. MyFaces CODI in a Nutshell• JSF 1.2 and 2.x • Type-safe View-Configs• Type-safety • Type-safe Navigation• Extensibility • JPA Integration• Advanced Scopes • Dependency Injection• Various Events Support for BV• View-Controller • Advanced I18n• JSF 2 Scope Mappings • Scripting Integration • And more!
  • 7. CODI - SETUP
  • 8. Getting CODI up and running• Add CODI to the project – With Maven • Add the modules (or the all-in-one package) to the POM – Without Maven • Download the current dist package • Add the modules (or the all-in-one package) to the Classpath of the project• Start using it!
  • 9. Getting CODI up and running - Hints• With JEE 5 and Mojarra use the controlled bootstrapping add-on• Attention (hint for all bean archives): Ensure that the libs aren’t duplicated – otherwise the CDI implementation will blame ambiguous interceptors, beans,…
  • 10. CODI CORE
  • 11. Startup*• Startup-Observer for the StartupEvent Triggered after the environment is initialized – Initialization tasks which need an up and running environment – Easy logging that the module was started protected void logModuleStart( @Observes StartupEvent startupEvent) { ... }• StartupEventBroadcaster Allows to integrate custom broadcasting mechanisms before the first mechanism of CODI gets called
  • 12. ProjectStage and ProjectStageActivated• Configure beans for a special project-stage in a type-safe way• Examples – Sample data – Debug Phase-Listener @ProjectStageActivated( ProjectStage.Development.class) public class SampleDataStartupObserver { protected void createSampleData( @Observes StartupEvent startupEvent, UserRepository userRepository) { //... userRepository.save(user); } }
  • 13. Custom Project-Stages - 1public class ProjectStages implements ProjectStageHolder { @Typed() //no bean! public static final class CustomProjectStage extends ProjectStage {} public static final CustomProjectStage CustomProjectStage = new CustomProjectStage();}+ Service-Loader config
  • 14. Custom Project-Stages - 2• Configure the project-stage like std. CODI project stages – JSF std. project stage – org.apache.myfaces.extensions.cdi.ProjectStage – ConfiguredValueResolver• Injecting the current project-stage @Inject private ProjectStage projectStage;• Compare the injected value ProjectStage.Development.equals(this.projectStage)• Overrule the current project-stage manually ProjectStageProducer.setProjectStage( ProjectStages.CustomProjectStage)
  • 15. [CODI-Hint] Deactivatable• CDI allows deactivation via a veto-mechanism• Won‘t work for artifacts which aren‘t managed by CDI• CODI allows do deactivate such implementations which implement Deactivatable• Deactivating classes via an implementation of ClassDeactivator (+ Service-Loader config)
  • 16. CODI JSF-MODULE
  • 17. @JsfPhaseListener @ProjectStageActivated( ProjectStage.Development.class, CustomProjectStage.Debugging.class) @Advanced @JsfPhaseListener public class DebugPhaseListener implements PhaseListener { @Inject private Logger logger; public void beforePhase(PhaseEvent phaseEvent) { this.logger.info("before " + phaseEvent.getPhaseId()); } public void afterPhase(PhaseEvent phaseEvent) { this.logger.info("after " + phaseEvent.getPhaseId()); } public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } }
  • 18. @InvocationOrder• Allows to specify the order of multiple artifacts• Example @JsfPhaseListener @InvocationOrder(1) //optional public class DebugPhaseListener implements PhaseListener { //... }
  • 19. JSF LOMs – JSF Lifecycle Observer Methods• Annotations – @BeforePhase – @AfterPhase• Example public void preInvokeApplication( @Observes @BeforePhase(ANY_PHASE) PhaseEvent event) { //... }
  • 20. CODI View-Configs and @Page• Allow to – host meta-data for pages – structure pages – navigate in a type-safe way• Inline usage at page-beans is possible with restrictions• Example for index.xhtml @Page public class Index implements ViewConfig {}
  • 21. Organizing your pages• Meta-data gets inherited (multiple inheritance with interfaces)• Nested classes for defining the view-id via convention (explicit configuration is also possible)• Example for /pages/index.xhtml @Page(navigation = REDIRECT) public interface Pages extends ViewConfig { public @Page class Index implements Pages { } }
  • 22. Inherit Page-Configs by Example@Page(navigation = REDIRECT)public interface Pages extends ViewConfig { public @Page class Login extends DefaultErrorView implements Pages {}}
  • 23. Type-safe Navigation• View-Conig public Class<? extends Pages> register() { //... return Pages.Login.class; }• ViewNavigationHandler (for manual navigation) @Inject private ViewNavigationHandler vnh; vnh.navigateTo(Pages.Login.class);• Navigation Event (PreViewConfigNavigateEvent) Allows to observe type-safe navigations and change the navigation target
  • 24. @Secured by Example@Secured(LoginAccessDecisionVoter.class)public interface Secure extends Pages { @PageBean(FeedbackPage.class) public @Page class FeedbackList implements Secure {}}@ApplicationScopedpublic class LoginAccessDecisionVoter extendsAbstractAccessDecisionVoter { @Override protected void checkPermission( InvocationContext ic, Set<SecurityViolation> violations) { if(...) { violations.add(newSecurityViolation("access denied")); } }}
  • 25. View-Controller• Via – View-Config (@PageBean) – Inline (@View) – Package based • @Page for Page-Beans • @InlineViewConfigRoot as marker• Annotations – @InitView – @PrePageAction – @PreRenderView – @PostRenderView
  • 26. View-Controller – Examples@Secured(LoginAccessDecisionVoter.class)public interface Secure extends Pages { @PageBean(FeedbackPage.class) public @Page class FeedbackList implements Secure {}}or@View(Pages.Secure.FeedbackList.class)public class FeedbackPage implements Serializable { ... }
  • 27. Error-Pages• Configure a default error page• Security violations  default error page (or the explicitly configured page)• Manual Navigation to the default error view (independent of the configured error page) @Inject private ViewNavigationHandler vnh; vnh.navigateTo(DefaultErrorView.class);
  • 28. Type-save Config by Example@Specializespublic class CustomJsfModuleConfig extends JsfModuleConfig { @Override public boolean isAlwaysKeepMessages () { return false; }} With Weld you have to use @Alternative + xml config
  • 29. Custom View-Meta-data• Allows to create custom meta-data• Get the meta-data with: ViewConfigResolver #getViewConfigDescriptor(...)#getMetaData();• Example @Target({TYPE}) @Retention(RUNTIME) @Documented @ViewMetaData public @interface AppInfo { ... } @AppInfo public @Page class About implements Pages {}
  • 30. CODI MESSAGE-MODULE
  • 31. I18n – The Message-Module• Highly customizable• Easy fluent API• Different argument formats – Numbered – Named – EL-Expressions (optional)• Serializable (key + config instead of the final message)  other users get the persisted message in their specific language• Message-Payload (e.g. MessageSeverity)• Different message sources• Optimized for JSF (in combination with the JSF Module)
  • 32. I18n – The Message-Module - Example@Injectprivate MessageContext messageContext;//...this.messageContext.message() .text("{msgUserRegistered}") .namedArgument("userName", this.user.getUserName()) . create(); msgUserRegistered=User {userName} registered successfully!
  • 33. I18n – The Message-Module – JSF Example@Injectprivate @Jsf MessageContext messageContext;//...this.messageContext.message() .text("{msgLoginFailed}") .payload(ERROR) . add();
  • 34. CODI JPA-MODULE
  • 35. @Transactional• Alternative to EJBs esp. outside an Application-Server• Allows to customize the behaviour• Supports multiple persistence-units with qualifiers
  • 36. @Transactional - Example@ApplicationScoped@Transactionalpublic abstract class AbstractGenericJpaRepository { @PersistenceContext(unitName = "default") protected EntityManager entityManager; public T loadById(Long id) { //... }}
  • 37. @Transactional with multiple Persistence Units@Produces + @Disposes@Users or @PreDestroy@PersistenceContext(unitName="UserDB")private EntityManager usersEntityManager;//...@Inject@Usersprotected EntityManager entityManager;@Transactional(Users.class)public void update(User user) { this.entityManager.merge(user);}
  • 38. LET’S WRITE CODE
  • 39. CODI BEAN-VALIDATION
  • 40. Bean-Validation by Example - 1@Inject @Advancedprivate Validator validator;//...validator.validate(user);//...@UniqueLoginNamepublic class User extends AbstractEntity{ //...}
  • 41. Bean-Validation by Example - 2@Target({TYPE}) @Retention(RUNTIME)@Documented@Constraint(validatedBy = { UniqueLoginNameValidator.class})public @interface UniqueLoginName {}@Dependentpublic class UniqueLoginNameValidator extends ClassLevelValidator <UniqueLoginName, User> { @Inject private UserRepository userRepository;}
  • 42. CODI SCRIPTING-MODULE
  • 43. Scripting-Module by Examplepublic class ServerSideScriptingBean { @Inject @ScriptLanguage(JavaScript.class) private ScriptExecutor se; private Double calc() { return se.eval("10 + 4", Double.class); }}
  • 44. UNIT TESTS WITH CODI
  • 45. CODI and JUnit by Example@RunWith(JUnit4.class)public class SimpleTestCase extends AbstractJsfAwareTest { @Inject private RegistrationPage registrationPage; @Inject private UserRepository repository; @Test public void testRegistration() { User user = this.registrationPage.getUser(); user.setUserName("gp"); user.setFirstName("Gerhard"); //... assertEquals(Pages.Login.class, this.registrationPage.register()); assertEquals("Gerhard", this.repository.loadUser("gp").getFirstName()); }}
  • 46. INTEGRATION TESTS WITH CODI
  • 47. CODI and Cargo by Example@RunWith(JUnit4.class)public class SimpleTestCase extends AbstractContainerAwareCargoTest { @Test public void testSimpleForm() { SimplePageInteraction pageInteraction = new SimplePageInteraction(getTestConfiguration()) .start(Pages.Index.class) .useDefaultForm(); String inputId = "userName"; pageInteraction.setValue(inputId, "gpetracek") .clickOk() .checkState(Pages.Result.class); }}
  • 48. WHAT’S NEXT?
  • 49. … more about MyFaces CODI and Apache DeltaSpike at:
  • 50. Links• http://myfaces.apache.org/extensions/cdi/• https://cwiki.apache.org/confluence/display/EXTCDI/Index• https://svn.apache.org/repos/asf/myfaces/extensions/cdi/• http://twitter.com/MyFacesTeam• http://myfaces.apache.org/extensions/cdi/mail-lists.html• Recommended – http://openwebbeans.apache.org – http://code.google.com/a/apache-extras.org/p/ myfaces-codi-addons/ – http://os890.spaaze.com/myfaces-codi