[help] choice in a wizard

19 posts / 0 new
Last post
atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent,

I want to get a wizard view with a list of options where the user chooses one of them. The number of options is fixed so it can be either radio buttons or a drop-down list.

Can you give me some advice where to start?

Regards

Pierre

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Hi Pierre,

If your options are known at compile-time, you can register a wizard step with a view descriptor that is backed by a component descriptor itself holding a BasicEnumerationPropertyDescriptor. Refer back to the topic we had together (http://www.jspresso.org/forum/front-action-get-value); you can just design arbitrary complex views for each wizard step. The wizard model will be populated accordingly.

If your options are known at run-time, then you have to use a collection view descriptor (either a list or a table).

Hope this helps,

 

Regards,

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent,

See below the code I tried and the exception I got.

I must miss something obvious... but what?

Regards

Pierre

============================================

  <bean
    id="getContractPeriodTypeWizardStep"
    class="org.jspresso.framework.application.frontend.action.wizard.StaticWizardStepDescriptor"
    >
    <property name="viewDescriptor">
      <bean
        class="org.jspresso.framework.view.descriptor.basic.BasicComponentViewDescriptor">
        <property name="modelDescriptor">
          <bean
            class="org.jspresso.framework.model.descriptor.basic.BasicComponentDescriptor">
            <property name="propertyDescriptors">
              <list>
                <bean class="org.jspresso.framework.model.descriptor.basic.BasicEnumerationPropertyDescriptor">
                  <property name="name"            value="contract.period.type" />
                  <property name="enumerationName" value="contractPeriodType" />
                  <property name="mandatory" value="true" />
                  <property name="valuesAndIconImageUrls">
                    <map>
                      <entry key="work" value="classpath:org/popsuite/hr/images/tool-48x48.png" />
                      <entry key="leave" value="classpath:org/popsuite/hr/images/armchair-48x48.png" />
                      <entry key="strike" value="classpath:org/popsuite/hr/images/fist-48x48.png" />
                    </map>
                  </property>
                </bean>
              </list>
            </property>
          </bean>   
        </property> 
      </bean>
    </property>
  </bean> 
     
  <bean
    id="createContractPeriodFrontAction"
    parent="wizardAction">
    <property name="firstWizardStep" ref="getContractPeriodTypeWizardStep" />
    <property name="finishAction" ref="addToMasterOkFrontAction" />
  </bean>

==================================================

java.lang.NullPointerException
    at org.jspresso.framework.model.descriptor.basic.AbstractComponentDescriptor.getPropertyDescriptor(AbstractComponentDescriptor.java:230)
    at org.jspresso.framework.model.descriptor.basic.AbstractComponentDescriptor.explodeComponentReferences(AbstractComponentDescriptor.java:542)
    at org.jspresso.framework.model.descriptor.basic.AbstractComponentDescriptor.getRenderedProperties(AbstractComponentDescriptor.java:311)
    at org.jspresso.framework.view.descriptor.basic.BasicComponentViewDescriptor.getRenderedProperties(BasicComponentViewDescriptor.java:73)
    at org.jspresso.framework.view.descriptor.basic.BasicComponentViewDescriptor.getPropertyViewDescriptors(BasicComponentViewDescriptor.java:123)
    at org.jspresso.framework.view.swing.DefaultSwingViewFactory.createComponentView(DefaultSwingViewFactory.java:385)
    at org.jspresso.framework.view.AbstractViewFactory.createView(AbstractViewFactory.java:199)
    at org.jspresso.framework.application.frontend.action.wizard.WizardAction.displayWizardStep(WizardAction.java:214)

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Pierre,

Can you try your code with a property name of contractPeriodType instead of contract.period.type ? The component descriptor tries to resolve nested property names and it can't find the nested component descriptors, i.e. :

wizardModel (IComponentDescriptor)
--> contract (expected IReferencePropertyDescriptor)
--> period (expected IReferencePropertyDescriptor)
--> type (expected IPropertyDescriptor)

Tell me if it solves your issue. In fact I've never tried to declare a property with dots in its name - how would it translate then ?

 

Regards,

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Tell me if it solves your issue

OK

how would it translate then ?

I don't see the issue...

Now the next step:

When I valid the choice, I don't come back to the previous view but to the view before.

The scenario is:

- from a view with contract list, I open one of the contracts in a detail view

- in the detail view of the contract, there is a list of periods

  this list has a menu with the action "createContractPeriodFrontAction", see below

- I run "createContractPeriodFrontAction"

- I select the right type and valid the choice

- then I come back to the contract list view and not to the detail view of the contract I'm working with

  and a new empty contract was added to the contract list !

So...

 

Pierre

===================================

"createContractPeriodFrontAction" as above and:

  <bean
    id="addToMasterOkFrontAction"
    parent="okDialogFrontAction" >
    <property name="name" value="create.contract.period" />
    <property name="nextAction">
      <bean parent="addToMasterFrontAction"
            class="org.popsuite.hr.frontend.action.AddContractPeriodCollectionToMasterAction" />
    </property>
  </bean>

  <bean
        id="contractPeriodMasterDetailActionMap"
        parent="masterDetailActionMap">
    <property name="actionLists">
      <list>
        <bean class="org.jspresso.framework.view.action.ActionList">
          <property name="name" value="ACTION" />
          <property name="actions">
            <list>
              <ref local="createContractPeriodFrontAction" />
              <ref bean="removeEntityCollectionFromMasterFrontAction" />
              <ref bean="cloneEntityCollectionFrontAction" />
            </list>
          </property>
        </bean>
        <bean class="org.jspresso.framework.view.action.ActionList">
          <property name="name" value="EDIT" />
          <property name="actions">
            <list>
              <ref bean="copyCollectionFrontAction" />
              <ref bean="cutCollectionFrontAction" />
              <ref bean="pasteCollectionFrontAction" />
            </list>
          </property>
        </bean>
      </list>
    </property>
  </bean> 

 

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Sorry for the noise. Forget the second part of the previous message

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Pierre,

When I talked about translation I actually meant "translation in terms of JavaBean property". Nested properties are fine for binding from the view but not for the model.

What was the solution to the other problem ?

 

Best,

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent

What was the solution to the other problem ?

None :'(

I thought my configuration was wrong and I tried an other one, where I wrapped "addToMasterFrontAction":

  <bean
    id="addToMasterOkFrontAction"
    parent="okDialogFrontAction" >
    <property name="name" value="create.contract.period" />
    <property name="wrappedAction">
      <bean parent="addToMasterFrontAction"
            class="org.popsuite.hr.frontend.action.AddContractPeriodCollectionToMasterAction" />
    </property>
  </bean>

This time I got:

        java.lang.ClassCastException: org.jspresso.framework.binding.model.ModelConnector
        cannot be cast to org.jspresso.framework.binding.ICollectionConnector

       [see below the trace]

So the issue stays: how to come back to the Contract detail view with the list of periods?

Regards

Pierre

======================================

java.lang.ClassCastException: org.jspresso.framework.binding.model.ModelConnector cannot be cast to org.jspresso.framework.binding.ICollectionConnector
    at org.jspresso.framework.application.backend.action.AbstractCollectionAction.getModelConnector(AbstractCollectionAction.java:57)
    at org.jspresso.framework.application.backend.action.AbstractAddCollectionToMasterAction.execute(AbstractAddCollectionToMasterAction.java:70)
    at org.jspresso.framework.application.backend.AbstractBackendController.execute(AbstractBackendController.java:107)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeBackend(AbstractFrontendController.java:625)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.protectedExecuteBackend(DefaultSwingController.java:537)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.executeBackend(DefaultSwingController.java:397)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:199)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.execute(DefaultSwingController.java:275)
    at org.jspresso.framework.application.frontend.action.WrappingAction.execute(WrappingAction.java:62)
    at org.jspresso.framework.application.frontend.action.std.AddCollectionToMasterAction.execute(AddCollectionToMasterAction.java:94)
    at org.popsuite.hr.frontend.action.AddContractPeriodCollectionToMasterAction.execute(AddContractPeriodCollectionToMasterAction.java:37)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeFrontend(AbstractFrontendController.java:638)
