First implementation of FieldProvider for OB Business Objects
authorMartin Taal <martin.taal@openbravo.com>
Tue, 23 Jun 2009 00:05:47 +0200
changeset 4056 a131cd5d9e7c
parent 4055 f15a06e10f8a
child 4057 27b9c6b0026b
First implementation of FieldProvider for OB Business Objects
src-test/org/openbravo/test/model/FieldProviderTest.java
src/org/openbravo/base/model/Property.java
src/org/openbravo/base/model/Reference.java
src/org/openbravo/erpCommon/utility/OBObjectFieldProvider.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/org/openbravo/test/model/FieldProviderTest.java	Tue Jun 23 00:05:47 2009 +0200
@@ -0,0 +1,74 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SL 
+ * All portions are Copyright (C) 2009 Openbravo SL 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.model;
+
+import org.openbravo.base.model.Entity;
+import org.openbravo.base.model.ModelProvider;
+import org.openbravo.base.model.Property;
+import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.dal.service.OBCriteria;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.data.FieldProvider;
+import org.openbravo.erpCommon.utility.OBObjectFieldProvider;
+import org.openbravo.test.base.BaseTest;
+
+/**
+ * Tests the {@link OBObjectFieldProvider}.
+ * 
+ * @author mtaal
+ */
+
+public class FieldProviderTest extends BaseTest {
+
+  /**
+   * Read all data from the database and create field providers then iterate over all columns and
+   * get the value.
+   */
+  public void testAll() {
+    super.setBigBazaarAdminContext();
+    for (Entity e : ModelProvider.getInstance().getModel()) {
+      final OBCriteria<BaseOBObject> criteria = OBDal.getInstance().createCriteria(e.getName());
+      if (criteria.list().size() > 100) {
+        // make the test a bit smaller...
+        continue;
+      }
+      for (BaseOBObject bob : criteria.list()) {
+        final FieldProvider fp = OBObjectFieldProvider.createOBObjectFieldProvider(bob);
+        for (Property p : e.getProperties()) {
+          if (p.getColumnName() == null) {
+            continue;
+          }
+          final String convertedName = p.getColumnName().replaceAll("_", "");
+          final String strValue = fp.getField(convertedName);
+          final Object value = bob.get(p.getName());
+          if (value instanceof BaseOBObject) {
+            assertTrue(((BaseOBObject) value).getIdentifier().equals(strValue));
+          } else if (value instanceof String) {
+            assertTrue(value.equals(strValue));
+          } else {
+            assertTrue((value != null && strValue != null)
+                || (value == null && strValue.equals("")));
+          }
+        }
+      }
+    }
+  }
+
+}
\ No newline at end of file
--- a/src/org/openbravo/base/model/Property.java	Mon Jun 22 21:56:51 2009 +0200
+++ b/src/org/openbravo/base/model/Property.java	Tue Jun 23 00:05:47 2009 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SL 
- * All portions are Copyright (C) 2008 Openbravo SL 
+ * All portions are Copyright (C) 2008-2009 Openbravo SL 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -83,6 +83,8 @@
 
   private Module module;
 
+  private boolean isDatetime;
+
   // keeps track of the index of this property in the entity.getProperties()
   // gives a lot of performance/memory improvements when getting property values
   private int indexInEntity;
@@ -98,6 +100,7 @@
     setId(fromColumn.isKey());
     setPrimitive(fromColumn.isPrimitiveType());
     setPrimitiveType(fromColumn.getPrimitiveType());
+    setDatetime(fromColumn.getReference().isDatetime());
     setIdentifier(fromColumn.isIdentifier());
     setParent(fromColumn.isParent());
     setColumnName(fromColumn.getColumnName());
@@ -920,4 +923,12 @@
   public void setIndexInEntity(int indexInEntity) {
     this.indexInEntity = indexInEntity;
   }
+
+  public boolean isDatetime() {
+    return isDatetime;
+  }
+
+  public void setDatetime(boolean isDatetime) {
+    this.isDatetime = isDatetime;
+  }
 }
--- a/src/org/openbravo/base/model/Reference.java	Mon Jun 22 21:56:51 2009 +0200
+++ b/src/org/openbravo/base/model/Reference.java	Tue Jun 23 00:05:47 2009 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SL 
- * All portions are Copyright (C) 2008 Openbravo SL 
+ * All portions are Copyright (C) 2008-2009 Openbravo SL 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -102,4 +102,8 @@
   public Set<String> getAllowedValues() {
     return allowedValues;
   }
