1   /*
2    * Copyright 2003 - 2013 The eFaps Team
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.admin.datamodel.attributetype;
22  
23  import java.math.BigDecimal;
24  import java.sql.SQLException;
25  import java.text.DecimalFormat;
26  import java.text.NumberFormat;
27  import java.text.ParseException;
28  import java.util.ArrayList;
29  import java.util.List;
30  
31  import org.efaps.admin.datamodel.Attribute;
32  import org.efaps.db.Context;
33  import org.efaps.db.wrapper.AbstractSQLInsertUpdate;
34  import org.efaps.util.EFapsException;
35  
36  /**
37   * Implements the mapping between values in the database and {@link BigDecimal}
38   * values in eFaps.
39   *
40   * @author The eFaps Team
41   * @version $Id$
42   */
43  public class DecimalType
44      extends AbstractType
45  {
46      /**
47       * Needed for serialization.
48       */
49      private static final long serialVersionUID = 1L;
50  
51      /**
52       * {@inheritDoc}
53       */
54      @Override
55      public void prepare(final AbstractSQLInsertUpdate<?> _insertUpdate,
56                          final Attribute _attribute,
57                          final Object... _values)
58          throws SQLException
59      {
60          checkSQLColumnSize(_attribute, 1);
61          _insertUpdate.column(_attribute.getSqlColNames().get(0), eval(_values));
62      }
63  
64      /**
65       * Evaluate the value.
66       * @param _values value to be evaluated
67       * @return BigDecimal value
68       * @throws SQLException on error
69       */
70      protected BigDecimal eval(final Object... _values)
71          throws SQLException
72      {
73          final BigDecimal ret;
74  
75          if ((_values == null) || (_values.length == 0) || (_values[0] == null))  {
76              ret = null;
77          } else if ((_values[0] instanceof String) && (((String) _values[0]).length() > 0)) {
78              try {
79                  ret = DecimalType.parseLocalized((String) _values[0]);
80              } catch (final EFapsException e) {
81                  throw new SQLException(e);
82              }
83          } else if (_values[0] instanceof BigDecimal) {
84              ret = (BigDecimal) _values[0];
85          } else if (_values[0] instanceof Number) {
86              ret = new BigDecimal(((Number) _values[0]).toString());
87          } else  {
88              ret = null;
89          }
90  
91          return ret;
92      }
93  
94      /**
95       * {@inheritDoc}
96       */
97      @Override
98      public Object readValue(final Attribute _attribute,
99                              final List<Object> _objectList)
100     {
101         final List<BigDecimal> ret = new ArrayList<BigDecimal>();
102         for (final Object object : _objectList) {
103             if (object instanceof BigDecimal) {
104                 ret.add((BigDecimal) object);
105             } else if (object != null) {
106                 ret.add(new BigDecimal(object.toString()));
107             }
108         }
109         return _objectList.size() > 0 ? (ret.size() > 1 ? ret : (ret.size() > 0 ? ret.get(0) : null)) : null;
110     }
111 
112     /**
113      * Method to parse a localized String to an BigDecimal.
114      *
115      * @param _value value to be parsed
116      * @return  BigDecimal
117      * @throws EFapsException on error
118      */
119     public static BigDecimal parseLocalized(final String _value) throws EFapsException
120     {
121         final DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
122                         .getLocale());
123         format.setParseBigDecimal(true);
124         try {
125             return (BigDecimal) format.parse(_value);
126         } catch (final ParseException e) {
127             throw new EFapsException(DecimalType.class, "ParseException", e);
128         }
129     }
130 
131 
132     /**
133      * {@inheritDoc}
134      */
135     @Override
136     public String toString4Where(final Object _value)
137         throws EFapsException
138     {
139         String ret = "";
140         if (_value instanceof BigDecimal) {
141             ret =  ((BigDecimal) _value).toPlainString();
142         } else if (_value instanceof String) {
143             ret = (String) _value;
144         } else if (_value != null) {
145             ret = (new BigDecimal(_value.toString())).toPlainString();
146         }
147         return ret;
148     }
149 }