Your SlideShare is downloading. ×
  • Like
  • Save
Make JSF more type-safe with CDI and MyFaces CODI
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Make JSF more type-safe with CDI and MyFaces CODI

  • 7,672 views
Published

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

Published 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,672
On SlideShare
0
From Embeds
0
Number of Embeds
40

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