[...]

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Pierre,

I seems that the AddContractPeriodCollectionToMasterAction does not work on the correct collection, i.e. as if it was working on the children module collection and not your list of periods... Could you post the source code of the class ? You where right in declaring it as the "nextAction" and not the "wrappedAction", since it has to work on the original context, i.e. before the wizard dialog opens.

 

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent,

See AddContractPeriodCollectionToMasterAction below.

But I get the same behavior even with a standard addToMasterFrontAction bean, that is:

  <bean
    id="addToMasterOkFrontAction"
    parent="okDialogFrontAction" >
    <property name="name" value="create.contract.period" />
    <property name="nextAction">
      <bean parent="addToMasterFrontAction" />
    </property>
  </bean>

Regards

Pierre

PS: I use a modified version of BasicEnumerationPropertyDescriptor<E> with valuesAndIconImageUrls of type Map<E, String>.

=====================================================

package org.popsuite.hr.frontend.action;

import java.util.HashMap;
import java.util.Map;

import org.jspresso.framework.action.ActionContextConstants;
import org.jspresso.framework.action.IActionHandler;
import org.jspresso.framework.application.frontend.action.std.AddCollectionToMasterAction;
import org.jspresso.framework.model.descriptor.IComponentDescriptor;
import org.jspresso.framework.model.entity.IEntity;

