You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 14 Next »

Intro

See Pre-required readings

Usage for Users

Activation

ProjectStageActivated

This annotation allows to activate beans for a special project-stage. It's possible to use one of the out-of-the-box project-stages or a custom typesafe project-stage.

Alternative implementation activated for Project-Stage UnitTest
@Alternative
@ProjectStageActivated(ProjectStage.UnitTest.class)
public class TestServiceMockImpl implements Service
{
  //...
}
Alternative implementation activated for Project-Stages UnitTest and Development
@Alternative
@ProjectStageActivated({ProjectStage.UnitTest.class, ProjectStage.Development.class})
public class DevServiceMockImpl implements Service
{
  //...
}

To configure a project-stage you can use the key: org.apache.myfaces.extensions.cdi.ProjectStage and configure it for your environment (see the out-of-the-box environment-config options). Static configuration files like web.xml and property files aren't supported because in our opinion it's a wrong and quite risky place to configure it - however, with a custom ConfiguredValueResolver it's possible to resolve the project-stage configuration from any kind of configuration-source.
If there is no CODI project-stage configured and it's a JSF application, CODI will re-use the project-stage configured for JSF.

ExpressionActivated

This annotation allows to activate beans based on expressions. Out-of-the-box simple conditions are supported. The values will be resolved from the environment via the default resolvers (see out-of-the-box environment-config options) or via a custom ConfiguredValueResolver which allows to use any type of configuration-format.

Alternative implementation activated based on a configured value
@ExpressionActivated("db==dev-db")
public class TestDataCreator
{
  //...
}

or

@ExpressionActivated("db!=prod-db;db==*")
public class TestDataCreator
{
  //...
}

'*' allows to ensure that there is a configured value. So the 2nd example ensures that there is a value for 'db' but it isn't 'prod'.

(Custom) ExpressionInterpreter

Per default a simple syntax for key/value based configs is supported. However, it's possible to implement a custom interpreter for custom expressions.

A custom interpreter for custom expressions
@ExpressionActivated(value = "${environment.stage eq 'test'}", interpreter = CustomInterpreter.class)
public class TestDataCreator
{
  //...
}

Config

The core of CODI provides base implementations which are used to provide a testable, pluggable and type-safe config. If it is possible this CDI based config approach is used to configure the framework (esp. the SPI). This approach decouples the logical config entries from the config-source. That means it's possible to switch e.g. between Java Config (values are directly encoded in config classes), property files, db table/s, xml (e.g. web.xml) and every other format which can be used for a config.

Out-of-the-box CODI uses typesafe configuration. Furthermore, there is an alternative configuration module which allows to resolve configure values from myfaces-extcdi.properties or via a custom ConfiguredValueResolver from any other configuration format/source.

Hint

Since the config is based on CDI mechanisms, it isn't possible to use it for all configurations. There are some very basic configurations (e.g. deactivation of specific CODI features), which have to be accessible before CDI is fully initialized. Furthermore, the new versions of Weld (at least until the version which implements CDI v1.1) requires a special bundled version to use a custom configuration.

CodiConfig

All modules which have CODI-Core as dependency use use the CodiConfig interface as marker interface for their config-classes. So it's easy to find all configurations. All methods annotated with ConfigEntry provide a config-value which is used by CODI. During bootstrapping all values are logged (it's possible to deactivate this behaviour by config see CodiCoreConfig#isConfigurationLoggingEnabled). If you provide custom custom values and you face any issue, please also post the configuration to the mailing-list.

CodiCoreConfig

This config contains the basic configuration for the core as well as common config entries for multiple modules.

Environment-Config Options

In some cases it isn't possible to use CDI based configuration. Esp. for parts which have to be active before the CDI container gets bootstrapped.
For such cases CODI uses an extensible configuration approach. By default it supports configuration via:

  • ServiceLoader (if classes have to be configured which implement an interface or extend an abstract class)
  • System properties
  • JNDI
  • Resource Bundle (properties file with the name myfaces-extcdi.properties btw. /META-INF/myfaces-extcdi.properties)

However, with a custom ConfiguredValueResolver it's possible to resolve the project-stage configuration from any kind of configuration-source.

Logging

To avoid external dependencies, CODI uses the JDK Logger. However, CDI often requires serializable beans - therefore CODI provides a serializable wrapper for the JDK Logger.

Injectable JDK logger
public class MyBean
{
    @Inject
    private Logger logger;
}

