[prev in list] [next in list] [prev in thread] [next in thread] 

List:       jakarta-commons-dev
Subject:    RE: [Betwixt] Possible enhancement (Issues with BigDecimal, TimeS
From:       "Tyree, Stan" <stant () firepond ! com>
Date:       2002-09-30 19:49:42
[Download RAW message or body]

Martin van den Bemt,

Thank you for responding to my e-mail.  I'm not sure I understand your
solution though.  I haven't used the java.beans package before so If I seem
a little ignorant, you will know why.  When looking at your suggestions, It
wasn't clear to me how the java.beans.Introspector class would help me
create the BigDecimal and Timestamp objects.

Please let me state some of the issues that I am seeing and re-state the
ones from my last e-mail to see if we are talking about the same problem.  I
know some of the issues listed here are a direct result of the java objects
not conforming to the bean specification.

1.  BeanWriter doesn't write out BigDecimal information.  
    This isn't really a problem with betwixt, but with the lack of a set/get
property on a BigDecimal.  
    I don't know how betwixt or I would handle this.  I noticed this after I
sent the last e-mail.

2.  BeanReader doesn't know how to create java objects that do not have a
default constructor. 
    (e.g. BigDecimal & Timestamp).  

3.  BeanReader doesn't know how to create java objects from interfaces.
    In my test example below, I have two Object TestA and TestB that
implement ITest.
    When BeanReader tries to re-create the bean inside the collection, it
fails because it is 
    trying to create an interface. 
  
The suggestion that I was proposing basically, allowed me to add a hook for
creating the beans for the BeanReader.  This does solve issues 2 & 3 for me,
but didn't address 1.


Thank you for your time,


Stan Tyree



TEST CASE: 

    protected static int IDX_STRING = 0;
    protected static int IDX_BIGDECIMAL = 1;
    protected static int IDX_INTEGER = 2;
    protected static int IDX_SHORT = 3;
    protected static int IDX_LONG = 4;
    protected static int IDX_DOUBLE = 5;
    protected static int IDX_TIMESTAMP = 6;
    protected static int IDX_BOOLEAN = 7;
    protected static int IDX_FLOAT = 8;

    protected static Object[]   A_VALUES = new Object[]
    {
        "12",
        new java.math.BigDecimal("12"),
        new Integer(12),
        new Short("12"),
        new Long(12),
        new Double(12.12),
        new Timestamp(1358014332546L),
        new Boolean(false),
        new Float(12.12)
    }

	public void testWriter()
	{
        	// Lets first create a class 
        	TestA aTest = new TestA();
       	aTest.setBigDecimalValue((BigDecimal)A_VALUES[IDX_BIGDECIMAL] );
	    	aTest.setTimestampValue((Timestamp)A_VALUES[IDX_TIMESTAMP]);
	    	aTest.setStringValue((String)A_VALUES[IDX_STRING]);
	    	aTest.setIntegerValue((Integer)A_VALUES[IDX_INTEGER]);
	    	aTest.setLongValue((Long)A_VALUES[IDX_LONG]);
	    	aTest.setDoubleValue((Double)A_VALUES[IDX_DOUBLE]);
	    	aTest.setBooleanValue((Boolean)A_VALUES[IDX_BOOLEAN]);
	
aTest.setIValue(((Integer)A_VALUES[IDX_INTEGER]).intValue());
	    	aTest.setLValue(((Long)A_VALUES[IDX_LONG]).longValue());
	
aTest.setDValue(((Double)A_VALUES[IDX_DOUBLE]).doubleValue());
	
aTest.setBValue(((Boolean)A_VALUES[IDX_BOOLEAN]).booleanValue());


	    	TestB bTest = new TestB();
	
bTest.setBigDecimalValue((BigDecimal)B_VALUES[IDX_BIGDECIMAL] );
	    	bTest.setTimestampValue((Timestamp)B_VALUES[IDX_TIMESTAMP]);
	    	bTest.setStringValue((String)B_VALUES[IDX_STRING]);
	    	bTest.setIntegerValue((Integer)B_VALUES[IDX_INTEGER]);
	    	bTest.setLongValue((Long)B_VALUES[IDX_LONG]);
	    	bTest.setDoubleValue((Double)B_VALUES[IDX_DOUBLE]);
	    	bTest.setBooleanValue((Boolean)B_VALUES[IDX_BOOLEAN]);
	
bTest.setIValue(((Integer)B_VALUES[IDX_INTEGER]).intValue());
	    	bTest.setLValue(((Long)B_VALUES[IDX_LONG]).longValue());
	
bTest.setDValue(((Double)B_VALUES[IDX_DOUBLE]).doubleValue());
	
bTest.setBValue(((Boolean)B_VALUES[IDX_BOOLEAN]).booleanValue());
    	
	    	aTest.addItem(bTest);
		String sXML = toXMLString(aTest);
            System.out.println("XML\n" + sXML);

	    	StringReader reader = new StringReader(sXML);
	    	TestA aTest2 = (TestA) toBean(reader, TestA.class);
    }

    public Object toBean(Reader oReader, Class oBeanClass) throws Exception
    {
	  BeanReader reader = new BeanReader();
	  reader.registerBeanClass(oBeanClass);
	  Object obj = reader.parse(oReader);
	  return obj;
    }

    public String toXMLString(Object domObject) throws Exception
    {
    	StringWriter strWriter = new StringWriter();
    	BeanWriter beanWriter = new BeanWriter(strWriter);
    	beanWriter.enablePrettyPrint();
    	beanWriter.write(domObject);
      return strWriter.toString();
    }
	

	



TESTA.JAVA
public class TestA implements ITest
{
    protected BigDecimal bigDecimalValue;
    protected String stringValue;
    protected Integer integerValue;
    protected Long longValue;
    protected Double doubleValue;
    protected Boolean booleanValue;
    protected Timestamp timestampValue;
    protected int iValue;
    protected long lValue;
    protected double dValue;
    protected boolean bValue;
    protected Collection items = new ArrayList();

    public void addItem(ITest item){items.add(item);}
    public void removeItem(ITest item){items.remove(item);}

    public Collection getItems(){return items;}
    public void setItems(Collection value){items=value;}

    public BigDecimal getBigDecimalValue(){return bigDecimalValue;}
    public void setBigDecimalValue(BigDecimal value){bigDecimalValue =
value;}
    
    public Timestamp getTimestampValue(){return timestampValue;}
    public void setTimestampValue(Timestamp value){timestampValue = value;}

    public String getStringValue(){ return stringValue;}
    public void setStringValue(String value){ stringValue = value;}

    public Integer getIntegerValue(){return integerValue;}
    public void setIntegerValue(Integer value){integerValue = value;}

    public Long getLongValue(){return longValue;}
    public void setLongValue(Long value){longValue = value;}

    public Double getDoubleValue(){return doubleValue;}
    public void setDoubleValue(Double value){doubleValue = value;}

    public Boolean getBooleanValue(){return booleanValue;}
    public void setBooleanValue(Boolean value){booleanValue = value;}

    public int getIValue(){return iValue;}
    public void setIValue(int value){iValue = value;}

    public long getLValue(){return lValue;}
    public void setLValue(long value){lValue = value;}

    public double getDValue(){return dValue;}
    public void setDValue(double value){dValue = value;}

    public boolean getBValue(){return bValue;}
    public void setBValue(boolean value){bValue = value;}
}    

TESTB.JAVA
====================================================
public class TestB extends TestA
{
}
 

INTERFACE
====================================================
public interface ITest
{
    public void addItem(ITest item);
    public void removeItem(ITest item);

    public Collection getItems();
    public void setItems(Collection value);

    public BigDecimal getBigDecimalValue();
    public void setBigDecimalValue(BigDecimal value);
    
    public Timestamp getTimestampValue();
    public void setTimestampValue(Timestamp value);

    public String getStringValue();
    public void setStringValue(String value);

    public Integer getIntegerValue();
    public void setIntegerValue(Integer value);

    public Long getLongValue();
    public void setLongValue(Long value);

    public Double getDoubleValue();
    public void setDoubleValue(Double value);

    public Boolean getBooleanValue();
    public void setBooleanValue(Boolean value);

    public int getIValue();
    public void setIValue(int value);

    public long getLValue();
    public void setLValue(long value);

    public double getDValue();
    public void setDValue(double value);

    public boolean getBValue();
    public void setBValue(boolean value);
}


-----Original Message-----
From: Halvorson, Loren 
Sent: Monday, September 30, 2002 10:37 AM
To: Tyree, Stan
Subject: FW: [Betwixt] Possible enhancement




-----Original Message-----
From: Martin van den Bemt [mailto:mllist@mvdb.net] 
Sent: Monday, September 30, 2002 4:09 AM
To: Jakarta Commons Users List
Subject: Re: [Betwixt] Possible enhancement


Hi Loren,

I think a better way is to reinstate the beaninfo searchpath (see notes for
this in the XMLIntrospector.java). I blocked usage of it, since I came
across a default bean who was interfering with one of my xml files. So I
think it is probably better to add a useBeanInfoPath boolean, so you can
register the beans you created for TimeStamp and BigDecimal via 
the java.beans.Introspector class yourself.
The current way is to ignore that beaninfoPath information completely. So I
am in favour of using the things that are already there instead of
reacreating it. 
You can see if it works for you by commenting out the resetting and
restoring of the searchPath in the method introspect(Class aClass) in
XMLIntrospector and let me know if making you own bean for it works for you,
so I can add the boolean so the beanPath is not cleared anymore. 
(default will still be to clear it though, since it can give a lot of
unsuspected results which are hard to debug..)

Sorry if this reply is a bit messy, I just returned from the south of 
France and am in need of some sleep ;))