public class AddContractPeriodCollectionToMasterAction<E, F, G>
extends AddCollectionToMasterAction<E, F, G> {

    public final static String CONTRACT_PERIOD_TYPE = "contractPeriodType";

    private IComponentDescriptor<IEntity> elementEntityDescriptor;

    /**
     * Completes the action context with the element entity descriptor.
     * Try to get one from the context parameters. If none, uses the
     * element entity descriptor parametrized.
     * <p>
     * {@inheritDoc}
     */
    @Override
    public boolean execute(IActionHandler actionHandler,
            Map<String, Object> context) {
        Map<String, Object> varContext = context;
        if (varContext == null) {
            varContext = new HashMap<String, Object>();
        }
        IComponentDescriptor<IEntity> descriptor = getEntityDescriptor(context);
        varContext.put(ActionContextConstants.ELEMENT_DESCRIPTOR,
                descriptor);
        return super.execute(actionHandler, varContext);
    }

    private IComponentDescriptor<IEntity> getEntityDescriptor(Map<String, Object> context) {
        Object params = context.get(ActionContextConstants.ACTION_PARAM);
        IComponentDescriptor<IEntity> descriptor = null;
        if (params != null) {
            if (params instanceof Map) {
                @SuppressWarnings("unchecked")
                IComponentDescriptor<IEntity> param =
                    (IComponentDescriptor<IEntity>) ((Map<?,?>) params).get(CONTRACT_PERIOD_TYPE);
                descriptor = param;
            } else if (params instanceof IComponentDescriptor<?>) {
                @SuppressWarnings("unchecked")
                IComponentDescriptor<IEntity> param = (IComponentDescriptor<IEntity>) params;
                descriptor = param;
            }
        }
        if (descriptor == null) {
            descriptor = elementEntityDescriptor;
        }
        return descriptor;
    }

    @Override
    public void setElementEntityDescriptor(
            IComponentDescriptor<IEntity> elementEntityDescriptor) {
        this.elementEntityDescriptor = elementEntityDescriptor;
        super.setElementEntityDescriptor(elementEntityDescriptor);
    }

}

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Pierre,

I've tested your wizard action linking it to the addToMasterFrontAction standard action. I've registered the exact same contractPeriodMasterDetailActionMap you've pasted on a table view and everything works fine... The new entity gets created and selected in the table Frown.

Can you just test the following : get rid of the wizard action by replacing createContractPeriodFrontAction by addToMasterFrontAction in the action map ? I really doubt that the wizard action is the cause.

