Make JSF more type-safe with CDI and MyFaces CODI


Published 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 maintain. is the next part with more details about MyFaces CODI and Apache DeltaSpike at

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Make JSF more type-safe with CDI and MyFaces CODI

  1. 1. MyFaces CODI Feature TourMake JSF more type-safe with MyFaces CODI
  2. 2. Join CONFESS_2012!
  3. 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. 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. 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. 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. 7. CODI - SETUP
  8. 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. 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. 10. CODI CORE
  11. 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. 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) { //...; } }
  13. 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. 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. 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)
  17. 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) {"before " + phaseEvent.getPhaseId()); } public void afterPhase(PhaseEvent phaseEvent) {"after " + phaseEvent.getPhaseId()); } public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } }
  18. 18. @InvocationOrder• Allows to specify the order of multiple artifacts• Example @JsfPhaseListener @InvocationOrder(1) //optional public class DebugPhaseListener implements PhaseListener { //... }
  19. 19. JSF LOMs – JSF Lifecycle Observer Methods• Annotations – @BeforePhase – @AfterPhase• Example public void preInvokeApplication( @Observes @BeforePhase(ANY_PHASE) PhaseEvent event) { //... }
  20. 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. 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. 22. Inherit Page-Configs by Example@Page(navigation = REDIRECT)public interface Pages extends ViewConfig { public @Page class Login extends DefaultErrorView implements Pages {}}
  23. 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. 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. 25. View-Controller• Via – View-Config (@PageBean) – Inline (@View) – Package based • @Page for Page-Beans • @InlineViewConfigRoot as marker• Annotations – @InitView – @PrePageAction – @PreRenderView – @PostRenderView
  26. 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. 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. 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. 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 {}
  31. 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. 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. 33. I18n – The Message-Module – JSF Example@Injectprivate @Jsf MessageContext messageContext;//...this.messageContext.message() .text("{msgLoginFailed}") .payload(ERROR) . add();
  35. 35. @Transactional• Alternative to EJBs esp. outside an Application-Server• Allows to customize the behaviour• Supports multiple persistence-units with qualifiers
  36. 36. @Transactional - Example@ApplicationScoped@Transactionalpublic abstract class AbstractGenericJpaRepository { @PersistenceContext(unitName = "default") protected EntityManager entityManager; public T loadById(Long id) { //... }}
  37. 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. 38. LET’S WRITE CODE
  40. 40. Bean-Validation by Example - 1@Inject @Advancedprivate Validator validator;//...validator.validate(user);//...@UniqueLoginNamepublic class User extends AbstractEntity{ //...}
  41. 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;}
  43. 43. Scripting-Module by Examplepublic class ServerSideScriptingBean { @Inject @ScriptLanguage(JavaScript.class) private ScriptExecutor se; private Double calc() { return se.eval("10 + 4", Double.class); }}
  45. 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()); }}
  47. 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. 48. WHAT’S NEXT?
  49. 49. … more about MyFaces CODI and Apache DeltaSpike at:
  50. 50. Links•••••• Recommended – – myfaces-codi-addons/ –