You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Miguel Almeida <mi...@almeida.at> on 2012/09/20 18:45:14 UTC

Type conversion on a Map

Dear all,

Considering:
1) the action property Map<CodeProperty, String> complexMap;
2) CodeProperty has an int id property

How would you configure type conversion and refer to it on the JSP to
populate it?

I am currently trying the following -conversion configuration:
KeyProperty_complexMap=id
Element_complexMap=java.lang.String
Key_complexMap=persist.model.CodeProperty
CreateIfNull_complexMap=true


However, a simple jUnit test where I populate the request with
getRequest().setParameter("complexMap[" + String.valueOf(33) +
"]","test") doesn't populate the map as expected.

Is the -conversion file wrong, the parameter set in the unit test, or
both?

Cheers,

Miguel Almeida

Re: Type conversion on a Map

Posted by Lukasz Lenart <lu...@apache.org>.
2012/9/21 Miguel Almeida <mi...@almeida.at>:
> Sure!
>
> Here's a maven project with a failing test case.
>
> There's actually a map being built, but it's a <String,String>, and the key
> reads "OGNL no conversion possible".

Got it working, but I think the main problem is with key value - it
isn't a simple string but an int that must be converted to complex
class Entity.

First thing, in TypeConversionAction-conversion.properties just put:
Key_simpleMap=test.example.Entity
Element_simpleMap=java.lang.String
CreateIfNull_codePropertyMap=true

Next create xwork-conversion.properties in the root folder
(src/java/resources) with:
test.example.Entity=test.example.EntityConverter

And the very end create EntityConverter (Struts2 must know how to
convert int into Entity)

public class EntityConverter extends StrutsTypeConverter {

    @Override
    public Object convertFromString(Map context, String[] values,
Class toClass) {
        if (values != null && values.length > 0) {
            Entity entity = new Entity();
            entity.setId(Integer.parseInt(values[0]));
            return entity;
        }
        return null;
    }

    @Override
    public String convertToString(Map context, Object o) {
        if (o != null) {
            return "" + ((Entity) o).getId();
        }
        return null;
    }

    @Override
    public Object convertValue(Map context, Object o, Class toClass) {
        if (toClass == Entity.class) {
            return convertFromString(context, new
String[]{o.toString()}, toClass);
        }
        return super.convertValue(context, o, toClass);
    }
}

The problem is in convertValue() method which supports only String
based conversions (but simpleMap[1] => key = 1 was already converted
to int) - and I'm thinking that the method should be changed from

    public Object convertValue(Map context, Object o, Class toClass) {
        if (toClass.equals(String.class)) {
            return convertToString(context, o);
        } else if (o instanceof String[]) {
            return convertFromString(context, (String[]) o, toClass);
        } else if (o instanceof String) {
            return convertFromString(context, new String[]{(String)
o}, toClass); // <-- problematic line
        } else {
            return performFallbackConversion(context, o, toClass);
        }
    }

to

    public Object convertValue(Map context, Object o, Class toClass) {
        if (toClass.equals(String.class)) {
            return convertToString(context, o);
        } else if (o instanceof String[]) {
            return convertFromString(context, (String[]) o, toClass);
// <-- changed
        } else {
            return convertFromString(context, new
String[]{o.toString()}, toClass);
        }
    }

I've been using Struts 2.3.5-SNAPSHOT


Kind regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


RE: Type conversion on a Map

Posted by Miguel Almeida <mi...@almeida.at>.
On Fri, 2012-09-21 at 09:04 -0400, Martin Gainty wrote:

> a stupid question but i have to ask

If you mean "where is the initialisation of simpleMap e.g. simpleMap=new
java.util.HashMap();" - it's not there. I don't think you need to,
Struts initializes it. (see below)