BTW, the only thing missing is the declaration of the view where the action map is registered. Can you provide it ?

 

Best,

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent,

 

If I use the standard "addToMasterFrontAction", I get

      org.jspresso.framework.model.entity.EntityException: org.popsuite.hr.model.ContractPeriod is purely abstract. It cannot be instanciated.

This is why I need to specify which type of period I want to add.

About the view:

  <bean
    id="contract.and.periods.pane"
    class="org.jspresso.framework.view.descriptor.basic.BasicSplitViewDescriptor">
    <property name="modelDescriptor"           ref="Contract" />
    <property name="leftTopViewDescriptor"     ref="contract.pane" />
    <property name="rightBottomViewDescriptor" ref="contract.periods.table" />
    <property name="cascadingModels"           value="true" />
  </bean>

  <bean
    id="contract.periods.table"
    parent="decoratedView"
    class="org.jspresso.framework.view.descriptor.basic.BasicTableViewDescriptor">
    <property name="modelDescriptor" ref="Contract-periods" />
    <property name="actionMap" ref="contractPeriodMasterDetailActionMap" />
  </bean>

  and the model

  <bean
    id="Contract-periods"
    class="org.jspresso.framework.model.descriptor.basic.BasicCollectionPropertyDescriptor">
    <property name="name"        value="periods" />
    <property name="composition" value="true" />
    <property name="referencedDescriptor" >
      <bean
        class="org.jspresso.framework.model.descriptor.basic.BasicCollectionDescriptor">
        <property name="collectionInterface" value="java.util.List" />
        <property name="elementDescriptor"   ref="ContractPeriod" />
      </bean>
    </property>
    <property name="integrityProcessorClassNames">
      <list>
        <value>org.popsuite.hr.model.processor.ContractPropertyProcessors$PeriodsProcessor</value>
      </list>
    </property>
  </bean>

 
Regards

Pierre

 

vvandens
Offline
Joined: 05/29/2008
[help] choice in a wizard

Pierre,

I'm a little confused here... Nothing suspicious in your description, except that cascadingModels=true is not needed on contract.and.periods.pane. But this is completely harmless. I don't get it.

Could you debug AbstractAddCollectionToMasterAction and see what's happening line 80 - Object master = collectionConnector.getParentConnector() ? master should definitely be assigned to the contract that is backing your detail view and newComponents should be a singleton list containing the newly created contract period.

 

Best,

Vincent

atao
Offline
Joined: 10/15/2008
[help] choice in a wizard

Vincent,

I did as you said. Two issues occured:

- the first (easy) one: newComponents was an empty list. The culprit is AddContractPeriodCollectionToMasterAction which calls AddCollectionToMasterAction.execute, and this last one erases ELEMENT_DESCRIPTOR...

So:

  * in AddCollectionToMasterAction I added a method getElementDescriptor that returns elementEntityDescriptor and used it in execute method

  * in AddContractPeriodCollectionToMasterAction I removed execute method and I kept getElementDescriptor

- then the second one: I get an IllegalArgumentException, see below.

  In AbstractAddCollectionToMasterAction.execute, collectionAccessor's attributes are

  * beanClass = org.popsuite.hr.model.Worker

  * elementClass = org.popsuite.hr.model.Contract

  * property = contracts

It doesn't seem as what is expected...

I put herewith the configuration where "contract.and.periods.pane" is used.

Regards

Pierre

===========================================

