Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Intro

See Pre-required readings

Usage for Users

Activation

ClassDeactivator

A class-deactivator allows to specify deactivated classes which can't be deactivated via std. CDI mechanisms. All classes which implement Deactivatable in-/directly, can be deactivated with this mechanism. For all other classes/beans, you can use the veto mechanism provided by CDI.

A ClassDeactivator will be resolved from the environment via the default resolvers or via a custom resolver which allows to use any type of configuration-format. An easy way to configure it permanently is to use the service-loader approach. Furthermore, AbstractClassDeactivator is a convenience class which allows an easier implementation.

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.

Code Block
java
java
titleAlternative implementation activated for Project-Stage UnitTest

@Alternative
@ProjectStageActivated(ProjectStage.UnitTest.class)
public class TestServiceMockImpl implements Service
{
  //...
}

...

Code Block
java
java
titleResolving the Bean-Manager

@Inject
private BeanManager beanManager;

//or

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

Project Stage

Alternative implementation activated for Project-Stage Development

@Alternative
@ProjectStageActivated({ProjectStage.Development.class})
public class DevServiceMockImpl implements Service
{
  //...
}

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 or via a custom resolver which allows to use any type of configuration-format. An easy way to configure it permanently is e.g. myfaces-extcdi.properties or for more dynamic use-cases, it's possible to use system-properties.

Code Block
java
java
titleAlternative 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.

Code Block
java
java
titleA 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.

Note
titleHint

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.

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.

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.

Code Block
java
java
titleInjectable 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.

Code Block
java
java
titleInjectable 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.

...

Code Block
java
java
titleResolving and using the Project-Stage
@Inject
private ProjectStage projectStage;

//...

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

...

Creating a custom type-safe project-stage

To configure the project-stage via the Service-Loader mechanism, it's required to implement the ProjectStageHolder interface. In this class you nest the custom project-stage implementations which have to be public static final class and it's required to extend ProjectStage.

Code Block
java
java
titleAlternative implementation for Project-Stage UnitTest

@Alternative
@ProjectStageActivated(ProjectStage.UnitTest.class)
public class TestServiceMockImpl implements Service
{
  //...
}
Custom project-stage implementation

public class CustomProjectStage implements ProjectStageHolder
{
    public static final class Debugging extends ProjectStage
    {
        private static final long serialVersionUID = -8626602281649294170L;
    }

    public static final Debugging Debugging = new Debugging();
}

It's required to provide a {{public static final}} instance even though, you won't use it directly.

Furthermore, you have to add the *fully qualified* class to /META-INF/services/org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStageHolder


{code:java|title=Using a custom project-stage implementation}
@ProjectStageActivated({CustomProjectStage.Debugging
Code Block
javajava
titleAlternative implementation for Project-Stage Development

@Alternative
@ProjectStageActivated({ProjectStage.Development.class})
public class DevServiceMockImpl implements ServiceDebuggingAspect
{
  //...
}

Marker Interfaces

BeanNames

This interface marks all interfaces which contain bean names (used by @Named within CODI)

Utils

Provider

BeanManagerProvider

Code Block
java
java
titleResolving 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).

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.

Code Block
java
java
titleCreate instances of Annotations

CustomAnnotation annotation = DefaultAnnotation.of(CustomAnnotation.class);

Misc

Advanced

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

Enhanced

InvocationOrder

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

PreViewConfigNavigateEvent

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

ViewAccessScoped

WindowScoped

WindowContext

Conversation

ConversationGroup

ConversationRequired

CloseConversationGroup

Scope/Conversation/Config

ConversationConfig

WindowContextConfig

Scope/Conversation/Event

AccessBeanEvent

CloseConversationEvent

CloseWindowContextEvent

CreateWindowContextEvent

RestartConversationEvent

ScopeBeanEvent

StartConversationEvent

UnscopeBeanEvent

Security

AccessDecisionVoter

AbstractAccessDecisionVoter

SecurityViolation

Secured

AbstractDecisionVoter

AbstractBeanCreationDecisionVoter

AccessDeniedException

BeanCreationDecisionVoter

Security/Event

InvalidBeanCreationEvent

Usage for Developers

Config

ConfiguredValueResolver

ConfiguredValueDescriptor

AttributeAware

AbstractAttributeAware

Config/View

ManualView

Interpreter

ExpressionInterpreter

Resolver

GenericResolver

BeanValidation

Security

AccessDecisionVoterContext

AccessDecisionState

Startup

CodiStartupBroadcaster

StartupEvent

StartupEventBroadcaster

Register a custom StartupEventBroadcaster for integrating a broadcaster which gets invoked before the StartupEvent gets fired.
Attention: There is no guarantee that CDI has been bootstrapped.
However, a StartupEventBroadcaster allows to do it (see the controlled bootstrapping add-on).

Note
titleHint

The usage of @InvocationOrder is supported.

Tools

InvocationOrderComparator

Util

ClassUtils

Misc

Aggregatable

CodiInformation

UnhandledException