You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Henning P. Schmiedehausen" <hp...@intermeta.de> on 2004/07/13 17:51:07 UTC

[BETWIXT] Array of bytes anyone?

Hi,

for a project, I need Betwixt to convert a special sort of beans into
XML. Beans, which contain a byte [] property (They come from Hibernate
which maps BINARY and TEXT onto these types, which is fine).

Regular Betwixt builds something like

<foo>
  <byte>0</byte>
  <byte>1</byte>
  <byte>2</byte>
  <byte>3</byte>
</foo>

for propery foo, which is not exactly the most efficient way to
express this array of bytes. Especially if it has about 5 MBytes
size. ;-) 

I was wondering whether I could get this done with regular betwixt but
the isPrimitive() in XMLIntrospectorHelp always bite me. In the end I
came up with the attached patch, which works fine for me (it might not
be ideal, because the resulting XML contains the raw sew^Wbinary data
if you write the bean out.

For my application I extend the DefaultObjectStringConverter to do
base64 encoding on the fly and end up with nice looking XML like this:

<foo attr1="1" attr2="2" attr3="3">
  <binary>
xCHPdC7mAlirPoYY8dZr1fACaXAqpW83BKOz//yCMWUkzgtkvkMhD0MwQpclKdsOhHB1PbaRzbxA
5KmsIprAxtG5Vkm2ze5jRUPY+og3Rqq5ccj19BL6joB0PKQmnJRlU0bw9ZGJntrIVH4g9Lq1E4Sx
bquW8iIOBGvsE3kYaW0bbf1mdPT2ubNnW2+fbm17wnhQxw9Ertbz1M69Mdp649/TZ//64WVw6Gg5
aLwq2161CMeKB0glbtMXxpNGASDG4G42q16YDtOIbJwRF429GLfpc+OJAI7UkHhGvx+cDcHYbTUC
YoSnsRNN+jn9AfcogqRDz/SfejeSC8FY0WQzggCCM8LT2BdjNs3T9fNEgCzWMyXRTRSCofdVFiD2
L1cSbZxSgQAAAABJRU5ErkJggg==
  </binary>
</foo>

which is exactly what I need. 

I was wondering if it would be more clever to allow the user to
explicitly set the primitiveType property of the element descriptor
from the .betwixt file. I found no way to do so, though and I already
had this patch which works for me.

Anyway, here is the patch, discussions welcome. ;-) This is against
CVS HEAD. I would volunteer to write an Unit test for it if has a
chance to get applied.

	Regards
		Henning

--- cut ---
Index: src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java
===================================================================
RCS file: /home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java,v
retrieving revision 1.31
diff -u -r1.31 XMLIntrospectorHelper.java
--- src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java	4 Jul 2004 16:40:49 -0000	1.31
+++ src/java/org/apache/commons/betwixt/digester/XMLIntrospectorHelper.java	13 Jul 2004 15:39:37 -0000
@@ -583,6 +583,8 @@
             
         } else if ( type.equals( Object.class ) ) {
             return false;
+        } else if (type.equals ( byte [].class) ) {
+            return true;
         }
         return type.getName().startsWith( "java.lang." )
             || Number.class.isAssignableFrom( type ) 
Index: src/java/org/apache/commons/betwixt/strategy/DefaultObjectStringConverter.java
===================================================================
RCS file: /home/cvs/jakarta-commons/betwixt/src/java/org/apache/commons/betwixt/strategy/DefaultObjectStringConverter.java,v
retrieving revision 1.10
diff -u -r1.10 DefaultObjectStringConverter.java
--- src/java/org/apache/commons/betwixt/strategy/DefaultObjectStringConverter.java	4 Jul 2004 16:57:05 -0000	1.10
+++ src/java/org/apache/commons/betwixt/strategy/DefaultObjectStringConverter.java	13 Jul 2004 15:39:37 -0000
@@ -66,7 +66,8 @@
             if ( object instanceof java.util.Date && isUtilDate( type ) ) {
                 
                 return formatter.format( (java.util.Date) object );
-                
+            } else if ( object instanceof byte[]) {
+                return new String((byte []) object);
             } else {
                 // use ConvertUtils implementation
                 return super.objectToString( object, type, flavour, context );
@@ -98,6 +99,8 @@
                     // but never mind
                     return value;
                 }
+            } else if (type.equals(byte [].class)) {
+                return value.getBytes();
             } else {
                 // use ConvertUtils implementation
                 return super.stringToObject( value, type, flavour, context );
--- cut ---

-- 
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen          INTERMETA GmbH
hps@intermeta.de        +49 9131 50 654 0   http://www.intermeta.de/

RedHat Certified Engineer -- Jakarta Turbine Development  -- hero for hire
   Linux, Java, perl, Solaris -- Consulting, Training, Development

"Fighting for one's political stand is an honorable action, but re-
 fusing to acknowledge that there might be weaknesses in one's
 position - in order to identify them so that they can be remedied -
 is a large enough problem with the Open Source movement that it
 deserves to be on this list of the top five problems."
                       -- Michelle Levesque, "Fundamental Issues with
                                    Open Source Software Development"

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


Re: [BETWIXT] Array of bytes anyone?

Posted by robert burrell donkin <ro...@blueyonder.co.uk>.
On 14 Jul 2004, at 08:44, Henning Schmiedehausen wrote:

> On Wed, 2004-07-14 at 00:09, robert burrell donkin wrote:
>> On 13 Jul 2004, at 16:51, Henning P. Schmiedehausen wrote:

<snip>

>> XMLIntrospectorHelper is very limiting and will hopefully be 
>> completely
>> deprecated sometime soon. the primitives concept needs to be extended
>> into the more flexible concept of simple type. (the simple type 
>> concept
>> is more often used in the xml-object binding community.) the 
>> refactored
>> code with improved design has been merged into HEAD now and some of
>> these changes in this direction have been made (but i've lost track a
>> bit since i'm currently juggling a number of releases at the moment).
>> just FYI the plan is to cut a 1.6 based on the improved design very
>> soon.
>
> This sounds nice. I felt that the XMLIntrospectionHelper is not 
> flexible
> enough to fit to all needs. Getting it pluggable through a strategy
> object would help here.

+1

i took a look into the current state of the code. i've deprecated the 
isPrimitive method and replaced with a strategy (but more work's need 
since it needs to support simple types and attributes as well).

just have isLoop to go before XMLIntrospectorHelper can be deprecated...

>>> In the end I came up with the attached patch, which works fine for me
>>> (it might not
>>> be ideal, because the resulting XML contains the raw sew^Wbinary data
>>> if you write the bean out.
>>
>> i'm not sure i parse this correctly. (it's a little late, so it might
>> be me.) care to expand?
>
> It's simple. With this patch, when you introspect a bean that contains
> a byte [] array, you might end up with <foo bytes="random noise right
> from the bean"> without any escaping or CDATA encapsulation. Most of 
> the
> times, this is not what the developer wants (and it might not be valid
> XML).

that's what i thought you meant :)

probably the best way to fix this would be to use a CDATA strategy for 
the mixed text. should be compatible with the custom object string 
converter.

> In my application I have a custom converter which does
>
> import org.apache.commons.codec.binary.Base64;
>
> public class CustomConverter
>         extends DefaultObjectStringConverter
> {
>   public String objectToString(Object object, Class type, String 
> flavour, Context context)
>   {
>      if (object instanceof byte[]) {
>        return new String(Base64.encodeBase64Chunked(object), 
> "ISO-8859-1");
>      } else {
>        return super.objectToString(object, type, flavour, context);
>      }
>   }
>
>   public Object stringToObject(String value, Class type, String 
> flavour, Context context)
>   {
>     if (type.equals(byte [].class)) {
>       return Base64.decodeBase64(value.getBytes("ISO-8859-1"));
>     } else {
>       return super.stringToObject(value, type, flavour, context);
>     }
>   }
> }
>
> So I get my byte arrays converted into base64 Strings.
>
> [...]

cool

>>> Anyway, here is the patch, discussions welcome. ;-) This is against
>>> CVS HEAD. I would volunteer to write an Unit test for it if has a
>>> chance to get applied.
>>
>> there is every chance that a fix for this would get committed with a
>> unit test :)
>>
>> i have an idea that the patch is against the 0.5 code base (but i 
>> could
>> be wrong since i haven't looked into this in detail). please set my
>> suspicious mind at rest by updating before you start getting into 
>> this.
>
> Well, it is against CVS HEAD, which identifies itself as 0.6-dev in the
> project.xml. Is there another version?

nope, that's it :)

- robert


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


Re: [BETWIXT] Array of bytes anyone?

Posted by Henning Schmiedehausen <hp...@intermeta.de>.
On Wed, 2004-07-14 at 00:09, robert burrell donkin wrote:
> On 13 Jul 2004, at 16:51, Henning P. Schmiedehausen wrote:
> 
> > Hi,
> 
> hi henning

Hi,


> XMLIntrospectorHelper is very limiting and will hopefully be completely  
> deprecated sometime soon. the primitives concept needs to be extended  
> into the more flexible concept of simple type. (the simple type concept  
> is more often used in the xml-object binding community.) the refactored  
> code with improved design has been merged into HEAD now and some of  
> these changes in this direction have been made (but i've lost track a  
> bit since i'm currently juggling a number of releases at the moment).  
> just FYI the plan is to cut a 1.6 based on the improved design very  
> soon.

This sounds nice. I felt that the XMLIntrospectionHelper is not flexible
enough to fit to all needs. Getting it pluggable through a strategy
object would help here.

> > In the end I came up with the attached patch, which works fine for me  
> > (it might not
> > be ideal, because the resulting XML contains the raw sew^Wbinary data
> > if you write the bean out.
> 
> i'm not sure i parse this correctly. (it's a little late, so it might  
> be me.) care to expand?

It's simple. With this patch, when you introspect a bean that contains
a byte [] array, you might end up with <foo bytes="random noise right
from the bean"> without any escaping or CDATA encapsulation. Most of the
times, this is not what the developer wants (and it might not be valid
XML). In my application I have a custom converter which does

import org.apache.commons.codec.binary.Base64;

public class CustomConverter
        extends DefaultObjectStringConverter
{
  public String objectToString(Object object, Class type, String flavour, Context context)
  {
     if (object instanceof byte[]) {
       return new String(Base64.encodeBase64Chunked(object), "ISO-8859-1");
     } else {
       return super.objectToString(object, type, flavour, context);
     }
  }

  public Object stringToObject(String value, Class type, String flavour, Context context)
  {
    if (type.equals(byte [].class)) {
      return Base64.decodeBase64(value.getBytes("ISO-8859-1"));
    } else {
      return super.stringToObject(value, type, flavour, context);
    }
  }
}

So I get my byte arrays converted into base64 Strings.

[...]

> > I was wondering if it would be more clever to allow the user to
> > explicitly set the primitiveType property of the element descriptor
> > from the .betwixt file. I found no way to do so, though and I already
> > had this patch which works for me.
> 
> the answer is yes but the concept needs to move from a fixed list of  
> primitives to a flexible, configurable (with strategy plugin as well as  
> property) simple type binding. this is definitely on the to-do list but  
> i'm right in the middle of managing various release cycles so i'm not  
> sure when i'll get the chance to look at this.
> 
> it should be pretty straightforward and i'd be willing to help explain  
> the new design, so if you'd like to volunteer to take this on, that  
> would be great.

I will take a look. No promises, though. 

> 
> > Anyway, here is the patch, discussions welcome. ;-) This is against
> > CVS HEAD. I would volunteer to write an Unit test for it if has a
> > chance to get applied.
> 
> there is every chance that a fix for this would get committed with a  
> unit test :)
> 
> i have an idea that the patch is against the 0.5 code base (but i could  
> be wrong since i haven't looked into this in detail). please set my  
> suspicious mind at rest by updating before you start getting into this.

Well, it is against CVS HEAD, which identifies itself as 0.6-dev in the
project.xml. Is there another version? 

	Regards
		Henning

-- 
Dipl.-Inf. (Univ.) Henning P. Schmiedehausen          INTERMETA GmbH
hps@intermeta.de        +49 9131 50 654 0   http://www.intermeta.de/
 
RedHat Certified Engineer -- Jakarta Turbine Development  -- hero for hire
   Linux, Java, perl, Solaris -- Consulting, Training, Development

"Fighting for one's political stand is an honorable action, but re-
 fusing to acknowledge that there might be weaknesses in one's
 position - in order to identify them so that they can be remedied -
 is a large enough problem with the Open Source movement that it
 deserves to be on this list of the top five problems."
                       --Michelle Levesque, "Fundamental Issues with
                                    Open Source Software Development"


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


Re: [BETWIXT] Array of bytes anyone?

Posted by robert burrell donkin <ro...@blueyonder.co.uk>.
On 13 Jul 2004, at 16:51, Henning P. Schmiedehausen wrote:

> Hi,

hi henning

> for a project, I need Betwixt to convert a special sort of beans into
> XML. Beans, which contain a byte [] property (They come from Hibernate
> which maps BINARY and TEXT onto these types, which is fine).
>
> Regular Betwixt builds something like
>
> <foo>
>   <byte>0</byte>
>   <byte>1</byte>
>   <byte>2</byte>
>   <byte>3</byte>
> </foo>
>
> for propery foo, which is not exactly the most efficient way to
> express this array of bytes. Especially if it has about 5 MBytes
> size. ;-)