Let me know if you have any questions..

Mvgr,
Martin van den Bemt

 
On Fri, 2002-09-27 at 00:04, Halvorson, Loren wrote:
> (Posted on behalf of a colleague, Stan Tyree)
> 
> I just started using Betwixt and was amazed how easy it was to use. I 
> am working on a project where I am trying to use it as an 
> "import/export" tool for my Java beans. Betwixt has saved me a lot of 
> time and energy.
>  
> In the process doing my task, I ran into a small problem when using 
> the BeanReader to re-create my bean.  The bean contained BigDecimal 
> and Timestamp properties.  When the bean was exported, it worked fine.
> The problem arose when it tried to create either of these object types 
> inside "protected Object createBean(Attributes attributes)" method in 
> org.apache.commons.betwixt.io.BeanCreateRule.  This function calls the 
> "newInstance" function on the bean class for this rule.  Neither 
> Timestamp and BigDecimal have default constructors, so this fails.  I 
> made some small changes to BeanReader and BeanCreateRule to fix this 
> issue.  I was wondering if this change or something similar could be 
> added to the project, or is there already a way to handle this 
> situation using Betwixt that we just missed.
>  
> Below are the steps I took to fix my problem.  If you want to see the 
> files, I can send those as well.
>  
> 1.  I created an interface for creating objects.
>  
>   package org.apache.commons.betwixt.io;
>   import org.xml.sax.Attributes;
>   /**
>    * This interface is used to create beans that do not
>    * have a default constructor.
>    */
>   public interface BeanCreator {
>     public Object createBean(BeanCreateRule rule,
>                              Attributes attributes)
>                   throws Exception;
>   };
>  
> 2.  On the BeanReader class, I added a Hashtable and methods to 
> support it:
>  
>   private Hashtable creatorMap = new Hashtable();
>  
>   public void addBeanCreator(String sPath, BeanCreator creator) {
>     creatorMap.put(sPath, creator);
>   }    
>  
>   public BeanCreator getBeanCreator(String sPath) {
>     return (BeanCreator)creatorMap.get(sPath);
>   }
>  
>   public void removeBeanCreators(String sPath) {
>     creatorMap.remove(sPath);
>   }
>  
>   public void clearBeanCreators() {
>     creatorMap.clear();
>   }
> 
> 3.  On the BeanCreateRule, I changed the function "createBean" to:
>  
>   protected Object createBean(Attributes attributes) throws Exception 
>    :
>   try {
>     BeanCreator beanCreator = 
> getBeanReader().getBeanCreator(beanClass.getName());
>     if (beanCreator != null)
>       return beanCreator.createBean(this, attributes);
>     else
>       return beanClass.newInstance();
>   }
>   catch (Exception e) {
>     log.warn( "Could not create instance of type: " + beanClass.getName()
);
>     return null;
>   }
>  
> After these changes, you can create a bean with BigDecimal and 
> Timestamp functions by doing the following:
>  
>   BeanCreator tsCreator = new BeanCreator()
>   {
>     public Object createBean(BeanCreateRule rule, Attributes
> attributes) throws Exception
>     {
>       Timestamp ts = new Timestamp(new
> java.util.GregorianCalendar().getTime().getTime());
>       return ts;
>     }
>   };
>   BeanCreator bigdCreator = new BeanCreator()
>   {
>     public Object createBean(BeanCreateRule rule, Attributes 
> attributes) throws Exception
>     {
>       BigDecimal bd = new BigDecimal(0.0d);
>       return bd;
>     }
>   };
>  
>   BeanReader reader = new BeanReader();
>   reader.addBeanCreator("java.math.BigDecimal", bigdCreator);
>   reader.addBeanCreator("java.sql.Timestamp", tsCreator);
>   Object bean = reader.parse(new File("testBean.xml"));
> 
> Thank you for your time,
> 
> Stan Tyree
> 
> --
> To unsubscribe, e-mail:
<mailto:commons-user-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: 
> <mailto:commons-user-help@jakarta.apache.org>
> 
> 



--
To unsubscribe, e-mail:
<mailto:commons-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail:
<mailto:commons-user-help@jakarta.apache.org>

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic