Fixes issue 12632: DomainType should be extended with hibernatetype and xml conversion
authorMartin Taal <martin.taal@openbravo.com>
Tue, 06 Apr 2010 09:45:31 +0200
changeset 6924 fb97b5f3e905
parent 6923 cdfd97ab9a81
child 6925 0a2aa53b170f
Fixes issue 12632: DomainType should be extended with hibernatetype and xml conversion
src-test/org/openbravo/test/dal/IssuesTest.java
src-test/org/openbravo/test/model/RuntimeModelTest.java
src-test/org/openbravo/test/model/UtilsTest.java
src/org/openbravo/base/model/domaintype/BasePrimitiveDomainType.java
src/org/openbravo/base/model/domaintype/BigDecimalDomainType.java
src/org/openbravo/base/model/domaintype/BinaryDomainType.java
src/org/openbravo/base/model/domaintype/BooleanDomainType.java
src/org/openbravo/base/model/domaintype/ButtonDomainType.java
src/org/openbravo/base/model/domaintype/DateDomainType.java
src/org/openbravo/base/model/domaintype/DatetimeDomainType.java
src/org/openbravo/base/model/domaintype/LongDomainType.java
src/org/openbravo/base/model/domaintype/ObjectDomainType.java
src/org/openbravo/base/model/domaintype/PrimitiveDomainType.java
src/org/openbravo/base/model/domaintype/StringDomainType.java
src/org/openbravo/base/model/domaintype/StringEnumerateDomainType.java
src/org/openbravo/base/model/domaintype/TimestampDomainType.java
src/org/openbravo/dal/xml/EntityXMLConverter.java
src/org/openbravo/dal/xml/EntityXMLException.java
src/org/openbravo/dal/xml/ModelXMLConverter.java
src/org/openbravo/dal/xml/StaxXMLEntityConverter.java
src/org/openbravo/dal/xml/XMLEntityConverter.java
src/org/openbravo/dal/xml/XMLTypeConverter.java
--- a/src-test/org/openbravo/test/dal/IssuesTest.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src-test/org/openbravo/test/dal/IssuesTest.java	Tue Apr 06 09:45:31 2010 +0200
@@ -29,14 +29,13 @@
 import org.apache.log4j.Logger;
 import org.hibernate.criterion.Expression;
 import org.openbravo.base.model.Reference;
+import org.openbravo.base.model.domaintype.LongDomainType;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.structure.IdentifierProvider;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.dal.service.OBQuery;
-import org.openbravo.dal.xml.EntityXMLException;
-import org.openbravo.dal.xml.XMLTypeConverter;
 import org.openbravo.data.UtilSql;
 import org.openbravo.model.ad.module.Module;
 import org.openbravo.model.ad.system.Language;
@@ -187,11 +186,11 @@
    * Tests issue: https://issues.openbravo.com/view.php?id=11812
    */
   public void test11812() {
-    assertTrue(24 == XMLTypeConverter.getInstance().fromXML(Long.class, "24.0"));
+    assertTrue(24 == (Long) new LongDomainType().createFromString("24.0"));
     try {
-      XMLTypeConverter.getInstance().fromXML(Long.class, "24.5");
+      new LongDomainType().createFromString("24.5");
       fail("No exception on 24.5");
-    } catch (EntityXMLException e) {
+    } catch (ArithmeticException e) {
       // expected
     }
   }
--- a/src-test/org/openbravo/test/model/RuntimeModelTest.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src-test/org/openbravo/test/model/RuntimeModelTest.java	Tue Apr 06 09:45:31 2010 +0200
@@ -30,6 +30,7 @@
 import org.openbravo.base.model.Property;
 import org.openbravo.base.model.Reference;
 import org.openbravo.base.model.Table;
+import org.openbravo.base.model.domaintype.BasePrimitiveDomainType;
 import org.openbravo.test.base.BaseTest;
 
 /**
@@ -303,4 +304,25 @@
               + columns.toString());
     assertEquals(0, columns.size());
   }
+
+  public void testPrimitiveDomainTypeDefaultMethods() {
+    final CustomDomainType customDomainType = new CustomDomainType();
+    final long testNumber = 121;
+    final String strValue = customDomainType.convertToString(testNumber);
+    final long result = (Long) customDomainType.createFromString(strValue);
+    assertTrue(result == testNumber);
+  }
+
+  private static class CustomDomainType extends BasePrimitiveDomainType {
+
+    @Override
+    public Class<?> getPrimitiveType() {
+      return Long.class;
+    }
+
+    @Override
+    public String getXMLSchemaType() {
+      return "ob:long";
+    }
+  }
 }
--- a/src-test/org/openbravo/test/model/UtilsTest.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src-test/org/openbravo/test/model/UtilsTest.java	Tue Apr 06 09:45:31 2010 +0200
@@ -26,12 +26,12 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.structure.BaseOBObject;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.security.EntityAccessChecker;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
-import org.openbravo.dal.xml.XMLTypeConverter;
 import org.openbravo.model.ad.access.User;
 import org.openbravo.test.base.BaseTest;
 
@@ -84,7 +84,7 @@
     }
   }
 
-  public void _testWriteAll() throws Exception {
+  public void testWriteAll() throws Exception {
     // final StringWriter sw = new StringWriter();
     final FileWriter writer = new FileWriter("/home/mtaal/mytmp/test.csv");
 
@@ -124,7 +124,7 @@
           }
           // export primitives in the same way as xml primitives
           if (property.isPrimitive()) {
-            line.append(XMLTypeConverter.getInstance().toXML(value));
+            line.append(((PrimitiveDomainType) property.getDomainType()).convertToString(value));
           } else {
             // export the id of a referenced business object
             line.append(((BaseOBObject) value).getId());
--- a/src/org/openbravo/base/model/domaintype/BasePrimitiveDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/BasePrimitiveDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,6 +19,8 @@
 
 package org.openbravo.base.model.domaintype;
 
+import java.lang.reflect.Constructor;
+
 import org.openbravo.base.model.Property;
 import org.openbravo.base.validation.ValidationException;
 
@@ -30,14 +32,12 @@
  */
 public abstract class BasePrimitiveDomainType extends BaseDomainType implements PrimitiveDomainType {
 
-  /**
-   * The type used in the hibernate mapping. Most of the time is the same as the
-   * {@link #getPrimitiveType()}. Can be used to set a hibnernate user type class. See the hibernate
-   * documentation for more information on this.
+  private Constructor<Object> constructor;
+
+  /*
+   * (non-Javadoc)
    * 
-   * This method will be moved to the PrimitiveDomainType in a later stage.
-   * 
-   * @return the class representing the hibernate type
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getHibernateType()
    */
   public Class<?> getHibernateType() {
     return getPrimitiveType();
@@ -72,4 +72,39 @@
     return null;
   }
 
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#convertToString(java.lang.Object)
+   */
+  @Override
+  public String convertToString(Object value) {
+    if (value == null) {
+      return EMPTY_STRING;
+    }
+    return value.toString();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.length() == 0) {
+      return null;
+    }
+
+    try {
+      if (constructor == null) {
+        final Class<Object> clz = (Class<Object>) getPrimitiveType();
+        constructor = clz.getConstructor(String.class);
+      }
+      return constructor.newInstance(strValue);
+    } catch (Exception e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
 }
--- a/src/org/openbravo/base/model/domaintype/BigDecimalDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/BigDecimalDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -66,4 +66,28 @@
       return "price";
     }
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.trim().length() == 0) {
+      return null;
+    }
+    return new BigDecimal(strValue);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:decimal";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/BinaryDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/BinaryDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,6 +19,10 @@
 
 package org.openbravo.base.model.domaintype;
 
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.codec.binary.Base64;
+
 /**
  * The type for a binary (image for example) column.
  * 
@@ -34,4 +38,49 @@
   public Class<?> getPrimitiveType() {
     return byte[].class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#convertToString(java.lang.Object)
+   */
+  @Override
+  public String convertToString(Object value) {
+    try {
+      if (value == null) {
+        return EMPTY_STRING;
+      }
+      return new String(Base64.encodeBase64((byte[]) value), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    try {
+      if (strValue == null || strValue.trim().length() == 0) {
+        return null;
+      }
+      return Base64.decodeBase64(strValue.getBytes("UTF-8"));
+    } catch (UnsupportedEncodingException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:base64Binary";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/BooleanDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/BooleanDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,7 +19,6 @@
 
 package org.openbravo.base.model.domaintype;
 
-
 /**
  * The type for a yes/no or boolean column.
  * 
@@ -35,4 +34,28 @@
   public Class<?> getPrimitiveType() {
     return Boolean.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.trim().length() == 0) {
+      return null;
+    }
+    return new Boolean(strValue);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:boolean";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/ButtonDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/ButtonDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -34,4 +34,28 @@
   public Class<?> getPrimitiveType() {
     return Boolean.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.trim().length() == 0) {
+      return null;
+    }
+    return new Boolean(strValue);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:boolean";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/DateDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/DateDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,6 +19,8 @@
 
 package org.openbravo.base.model.domaintype;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 
 /**
@@ -29,6 +31,8 @@
 
 public class DateDomainType extends BasePrimitiveDomainType {
 
+  private final SimpleDateFormat xmlDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
+
   /**
    * @return class of the {@link Date}
    * @see org.openbravo.base.model.domaintype.DomainType#getPrimitiveType()
@@ -36,4 +40,45 @@
   public Class<?> getPrimitiveType() {
     return Date.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#convertToString(java.lang.Object)
+   */
+  @Override
+  public synchronized String convertToString(Object value) {
+    if (value == null) {
+      return EMPTY_STRING;
+    }
+    return xmlDateFormat.format(value);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public synchronized Object createFromString(String strValue) {
+    try {
+      if (strValue == null || strValue.trim().length() == 0) {
+        return null;
+      }
+      return xmlDateFormat.parse(strValue);
+    } catch (ParseException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:dateTime";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/DatetimeDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/DatetimeDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,6 +19,8 @@
 
 package org.openbravo.base.model.domaintype;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 
 /**
@@ -29,6 +31,8 @@
 
 public class DatetimeDomainType extends BasePrimitiveDomainType {
 
+  private final SimpleDateFormat xmlDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
+
   /**
    * @return class of the {@link Date}
    * @see org.openbravo.base.model.domaintype.DomainType#getPrimitiveType()
@@ -36,4 +40,44 @@
   public Class<?> getPrimitiveType() {
     return Date.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#convertToString(java.lang.Object)
+   */
+  @Override
+  public synchronized String convertToString(Object value) {
+    if (value == null) {
+      return EMPTY_STRING;
+    }
+    return xmlDateFormat.format(value);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public synchronized Object createFromString(String strValue) {
+    try {
+      if (strValue == null || strValue.trim().length() == 0) {
+        return null;
+      }
+      return xmlDateFormat.parse(strValue).getTime();
+    } catch (ParseException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:dateTime";
+  }
 }
--- a/src/org/openbravo/base/model/domaintype/LongDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/LongDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -19,6 +19,8 @@
 
 package org.openbravo.base.model.domaintype;
 
+import java.math.BigDecimal;
+
 import org.openbravo.base.model.Property;
 import org.openbravo.base.validation.ValidationException;
 
@@ -57,4 +59,28 @@
   public String getFormatId() {
     return "integer";
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.trim().length() == 0) {
+      return null;
+    }
+    return new Long(new BigDecimal(strValue).longValueExact());
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:long";
+  }
+
 }
--- a/src/org/openbravo/base/model/domaintype/ObjectDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/ObjectDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -36,4 +36,24 @@
   public Class<?> getPrimitiveType() {
     return Object.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    return strValue;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "xs:anyType";
+  }
 }
--- a/src/org/openbravo/base/model/domaintype/PrimitiveDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/PrimitiveDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -30,6 +30,48 @@
 
 public interface PrimitiveDomainType extends DomainType {
 
+  public static final String EMPTY_STRING = "";
+
+  /**
+   * Converts an object value of this type to a locale/system neutral String. Is used in XML
+   * conversion. The opposite of this method is the {@link #createFromString(String)} method.
+   * 
+   * @param value
+   *          the value to convert to a string.
+   * @return the String representation, if the value is null then an empty String is returned
+   * @throws IllegalArgumentException
+   *           if the conversion is not possible
+   */
+  String convertToString(Object value);
+
+  /**
+   * Converts a string back to an object value of the primitive type ({@see #getPrimitiveType()})
+   * represented by this DomainType. This method is the opposite of the
+   * {@link #convertToString(Object)} method.
+   * 
+   * @param strValue
+   *          the string value to convert
+   * @return the object value, null is returned if an empty string or null are passed as parameter.
+   * @throws IllegalArgumentException
+   *           if the conversion is not possible
+   */
+  Object createFromString(String strValue);
+
+  /**
+   * @return the xml schema type which matches the primitive type, is used to create the XML Schema
+   *         for the REST web services.
+   */
+  String getXMLSchemaType();
+
+  /**
+   * The type used in the hibernate mapping. Most of the time is the same as the
+   * {@link #getPrimitiveType()}. Can be used to set a hibnernate user type class. See the hibernate
+   * documentation for more information on this.
+   * 
+   * @return the class representing the hibernate type
+   */
+  Class<?> getHibernateType();
+
   /**
    * The primitive type class (for example java.lang.Long) if this is a primitive type.
    * 
--- a/src/org/openbravo/base/model/domaintype/StringDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/StringDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -34,4 +34,27 @@
   public Class<?> getPrimitiveType() {
     return String.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.length() == 0) {
+      return null;
+    }
+    return strValue;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:string";
+  }
 }
--- a/src/org/openbravo/base/model/domaintype/StringEnumerateDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/StringEnumerateDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -36,4 +36,27 @@
   public Class<?> getPrimitiveType() {
     return String.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public Object createFromString(String strValue) {
+    if (strValue == null || strValue.length() == 0) {
+      return null;
+    }
+    return strValue;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:string";
+  }
 }
--- a/src/org/openbravo/base/model/domaintype/TimestampDomainType.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/base/model/domaintype/TimestampDomainType.java	Tue Apr 06 09:45:31 2010 +0200
@@ -20,6 +20,8 @@
 package org.openbravo.base.model.domaintype;
 
 import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 
 /**
  * The type for a datetime column.
@@ -29,6 +31,8 @@
 
 public class TimestampDomainType extends BasePrimitiveDomainType {
 
+  private final SimpleDateFormat xmlDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'");
+
   /**
    * @return class of the {@link Timestamp}
    * @see org.openbravo.base.model.domaintype.DomainType#getPrimitiveType()
@@ -36,4 +40,44 @@
   public Class<?> getPrimitiveType() {
     return Timestamp.class;
   }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#convertToString(java.lang.Object)
+   */
+  @Override
+  public synchronized String convertToString(Object value) {
+    if (value == null) {
+      return EMPTY_STRING;
+    }
+    return xmlDateFormat.format(value);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#createFromString(java.lang.String)
+   */
+  @Override
+  public synchronized Object createFromString(String strValue) {
+    try {
+      if (strValue == null || strValue.trim().length() == 0) {
+        return null;
+      }
+      return new Timestamp(xmlDateFormat.parse(strValue).getTime());
+    } catch (ParseException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.openbravo.base.model.domaintype.PrimitiveDomainType#getXMLSchemaType()
+   */
+  @Override
+  public String getXMLSchemaType() {
+    return "ob:dateTime";
+  }
 }
--- a/src/org/openbravo/dal/xml/EntityXMLConverter.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/EntityXMLConverter.java	Tue Apr 06 09:45:31 2010 +0200
@@ -41,6 +41,7 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.provider.OBNotSingleton;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.structure.BaseOBObject;
@@ -408,7 +409,7 @@
             }
           }
         }
-        final String txt = XMLTypeConverter.getInstance().toXML(value);
+        final String txt = ((PrimitiveDomainType) p.getDomainType()).convertToString(value);
         xmlHandler.startElement("", "", p.getName(), propertyAttrs);
         xmlHandler.characters(txt.toCharArray(), 0, txt.length());
         xmlHandler.endElement("", "", p.getName());
--- a/src/org/openbravo/dal/xml/EntityXMLException.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/EntityXMLException.java	Tue Apr 06 09:45:31 2010 +0200
@@ -26,7 +26,6 @@
  * 
  * @see EntityXMLConverter
  * @see XMLEntityConverter
- * @see XMLTypeConverter
  * @author mtaal
  */
 public class EntityXMLException extends OBException {
--- a/src/org/openbravo/dal/xml/ModelXMLConverter.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/ModelXMLConverter.java	Tue Apr 06 09:45:31 2010 +0200
@@ -28,6 +28,7 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.provider.OBSingleton;
 
@@ -172,8 +173,7 @@
 
       // set the type
       if (p.isPrimitive()) {
-        element.addAttribute("type", XMLTypeConverter.getInstance().toXMLSchemaType(
-            p.getPrimitiveType()));
+        element.addAttribute("type", ((PrimitiveDomainType) p.getDomainType()).getXMLSchemaType());
       } else if (p.isOneToMany()) {
         final Element complexChildElement = element.addElement("xs:complexType");
         final Element sequenceChildElement = complexChildElement.addElement("xs:sequence");
--- a/src/org/openbravo/dal/xml/StaxXMLEntityConverter.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/StaxXMLEntityConverter.java	Tue Apr 06 09:45:31 2010 +0200
@@ -37,6 +37,7 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.provider.OBNotSingleton;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.structure.BaseOBObject;
@@ -259,8 +260,7 @@
           // element value, note that getElementText means that it is not required anymore
           // to go to element end, that is done by the xmlReader
           final String elementText = xmlReader.getElementText();
-          Object newValue = XMLTypeConverter.getInstance().fromXML(p.getPrimitiveType(),
-              elementText);
+          Object newValue = ((PrimitiveDomainType) p.getDomainType()).createFromString(elementText);
 
           // correct the value
           newValue = replaceValue(bob, p, newValue);
--- a/src/org/openbravo/dal/xml/XMLEntityConverter.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/XMLEntityConverter.java	Tue Apr 06 09:45:31 2010 +0200
@@ -32,6 +32,7 @@
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.structure.BaseOBObject;
 import org.openbravo.base.structure.ClientEnabled;
@@ -210,8 +211,9 @@
 
         // do the primitive values
         if (p.isPrimitive()) {
-          Object newValue = XMLTypeConverter.getInstance().fromXML(p.getPrimitiveType(),
-              childElement.getText());
+          Object newValue = ((PrimitiveDomainType) p.getDomainType()).createFromString(childElement
+              .getText());
+
           // correct the value
           newValue = replaceValue(bob, p, newValue);
 
--- a/src/org/openbravo/dal/xml/XMLTypeConverter.java	Tue Apr 06 09:17:40 2010 +0200
+++ b/src/org/openbravo/dal/xml/XMLTypeConverter.java	Tue Apr 06 09:45:31 2010 +0200
@@ -27,12 +27,18 @@
 
 import org.apache.commons.codec.binary.Base64;
 import org.openbravo.base.exception.OBException;
+import org.openbravo.base.model.Property;
+import org.openbravo.base.model.domaintype.PrimitiveDomainType;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.provider.OBSingleton;
 
 /**
  * Converts primitive types to a XML representation and back.
  * 
+ * NOTE: class is deprecated, use the {@link PrimitiveDomainType} interface which can be obtained
+ * from the {@link Property#getDomainType()}.
+ * 
+ * 
  * @author mtaal
  */