java.lang.RuntimeException: java.lang.IllegalArgumentException: argument type mismatch
    at org.jspresso.framework.util.accessor.bean.BeanCollectionAccessor.addToValue(BeanCollectionAccessor.java:90)
    at org.jspresso.framework.application.backend.action.AbstractAddCollectionToMasterAction.execute(AbstractAddCollectionToMasterAction.java:109)
    at org.jspresso.framework.application.backend.AbstractBackendController.execute(AbstractBackendController.java:107)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeBackend(AbstractFrontendController.java:625)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.protectedExecuteBackend(DefaultSwingController.java:537)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.executeBackend(DefaultSwingController.java:397)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:199)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.execute(DefaultSwingController.java:275)
    at org.jspresso.framework.application.frontend.action.WrappingAction.execute(WrappingAction.java:62)
    at org.jspresso.framework.application.frontend.action.std.AddCollectionToMasterAction.execute(AddCollectionToMasterAction.java:95)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeFrontend(AbstractFrontendController.java:638)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.protectedExecuteFrontend(DefaultSwingController.java:542)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.executeFrontend(DefaultSwingController.java:406)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:201)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.execute(DefaultSwingController.java:275)
    at org.jspresso.framework.application.frontend.action.CloseDialogAction.execute(CloseDialogAction.java:66)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.executeFrontend(AbstractFrontendController.java:638)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.protectedExecuteFrontend(DefaultSwingController.java:542)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.executeFrontend(DefaultSwingController.java:406)
    at org.jspresso.framework.application.frontend.controller.AbstractFrontendController.execute(AbstractFrontendController.java:201)
    at org.jspresso.framework.application.frontend.controller.swing.DefaultSwingController.execute(DefaultSwingController.java:275)
    at org.jspresso.framework.application.frontend.action.wizard.WizardAction$FinishAction.execute(WizardAction.java:291)
[...]

===========================================

  <bean
    id="workers.and.contracts.view"
    class="org.jspresso.framework.view.descriptor.basic.BasicSplitViewDescriptor">
    <property name="leftTopViewDescriptor" ref="branch-workers.table" />
    <property name="rightBottomViewDescriptor">
      <bean
        class="org.jspresso.framework.view.descriptor.basic.BasicSplitViewDescriptor">
        <property name="orientation"               value="HORIZONTAL" />
        <property name="leftTopViewDescriptor"     ref="worker-contracts.table" />
        <property name="rightBottomViewDescriptor" ref="contract-payslips.table" />
        <property name="cascadingModels"           value="true" />
      </bean>
    </property>
    <property name="cascadingModels"       value="true" />
  </bean>

  <bean
    id="worker-contracts.table"
    parent="decoratedView"
    class="org.jspresso.framework.view.descriptor.basic.BasicTableViewDescriptor">
    <property name="modelDescriptor" ref="Worker-contracts" />
    <property name="actionMap" ref="contractMasterDetailActionMap" />
    <property name="columnViewDescriptors">
      <list>
        <bean parent="subview">
          <property name="name" value="job" />
          <property name="readOnly" value="true" />
        </bean>
        <bean parent="subview">
          <property name="name" value="begin" />
          <property name="readOnly" value="true" />
        </bean>
        <bean parent="subview">
          <property name="name" value="end" />
          <property name="readOnly" value="true" />
        </bean>

        <bean parent="subview">
          <property name="name" value="grossWageComponent" />
          <property name="readOnly" value="true" />
        </bean>

      </list>
    </property>
  </bean>

      <bean
        id="contractMasterDetailActionMap"
        parent="masterDetailActionMap">
        <property name="parentActionMaps">
          <list>
            <ref bean="masterDetailActionMap" />
          </list>
        </property>
        <property name="actionLists">
          <list>
            <bean class="org.jspresso.framework.view.action.ActionList">
              <property name="name"    value="POPSUITE" />
              <property name="actions">
                <list>
                  <ref local="editContractAction" />
                  <ref local="createPayslipsFrontAction" />
                  <ref local="printPayslipsFrontAction" />
                </list>
              </property> 
            </bean>         
          </list>
        </property>
      </bean>

  <bean
    id="editContractAction"
    parent="editComponentFromCollectionAction">
        <property name="nextAction">
            <bean parent="editAndSaveComponentAction">
                <property name="viewDescriptor" ref="contract.and.periods.pane" />
            </bean>
        </property>
  </bean>

 

 

 

 

vvandens
Offline
Joined: 05/29/2008
That's a bug in the wizard action !

Pierre,

