[
https://issues.apache.org/jira/browse/DELTASPIKE-877?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Gerhard Petracek resolved DELTASPIKE-877.
-----------------------------------------
Resolution: Fixed
> allow to inherit dynamically changed metadata
> ----------------------------------------------
>
> Key: DELTASPIKE-877
> URL: https://issues.apache.org/jira/browse/DELTASPIKE-877
> Project: DeltaSpike
> Issue Type: New Feature
> Components: JSF-Module
> Affects Versions: 1.3.0
> Reporter: Gerhard Petracek
> Assignee: Gerhard Petracek
> Fix For: 1.3.1
>
>
> currently a ConfigPreProcessor can manipulate custom metadata.
> such a changed annotation-instance will be used instead of the found one.
> however, those changes are currently limited to the current node and they
> aren't visible to child nodes. that can lead to redundant implementations
> (depending on the concrete use-case).
> changing metadata in a "mixed" tree (inheritance and nesting) can get
> complex, however, if we allow child nodes to see just the changes done by
> ancestor-nodes, it won't increase the complexity for users and it's possible
> to support nice uses-cases like:
> {code}
> @View(navigation = REDIRECT)
> public interface Pages extends ViewConfig {
> //...
> @Wizard //all wizard-steps inherit this meta-data and Step1 is known as
> entry-point (for all wizard-steps)
> interface MyWizard extends Pages {
> @EntryPoint
> class Step1 implements MyWizard {}
> class Step2 implements MyWizard {} //protected wizard-step (see
> EntryPointHandler)
> class Summary implements MyWizard {} //protected wizard-step (see
> EntryPointHandler)
> }
> }
> //...
> @ViewMetaData
> public @interface EntryPoint {
> }
> //...
> @ViewMetaData(preProcessor = Wizard.EntryPointProcessor.class)
> public @interface Wizard {
> Class<? extends ViewConfig> entryPoint() default ViewConfig.class;
> class EntryPointProcessor implements ConfigPreProcessor<Wizard> {
> @Override
> public Wizard beforeAddToConfig(Wizard wizard, ViewConfigNode
> viewConfigNode) {
> if (!ViewConfig.class.equals(wizard.entryPoint()) /*explicitly
> defined entry-point*/) {
> return wizard;
> }
> for (ViewConfigNode childNode : viewConfigNode.getChildren()) {
> for (Annotation childMetaData : childNode.getMetaData()) {
> if
> (EntryPoint.class.equals(childMetaData.annotationType())) {
> Map<String, Object> values = new HashMap<String,
> Object>();
> values.put("entryPoint", childNode.getSource());
> return AnnotationInstanceProvider.of(Wizard.class,
> values);
> }
> }
> }
> return wizard;
> }
> }
> }
> @WindowScoped
> public class EntryPointHandler implements Serializable {
> private Class<? extends ViewConfig> previousEntryPoint;
> @Inject
> private ViewConfigResolver viewConfigResolver;
> @Inject
> private ViewNavigationHandler viewNavigationHandler;
> protected void checkEntryPointsAndWizardSteps(@Observes
> @BeforePhase(JsfPhaseId.RENDER_RESPONSE) PhaseEvent phaseEvent) {
> UIViewRoot viewRoot = phaseEvent.getFacesContext().getViewRoot();
> if (viewRoot == null) {
> return;
> }
> String viewIdToRender = viewRoot.getViewId();
> ViewConfigDescriptor viewConfigDescriptor =
> viewConfigResolver.getViewConfigDescriptor(viewIdToRender);
> if (viewConfigDescriptor == null) {
> return;
> }
> if (!viewConfigDescriptor.getMetaData(EntryPoint.class).isEmpty()) {
> this.previousEntryPoint = viewConfigDescriptor.getConfigClass();
> //additional entry-point logic - like close open conversation,
> fire an event,...
> } else if (!viewConfigDescriptor.getMetaData(Wizard.class).isEmpty())
> {
> Wizard wizard =
> viewConfigDescriptor.getMetaData(Wizard.class).iterator().next();
> Class<? extends ViewConfig> entryPointOfWizard =
> wizard.entryPoint();
> if (!entryPointOfWizard.equals(this.previousEntryPoint)) {
> this.viewNavigationHandler.navigateTo(entryPointOfWizard);
> }
> }
> }
> }
> {code}
> that are less than 100 loc for a simple but generic entry-point logic and
> protection of wizard steps (including redirection to the start/entry-point of
> the corresponding wizard) which replace features like @ConversationRequired
> and it's way nicer than what's needed currently:
> {code}
> @View(navigation = REDIRECT)
> public interface Pages extends ViewConfig {
> //...
> interface OutdatedWizard extends Pages {
> @EntryPoint
> class Step1 implements MyWizard {}
> @Wizard(EntryPoint = Pages.MyWizard.Step1.class)
> class Step2 implements MyWizard {}
> @Wizard(EntryPoint = Pages.MyWizard.Step1.class)
> class Summary implements PromotionWizard {}
> }
> }
> //...
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)