By default the fully qualified class name of the target class which uses the injected logger, will be used to create the logger. As an alternative it's possible to use the LoggerDetails qualifier to provide e.g. a name for the logger.

Injectable JDK logger with a custom name
public class MyBean
{
    @Inject
    @LoggerDetails(name = "AppLogger")
    private Logger logger;
}

ProjectStage

The core provides a pluggable and type-safe approach for using project stages in a project (it's also used within the framework). Furthermore, @ProjectStageActivated allows to use e.g. implementations annotated with javax.enterprise.inject.Alternative for specific project-stages. Besides the out-of-the-box project-stages it's possible to implement custom but type-safe project-stages which will be exposed by CODI.

Resolving and using the Project-Stage
@Inject
private ProjectStage projectStage;

//...

boolean isDevProjectStage = ProjectStage.Development.equals(this.projectStage);

Provider

BeanManagerProvider

Resolving the Bean-Manager
@Inject
private BeanManager beanManager;

//or

BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();

In some cases, it isn't possible to inject the BeanManager. Therefore, it's possible to use BeanManagerProvider.getInstance().getBeanManager().

Startup

CODI provides multiple hooks for the startup. Usually it's enough to observe the StartupEvent fired by CODI during the startup-process as soon as the target environment is up and running. In case of JSF this event is fired lazily. If you need to execute custom logic before CODI gets active, you should have a look at the dev guide (see StartupEventBroadcaster).

Observing the startup event
@ProjectStageActivated({Development.class, IntegrationTest.class})
public class SampleDataStartupObserver
{
    protected void createSampleData(@Observes StartupEvent startupEvent, UserRepository userRepository)
    {
        User user = new User("Demo", "User");
        userRepository.save(user);
    }
}

Tools

DefaultAnnotation

For creating instances of Annotations, you can use the literal trick. A custom implementation allows to provide custom values (see e.g. the NamedLiteral which is used by CODI internally). If you are fine with the default values of an annotation, you can use DefaultAnnotation to create an annotation for a given type, instead of a custom literal implementation.

Create instances of Annotations
CustomAnnotation annotation = DefaultAnnotation.of(CustomAnnotation.class);

Misc

Advanced

This annotation can be used as marker annotation for artifacts which aren't managed by CDI. If such arifacts are supported by CODI and annotated with this annotation, it's possible to use dependency injection for fields. Furthermore, this annotation can be used as qualifier.

Enhanced

This annotation isn't used by CODI modules. It's a common annotation which can be used as marker annotation or qualifier by CODI add-ons. So they don't have to introduce their own marker annotation.

BeanNames

This interface is a marker interface for all interfaces which contain bean names (used by @Named within CODI). So it's very easy to find beans which can be used in EL expressions.

CoreModuleBeanNames

This interface specifies all beans of the core which can be resolved by name.

InvocationOrder

Artifacts which support this annotation can be sorted. The default order is 1000. Artifacts with a lower ordinal will be called before artifacts with a higher ordinal. If there is an artifact which is supported by CODI but doesn't provide an explicit order, it will be moved at the end of the list.

Base contracts only used by modules of CODI or custom modules

The following artifacts define base contracts which can be used by CODI modules or any other custom modules which would like to build on the well known contracts provided by CODI.

Config/View

This package provides the basic concepts which allow to provide a type-safe config for views. CODI currently uses it in the JSF module for typesafe navigation as well as multiple inheritance for type-safe page-configs.
ViewConfig as well as DefaultErrorView are the foundations for the concept and will be explained in the documentation of the JSF module. However, it's possible to use it for other UI technologies as well.

View

This annotation can be used as interceptor to restrict calls to methods to one or more views. Modules are also allowed to use it as marker annotation to link a bean to a view by annotation the bean with it and pointing to the view(s). In this case a module is allowed to store the information internally and remove the interceptor dynamically to avoid performance impacts.

ViewMetaData

This annotation allows to provide custom meta-data. Just annotate a custom annotation with it. A module like the JSF module has to provide a resolver to query it. A query might return multiple results of the same type. If it doesn't make sense to have multiple results, you can use @ViewMetaData(override=true).

Navigation

ViewNavigationHandler

This navigation handler defines how to navigate with view-configs. Currently it's used by all JSF modules to allow implicit navigation based on the view-configs.

Observing the navigation
@Model
public class ManualNavigationBean
{
    @Inject
    private ViewNavigationHandler viewNavigationHandler;

    public void navigateToHelloMyFacesCodi(ActionEvent actionEvent)
    {
        this.viewNavigationHandler.navigateTo(DemoPages.HelloMyFacesCodi.class);
    }

    public void navigateToErrorView(ActionEvent actionEvent)
    {
        this.viewNavigationHandler.navigateTo(DefaultErrorView.class);
    }
}

This example is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Since it's a generic concept, it's also possible to provide an implementations for other view-technologies.

PreViewConfigNavigateEvent

This event gets triggered if a navigation is going to happen from and to a page represented by a view-config. It also allows to redefine the navigation target.

Observing the navigation
@Model
public class ViewConfigNavigationObserver
{
    @Inject
    //@Jsf //just in case of a JSF application
    private MessageContext messageContext;

    protected void onViewConfigNavigation(@Observes PreViewConfigNavigateEvent navigateEvent)
    {
        if(/*...*/)
        {
            navigateEvent.navigateTo(DefaultErrorView.class);
        }

        this.messageContext.message()
                                .text("navigate from {oldViewId} to {newViewId} view.")
                                .namedArgument("oldViewId", navigateEvent.getFromView())
                                .namedArgument("newViewId", navigateEvent.getToView())
                           .add();
    }
}

In this example the navigation is observed and in a special case the navigation target is changed to the configured default error view. At the end a message gets created and added to the current MessageHandler. In case of a JSF application it gets added to the FacesContext.

This example is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

Scope/Conversation

All interfaces and annotations which are independent from the concrete UI technology are provided by the core. E.g. the concepts of CODI conversations aren't bound to JSF. So the core defines the basic API for CODI conversations. Instead of providing a framework adapter (like MyFaces Orchestra does), CODI hosts the specific implementation in the corresponding module. Currently the UI modules of CODI are just for JSF. However, it would be possible to provide a module e.g. for (plain) servlets. Such a module can use the APIs provided by the core (which are independent of JSF and its concepts).

ConversationScoped

With this annotation it's possible to scope beans in parallel or grouped conversations which are way more powerful that the std. conversation of CDI 1.

This scope is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

ViewAccessScoped

With this annotation it's possible to save beans until the first request of a new view doesn't access it. It's a very convenient scope e.g. for wizard which can't be interrupted.

This scope is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

WindowScoped

This annotation is comparable to a session per window. Compared to the scopes mentioned above, all beans will be removed at the same point in time.

This scope is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

WindowContext

This context contains all CODI scopes which are bound to a window and allows to control them in a fine-grained manner. Furthermore, it contains information about the current window like the window-id.

This interface is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

Conversation

This interface allows to close the associated conversation immediately. Furthermore, it's possible to restart the conversation if it is known that it's going to started again soon (the only difference to closing the conversation is a better performance).

This interface is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

ConversationGroup

This annotation allows to group conversations with a type-safe mechanism.

This interface is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

ConversationRequired

This annotation allows to prevent a navigation to a view which require an existing conversation.

This interface is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

CloseConversationGroup

This method-interceptor allows to close the conversation(-group) of the current bean or an explicitly specified group after the invocation of the method or in case of a specified exception.

This interface is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Since it's a generic concept, it's also possible to provide an implementation for other view-technologies.

Scope/Conversation/Config

ConversationConfig

The conversation config allows to specify e.g. the time-out for grouped conversations and to enable the optional events.

This config is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

WindowContextConfig

The window config allows to specify e.g. the time-out for a window which includes all CODI scopes and to adjust the basic window/-id handling.

This config is independent of JSF. However, currently you need the JSF 1.x or 2.x module to use an out-of-the-box implementation of it. Further, details and examples are available in the documentation of the CODI-JSF-module.

Scope/Conversation/Event

The following events are optional and have to be activated via the configs mentioned above.

  • AccessBeanEvent
  • CloseConversationEvent
  • CloseWindowContextEvent
  • CreateWindowContextEvent
  • RestartConversationEvent
  • ScopeBeanEvent
  • StartConversationEvent
  • UnscopeBeanEvent

Security

AccessDecisionVoter

AbstractAccessDecisionVoter

SecurityViolation

Secured

AbstractDecisionVoter

AbstractBeanCreationDecisionVoter

AccessDeniedException

BeanCreationDecisionVoter

Security/Event

InvalidBeanCreationEvent

  • No labels