> 
> public class TypeConversionAction extends ActionSupport 
> {
>     private Map<Entity, String> simpleMap;   //where is the initialisation of simpleMap e.g. simpleMap=new java.util.HashMap();
>     public Map<Entity, String> getSimpleMap()  { return simpleMap;  }
>     public void setSimpleMap(Map<Entity, String> simpleMap) {   this.simpleMap = simpleMap; }
>     public String execute() {  return SUCCESS; }
> }
> 
> //then the test-harness:
> 
> package test.example;
> import java.util.Map;
> import org.apache.struts2.StrutsTestCase;
> import org.junit.Test;
> import com.opensymphony.xwork2.ActionProxy;
> import com.opensymphony.xwork2.ActionSupport;
> 
> public class TypeConversionTest extends StrutsTestCase 
> {
> private ActionProxy actionProxy;    
> private ActionSupport action;
> 
> @Test
> public void test() throws Exception{
>     Entity entity = new Entity();
>     entity.setId(1);
>     super.setUp();
> 
>     request.setParameter("simpleMap[1]", "value");
>     createAction("/example/Convesion.action");        
>     executeProxy();
> 
>     Map<Entity, String> complexMap = ((TypeConversionAction) action).getSimpleMap();
>     assertNotNull(complexMap);   //getSimpleMap is NULL in the Action so it would always be NULL here

No. The test fails below, not here. executeProxy executed the action and
initialized the map. If you run the test you'll see it fails on the last
assertEquals, not here.

>         
>     assertFalse(complexMap.isEmpty());  //FAIL it is empty
>     assertEquals("value", complexMap.get(entity));     //Never initialised so this would fail as well

This is where it is failing. Not because it hasn't been initialized, but
because it doesn't have that key.

Miguel Almeida

RE: Type conversion on a Map

Posted by Martin Gainty <mg...@hotmail.com>.
a stupid question but i have to ask

public class TypeConversionAction extends ActionSupport 
{
    private Map<Entity, String> simpleMap;   //where is the initialisation of simpleMap e.g. simpleMap=new java.util.HashMap();
    public Map<Entity, String> getSimpleMap()  { return simpleMap;  }
    public void setSimpleMap(Map<Entity, String> simpleMap) {   this.simpleMap = simpleMap; }
    public String execute() {  return SUCCESS; }
}

//then the test-harness:

package test.example;
import java.util.Map;
import org.apache.struts2.StrutsTestCase;
import org.junit.Test;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionSupport;

public class TypeConversionTest extends StrutsTestCase 
{
private ActionProxy actionProxy;    
private ActionSupport action;

@Test
public void test() throws Exception{
    Entity entity = new Entity();
    entity.setId(1);
    super.setUp();

    request.setParameter("simpleMap[1]", "value");
    createAction("/example/Convesion.action");        
    executeProxy();

    Map<Entity, String> complexMap = ((TypeConversionAction) action).getSimpleMap();
    assertNotNull(complexMap);   //getSimpleMap is NULL in the Action so it would always be NULL here
        
    assertFalse(complexMap.isEmpty());  //FAIL it is empty
    assertEquals("value", complexMap.get(entity));     //Never initialised so this would fail as well
}

/**
     * Creates the action with the given actionPath if it wasn't already created
     * @see isAlreadyCreated
     * @param actionPath
* @throws Exception
*/
public ActionSupport createAction(String actionPath) throws Exception 
{
    actionProxy = getActionProxy(actionPath);
    action = (ActionSupport) actionProxy.getAction();
    return action;   
}
    
/**
     * Executes the action created and returns the result 
     * @return
         * @throws Exception
     */
public String executeProxy() throws Exception {
    actionProxy.setExecuteResult(false);        
    return actionProxy.execute();
}
}

?

Saludos,
Martin 
______________________________________________ 
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.
Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.


Subject: Re: Type conversion on a Map
From: miguel@almeida.at
To: user@struts.apache.org
Date: Fri, 21 Sep 2012 10:31:24 +0100




  
  


Sure!



Here's a maven project with a failing test case.



There's actually a map being built, but it's a <String,String>, and the key reads "OGNL no conversion possible".



Cheers,

Miguel Almeida



On Thu, 2012-09-20 at 19:44 +0200, Lukasz Lenart wrote:

Hi,

Could you share the unit test as well ? The whole code would be the best :-)


Regards







---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org 		 	   		  

Re: Type conversion on a Map

Posted by Miguel Almeida <mi...@almeida.at>.
Sure!

Here's a maven project with a failing test case.

There's actually a map being built, but it's a <String,String>, and the
key reads "OGNL no conversion possible".

Cheers,
Miguel Almeida

On Thu, 2012-09-20 at 19:44 +0200, Lukasz Lenart wrote:

> Hi,
> 
> Could you share the unit test as well ? The whole code would be the best :-)
> 
> 
> Regards



Re: Type conversion on a Map

Posted by Lukasz Lenart <lu...@apache.org>.
Hi,

Could you share the unit test as well ? The whole code would be the best :-)


Regards
-- 
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org