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.util.ArrayList;
26  import java.util.List;
27  
28  import org.efaps.admin.datamodel.Attribute;
29  import org.efaps.admin.datamodel.attributevalue.Rate;
30  import org.efaps.db.wrapper.AbstractSQLInsertUpdate;
31  import org.efaps.util.EFapsException;
32  
33  /**
34   * TODO comment!
35   *
36   * @author The eFaps Team
37   * @version $Id$
38   */
39  public class RateType
40      extends AbstractType
41  {
42      /**
43       * Needed for serialization.
44       */
45      private static final long serialVersionUID = 1L;
46  
47      /**
48       * The method prepares the statement for insert the object in the database.
49       * It must be overwritten, because this type has at least two columns.
50       * {@inheritDoc}
51       */
52      @Override
53      public void prepare(final AbstractSQLInsertUpdate<?> _insertUpdate,
54                          final Attribute _attribute,
55                          final Object... _values)
56          throws SQLException
57      {
58          checkSQLColumnSize(_attribute, 2);
59          final Rate value = eval(_values);
60          _insertUpdate.column(_attribute.getSqlColNames().get(0), value.getNumerator());
61          _insertUpdate.column(_attribute.getSqlColNames().get(1), value.getDenominator());
62      }
63  
64      /**
65       * The localized string and the internal string value are equal. So the
66       * internal value can be evaluated directly.
67       *
68       * @param _values values to evaluate
69       * @return evaluated big decimal value with unit of measure
70       * @throws SQLException on error
71       */
72      protected Rate eval(final Object... _values)
73          throws SQLException
74      {
75          final Rate ret;
76          if ((_values == null) || (_values[0] == null)) {
77              ret = null;
78          } else if (_values[0] instanceof Object[]) {
79              final Object[] valueTmp = (Object[]) _values[0];
80              if (valueTmp.length < 2) {
81                  ret = null;
82              } else {
83                  ret = new Rate(evalObject(valueTmp[0]), evalObject(valueTmp[1]));
84              }
85          } else {
86              ret = new Rate(evalObject(_values[0]), evalObject(_values[1]));
87          }
88          return ret;
89      }
90  
91      /**
92       * @param _value value to evaluated
93       * @return BigDecimal
94       * @throws SQLException on error
95       */
96      protected BigDecimal evalObject(final Object _value)
97          throws SQLException
98      {
99          BigDecimal ret;
100         if ((_value instanceof String) && (((String) _value).length() > 0)) {
101             try {
102                 ret = DecimalType.parseLocalized((String) _value);
103             } catch (final EFapsException e) {
104                 throw new SQLException(e);
105             }
106         } else if (_value instanceof BigDecimal) {
107             ret = (BigDecimal) _value;
108         } else if (_value instanceof Number) {
109             ret = new BigDecimal(((Number) _value).toString());
110         } else {
111             ret = BigDecimal.ONE;
112         }
113         return ret;
114     }
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public Object readValue(final Attribute _attribute,
121                             final List<Object> _objectList)
122         throws EFapsException
123     {
124         final List<Object[]> ret = new ArrayList<Object[]>();
125         for (final Object object : _objectList) {
126             final Object[] temp = (Object[]) object;
127             final Object numerator = readValue(temp[0]);
128             final Object denominator = readValue(temp[1]);
129             ret.add(new Object[] { numerator, denominator });
130         }
131         return _objectList.size() > 0 ? (ret.size() > 1 ? ret : ret.get(0)) : null;
132     }
133 
134     /**
135      * @param _object objetc to read
136      * @return object
137      */
138     protected Object readValue(final Object _object)
139     {
140         final BigDecimal ret;
141         if (_object instanceof BigDecimal) {
142             ret = (BigDecimal) _object;
143         } else if (_object != null) {
144             ret = new BigDecimal(_object.toString());
145         } else {
146             ret = BigDecimal.ONE;
147         }
148         return ret;
149     }
150 }