yep

> I was wondering whether I could get this done with regular betwixt but
> the isPrimitive() in XMLIntrospectorHelp always bite me.
>

XMLIntrospectorHelper is very limiting and will hopefully be completely  
deprecated sometime soon. the primitives concept needs to be extended  
into the more flexible concept of simple type. (the simple type concept  
is more often used in the xml-object binding community.) the refactored  
code with improved design has been merged into HEAD now and some of  
these changes in this direction have been made (but i've lost track a  
bit since i'm currently juggling a number of releases at the moment).  
just FYI the plan is to cut a 1.6 based on the improved design very  
soon.

> In the end I came up with the attached patch, which works fine for me  
> (it might not
> be ideal, because the resulting XML contains the raw sew^Wbinary data
> if you write the bean out.

i'm not sure i parse this correctly. (it's a little late, so it might  
be me.) care to expand?

> For my application I extend the DefaultObjectStringConverter to do
> base64 encoding on the fly and end up with nice looking XML like this:
>
> <foo attr1="1" attr2="2" attr3="3">
>   <binary>
> xCHPdC7mAlirPoYY8dZr1fACaXAqpW83BKOz// 
> yCMWUkzgtkvkMhD0MwQpclKdsOhHB1PbaRzbxA
> 5KmsIprAxtG5Vkm2ze5jRUPY+og3Rqq5ccj19BL6joB0PKQmnJRlU0bw9ZGJntrIVH4g9Lq 
> 1E4Sx
> bquW8iIOBGvsE3kYaW0bbf1mdPT2ubNnW2+fbm17wnhQxw9Ertbz1M69Mdp649/TZ// 
> 64WVw6Gg5
> aLwq2161CMeKB0glbtMXxpNGASDG4G42q16YDtOIbJwRF429GLfpc+OJAI7UkHhGvx+cDcH 
> YbTUC
> YoSnsRNN+jn9AfcogqRDz/ 
> SfejeSC8FY0WQzggCCM8LT2BdjNs3T9fNEgCzWMyXRTRSCofdVFiD2
> L1cSbZxSgQAAAABJRU5ErkJggg==
>   </binary>
> </foo>
>
> which is exactly what I need.
>
> I was wondering if it would be more clever to allow the user to
> explicitly set the primitiveType property of the element descriptor
> from the .betwixt file. I found no way to do so, though and I already
> had this patch which works for me.

the answer is yes but the concept needs to move from a fixed list of  
primitives to a flexible, configurable (with strategy plugin as well as  
property) simple type binding. this is definitely on the to-do list but  
i'm right in the middle of managing various release cycles so i'm not  
sure when i'll get the chance to look at this.

it should be pretty straightforward and i'd be willing to help explain  
the new design, so if you'd like to volunteer to take this on, that  
would be great.

> Anyway, here is the patch, discussions welcome. ;-) This is against
> CVS HEAD. I would volunteer to write an Unit test for it if has a
> chance to get applied.

there is every chance that a fix for this would get committed with a  
unit test :)

i have an idea that the patch is against the 0.5 code base (but i could  
be wrong since i haven't looked into this in detail). please set my  
suspicious mind at rest by updating before you start getting into this.

- robert


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