This was the missing piece of information... Your wizard is triggered from a dialog (the one you use to display/edit the selected contract) and not from the main application window. And there's a bug in that case that makes the wizard action reuse the existing dialog to display the first wizard step. Reusing the top dialog is fine for all other steps but the first one. The bug does not appear when using a wizard from the top application window since there is no dialog to reuse...
Afterwards, when the wizard dialog closes, the framework restores the initial action context that is the wrong one (it should have remained on the context of your edit component dialog) => wrong types infered for executing the add action :-(

The fix is quite simple but I can't deploy it right now. Here under is the patch to apply to the WizardAction class in case you would like to test it. Thanks for reporting the bug !

Regards,
Vincent

Index: WizardAction.java
===================================================================
--- WizardAction.java (revision 1870)
+++ WizardAction.java (working copy)
@@ -59,7 +59,8 @@
     }
     completeInitialWizardModel(wizardModel, context);
     modelConnector.setConnectorValue(wizardModel);
-    displayWizardStep(firstWizardStep, modelConnector, actionHandler, context);
+    displayWizardStep(firstWizardStep, modelConnector, actionHandler, context,
+        false);
     return true;
   }
 
@@ -225,7 +226,7 @@
 
   private void displayWizardStep(IWizardStepDescriptor wizardStep,
       IValueConnector modelConnector, IActionHandler actionHandler,
-      Map<String, Object> context) {
+      Map<String, Object> context, boolean reuseCurrent) {
 
     ITranslationProvider translationProvider = getTranslationProvider(context);
     Locale locale = getLocale(context);
@@ -241,7 +242,7 @@
         view.getPeer(),
         createWizardStepActions(wizardStep, view, actionHandler,
             translationProvider, locale, modelConnector, context), title,
-        getSourceComponent(context), context, dialogSize, true);
+        getSourceComponent(context), context, dialogSize, reuseCurrent);
   }
 
   private class CancelAction extends AbstractFrontendAction<E, F, G> {
@@ -355,7 +356,7 @@
         IWizardStepDescriptor nextWizardStep = wizardStep
             .getNextStepDescriptor(context);
         displayWizardStep(nextWizardStep, modelConnector, actionHandler,
-            context);
+            context, true);
         if (nextWizardStep.getOnEnterAction() != null) {
           actionHandler.execute(nextWizardStep.getOnEnterAction(), context);
         }
@@ -381,7 +382,7 @@
       IWizardStepDescriptor previousWizardStep = wizardStep
           .getPreviousStepDescriptor(context);
       displayWizardStep(previousWizardStep, modelConnector, actionHandler,
-          context);
+          context, true);
       return true;
     }
   }
atao
Offline
Joined: 10/15/2008
Thanks and request

Vincent,

Thank you for the patch. It works fine.

And now two requests!

1/ a more versatile IEnumerationPropertyDescriptor i.e. a generic one:

Any objection against a generic IEnumerationPropertyDescriptor<E>, i.e. with:

    List<E> getEnumerationValues();
    String getIconImageURL(E value);

and then in BasicEnumerationPropertyDescriptor a attribute valuesAndIconImageUrls of type Map<E, String>?

2/ a more versatile AddCollectionToMasterAction

    with a new method

    protected IComponentDescriptor<IEntity> getEntityDescriptor(Map<String, Object> context) {
        return elementEntityDescriptor;
    }

    which is called from the execute method:

    public boolean execute(IActionHandler actionHandler,
            Map<String, Object> context) {
        Map<String, Object> varContext = context;
        if (varContext == null) {
            varContext = new HashMap<String, Object>();
        }
        IComponentDescriptor<IEntity> descriptor = getEntityDescriptor(context);
        varContext.put(ActionContextConstants.ELEMENT_DESCRIPTOR,
                descriptor);
        return super.execute(actionHandler, varContext);
    }

Regards

Pierre

vvandens
Offline
Joined: 05/29/2008
Requests

Pierre,

Thank you for the patch. It works fine.

You welcome. This one was hard to track... The new snapshot including the fix is deploying right now.

 

Regarding your requests, I've implemented #2 and it's also in the snapshot.