+
+  public boolean isDatetime() {
+    return getId().equals("16");
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/utility/OBObjectFieldProvider.java	Tue Jun 23 00:05:47 2009 +0200
@@ -0,0 +1,202 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SL 
+ * All portions are Copyright (C) 2009 Openbravo SL 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.erpCommon.utility;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.model.Property;
+import org.openbravo.base.provider.OBNotSingleton;
+import org.openbravo.base.provider.OBProvider;
+import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.base.structure.Identifiable;
+import org.openbravo.data.FieldProvider;
+
+/**
+ * An implementation of the {@link FieldProviderFactory} which can handle Openbravo business
+ * objects.
+ */
+public class OBObjectFieldProvider implements FieldProvider, OBNotSingleton {
+
+  private BaseOBObject obObject;
+  private Map<String, Property> fieldNameToProperty = new HashMap<String, Property>();
+  private Map<String, String> valueCache = new HashMap<String, String>();
+
+  private boolean returnObjectValueAsId = false;
+
+  private DateFormat dateFormatter;
+  private DateFormat dateTimeFormatter;
+  private NumberFormat decimalFormatter = DecimalFormat.getNumberInstance();
+  private NumberFormat integerFormatter = NumberFormat.getIntegerInstance();
+
+  /**
+   * Creates a new instance of a field provider and sets the internal obObject member.
+   * 
+   * @param bob
+   *          the business object to create the field provider for
+   * @return a new FieldProvider
+   */
+  public static OBObjectFieldProvider createOBObjectFieldProvider(BaseOBObject bob) {
+    final OBObjectFieldProvider fieldProvider = OBProvider.getInstance().get(
+        OBObjectFieldProvider.class);
+    fieldProvider.setObObject(bob);
+    return fieldProvider;
+  }
+
+  /**
+   * Returns an array of field providers.
+   * 
+   * @param bobs
+   *          the list of {@link BaseOBObject} instances for which to create the
+   *          {@link FieldProvider} instances
+   * @return an array of field providers, one for each passed BaseOBObject
+   */
+  public static OBObjectFieldProvider[] createOBObjectFieldProvider(List<BaseOBObject> bobs) {
+    final OBObjectFieldProvider[] result = new OBObjectFieldProvider[bobs.size()];
+    int index = 0;
+    for (BaseOBObject bob : bobs) {
+      result[index++] = createOBObjectFieldProvider(bob);
+    }
+    return result;
+  }
+
+  /**
+   * This is the implementation for the FieldProvider.getField(String s) method which will be
+   * invoked in the object.
+   * <p>
+   * It finds the property of the BaseOBObject using the passed field name parameter. The fieldName
+   * is encoded in a special way: all underscores have been removed from the column name and all the
+   * characters after the underscores have been uppercased.
+   * 
+   */
+  public String getField(String fieldName) {
+    // is converted to lower case for simplicity
+    final String lowerFieldName = fieldName.toLowerCase();
+    final String result;
+    if ((result = valueCache.get(lowerFieldName)) != null) {
+      return result;
+    }
+    final Property property = fieldNameToProperty.get(lowerFieldName);
+    if (property == null) {
+      throw new OBException("The fieldName " + fieldName
+          + " can not be mapped to a property of the entity " + getObObject().getEntityName());
+    }
+    final Object objValue = getObObject().get(property.getName());
+    final String strValue = convert(property, objValue);
+    valueCache.put(lowerFieldName, strValue);
+    return strValue;
+  }
+
+  protected String convert(Property property, Object value) {
+    if (value == null) {
+      return "";
+    }
+    if (value instanceof String) {
+      return (String) value;
+    }
+    if (value instanceof BaseOBObject) {
+      if (isReturnObjectValueAsId()) {
+        return (String) ((BaseOBObject) value).getId();
+      } else {
+        return ((Identifiable) value).getIdentifier();
+      }
+    }
+    if (value instanceof Date && property.isDatetime()) {
+      return dateTimeFormatter.format((Date) value);
+    } else if (value instanceof Date) {
+      return dateFormatter.format((Date) value);
+    }
+
+    if (value instanceof BigDecimal) {
+      return decimalFormatter.format(value);
+    }
+
+    if (value instanceof Long) {
+      return integerFormatter.format(value);
+    }
+    // TODO do some smart things with conversion!
+    // to handle date/datetime/Numeric values
+    return value.toString();
+  }
+
+  public BaseOBObject getObObject() {
+    return obObject;
+  }
+
+  public void setObObject(BaseOBObject obObject) {
+    this.obObject = obObject;
+    // fill the field name to property thing
+    for (Property property : obObject.getEntity().getProperties()) {
+      if (property.getColumnName() == null) {
+        // ignore these....
+        continue;
+      }
+
+      // convert the columnname!
+      // note removing all _ and to lower case
+      final String convertedColName = property.getColumnName().replaceAll("_", "").toLowerCase();
+      fieldNameToProperty.put(convertedColName, property);
+    }
+
+    // also set the date format
+    final Properties props = OBPropertiesProvider.getInstance().getOpenbravoProperties();
+    dateFormatter = new SimpleDateFormat(props.getProperty("dateFormat.java"));
+    dateTimeFormatter = new SimpleDateFormat(props.getProperty("dateTimeFormat.java"));
+  }
+
+  public boolean isReturnObjectValueAsId() {
+    return returnObjectValueAsId;
+  }
+
+  public void setReturnObjectValueAsId(boolean returnObjectValueAsId) {
+    this.returnObjectValueAsId = returnObjectValueAsId;
+  }
+
+  /**
+   * Sets the pattern by which decimal numbers are formatted.
+   * 
+   * @param pattern
+   *          a java pattern
+   * @see DecimalFormat
+   */
+  public void setDecimalFormatPattern(String pattern) {
+    decimalFormatter = new DecimalFormat(pattern);
+  }
+
+  /**
+   * Sets the pattern by which integer/long numbers are formatted.
+   * 
+   * @param pattern
+   *          a java pattern
+   * @see DecimalFormat
+   */
+  public void setIntegerFormatPattern(String pattern) {
+    integerFormatter = new DecimalFormat(pattern);
+  }
+}