I'm a little more concerned with #1. Enumeration values are to be considered as constants. Wether they are strings or anything else doesn't really matter or am I missing something ? Take the example of java enums, I think that they are stored as strings internally but does anyone care ?

Moreover, it has a bigger impact on code than I expected, e.g. :

  • You you would have to explicitely set a property type on it for the generator to infer the correct mapping and property class,
  • You have to transmit the values over the wire for the flex and Qooxdoo frontend. How can you be sure that the type of the values are actually supported by the communication protocol ? Even if you transmit them as their toString() value, are you sure that you can do the reverse fromString() operation when the value is comming back ?
  • Maybe other caveats I don't foresee now.

But having said that, I'm opened to any use-case that could convince me that it would give a real advantage over the simple-yet-robust string constants Wink.

 

Best,

Vincent

atao
Offline
Joined: 10/15/2008
Request #1: geneic IEnumerationPropertyDescriptor

Vincent,

 Enumeration values are to be considered as constants. Wether they are strings or anything else doesn't really matter

Yes

java enums, I think that they are stored as strings internally

Even when they have custombuild properties and methods?

use case: mine is quite simple.

ContractPeriod is a abstract type, with many subtypes (work, leave, strike...). Each period is ownn by a contract. When working with a contract, the user can see the list of the periods associated. And when a new one is needed, the user must choice which type is needed.

As each subtype is defined by a bean, I try to directly use these beans as key of the map used in the wizard step. Then I can avoid the search of the selected bean from a constant string used as map key. See code below.

I have tested it only with Swing configuration. I'll do it with other ones right now. Stay tune :-)

By the way, why not sticking with strings as map keys. But then it would be nice to be able to use more complex value than only the icon file path...

Regards

Pierre

 

================================================

  <bean
    id="getContractPeriodTypeWizardStep"
    class="org.jspresso.framework.application.frontend.action.wizard.StaticWizardStepDescriptor"
    >
    <property name="viewDescriptor">
      <bean
        class="org.jspresso.framework.view.descriptor.basic.BasicComponentViewDescriptor">
        <property name="modelDescriptor">
          <bean
            class="org.jspresso.framework.model.descriptor.basic.BasicComponentDescriptor">
            <property name="propertyDescriptors">
              <list>
                <bean class="org.jspresso.framework.model.descriptor.basic.BasicEnumerationPropertyDescriptor">
                  <property name="name"            value="contractPeriodType" />
                  <property name="enumerationName" value="contractPeriodType2" />
                  <property name="mandatory"       value="true" />
                  <property name="valuesAndIconImageUrls">
                    <map>
                      <entry key-ref="WorkPeriod" value="classpath:org/popsuite/hr/images/tool-48x48.png" />
                      <entry key-ref="LeavePeriod" value="classpath:org/popsuite/hr/images/armchair-48x48.png" />
                      <entry key-ref="StrikePeriod" value="classpath:org/popsuite/hr/images/fist-48x48.png" />
                    </map>
                  </property>
                </bean>
              </list>
            </property>
          </bean>   
        </property> 
      </bean>
    </property>
  </bean>

vvandens
Offline
Joined: 05/29/2008
Generic enumeration property descriptor

Pierre,

I understand the goal now. However I have 2 remarks :

  • Your use-case is on the wizard action. The wizard views are backed by a hashmap hierarchy model. It is naturally untyped and it will have no problem accepting whatever value you will provide it for a given property. But when your model is strongly typed (e.g. an entity, a component) the accessors have to be typed by the underlying property type and the ORM must also support it and be configured for it. Or the property should be typed as Object (or Serializable) and you will loose typing.
  • In your precise case, there is also another option that consists in using a collection instead of a enumeration property. You can then describe each of your period type in a bean (or a map) with a name, a description, and the referenced entity descriptor. Then you can build a readonly table view out of this singleton collection (the collection could even be constructed in spring and injected in the action) and get back the selected row out of the wizard, giving you the referenced descriptor. This might be a lot more flexible than a single enumeration property.

 

Best,

Vincent