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.ui;
22  
23  import java.math.BigDecimal;
24  import java.text.DecimalFormat;
25  import java.text.NumberFormat;
26  import java.util.List;
27  
28  import org.apache.commons.lang3.StringEscapeUtils;
29  import org.efaps.admin.datamodel.attributetype.DecimalType;
30  import org.efaps.admin.dbproperty.DBProperties;
31  import org.efaps.admin.ui.AbstractUserInterfaceObject.TargetMode;
32  import org.efaps.admin.ui.field.Field;
33  import org.efaps.db.Context;
34  import org.efaps.util.EFapsException;
35  
36  /**
37   * Class used to represent any type of decimal for the UI.
38   *
39   * @author The eFaps Team
40   * @version $Id$
41   */
42  public class DecimalUI
43      extends AbstractUI
44  {
45  
46      /**
47       * Needed for serialization.
48       */
49      private static final long serialVersionUID = 1L;
50  
51      /**
52       * {@inheritDoc}
53       */
54      @Override
55      public String getReadOnlyHtml(final FieldValue _fieldValue)
56          throws EFapsException
57      {
58          final StringBuilder ret = new StringBuilder();
59          final Field field = _fieldValue.getField();
60          final Object value = _fieldValue.getValue();
61          final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
62                          .getLocale());
63          if (_fieldValue.getAttribute() != null) {
64              formatter.setMaximumFractionDigits(_fieldValue.getAttribute().getScale());
65          }
66          if (value instanceof List<?>) {
67              final List<?> values = (List<?>) value;
68              boolean first = true;
69              for (final Object obj : values) {
70                  final int scale = ((BigDecimal) value).scale();
71                  if (formatter.getMinimumFractionDigits() < scale) {
72                      formatter.setMinimumFractionDigits(scale);
73                  }
74                  final String tmp = evalString4Object(formatter, obj);
75                  if (tmp != null) {
76                      if (first) {
77                          first = false;
78                      } else {
79                          ret.append("<br/>");
80                      }
81                      ret.append(StringEscapeUtils.escapeHtml4(tmp));
82                  }
83              }
84          } else {
85              final String tmp = evalString4Object(formatter, value);
86              if (tmp != null) {
87                  ret.append("<span name=\"").append(field.getName()).append("\" ")
88                      .append(UIInterface.EFAPSTMPTAG).append(">")
89                      .append(StringEscapeUtils.escapeHtml4(tmp))
90                      .append("</span>");
91              }
92          }
93          return ret.toString();
94      }
95  
96      /**
97       * {@inheritDoc}
98       */
99      @Override
100     public String getHiddenHtml(final FieldValue _fieldValue)
101         throws EFapsException
102     {
103         final StringBuilder ret = new StringBuilder();
104         final Field field = _fieldValue.getField();
105         final Object value = _fieldValue.getValue();
106         final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
107                         .getLocale());
108         if (_fieldValue.getAttribute() != null) {
109             formatter.setMaximumFractionDigits(_fieldValue.getAttribute().getScale());
110         }
111         final String tmp = evalString4Object(formatter, value);
112         ret.append("<input type=\"hidden\" ").append(" name=\"").append(field.getName())
113                         .append("\" value=\"").append(StringEscapeUtils.escapeHtml4(tmp)).append("\"")
114                         .append(UIInterface.EFAPSTMPTAG).append("/>");
115 
116         return ret.toString();
117     }
118 
119     /**
120      * {@inheritDoc}
121      *
122      * @throws EFapsException
123      */
124     @Override
125     public String getEditHtml(final FieldValue _fieldValue)
126         throws EFapsException
127     {
128         final StringBuilder ret = new StringBuilder();
129         final Field field = _fieldValue.getField();
130         final Object value = _fieldValue.getValue();
131         final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
132                         .getLocale());
133         if (_fieldValue.getAttribute() != null) {
134             formatter.setMaximumFractionDigits(_fieldValue.getAttribute().getScale());
135         }
136         final String tmp = evalString4Object(formatter, value);
137         if (_fieldValue.getTargetMode().equals(TargetMode.SEARCH)) {
138             ret.append("<input type=\"text\"").append(" size=\"").append(field.getCols()).append("\" name=\"")
139                             .append(field.getName()).append("\" value=\"")
140                             .append(value != null ? StringEscapeUtils.escapeHtml4(tmp) : "*").append("\" />");
141         } else {
142             if (field.getRows() > 1) {
143                 ret.append("<textarea type=\"text\"")
144                                 .append(" cols=\"").append(field.getCols())
145                                 .append("\" rows=\"").append(field.getRows())
146                                 .append("\" name=\"").append(field.getName()).append("\"")
147                                 .append(UIInterface.EFAPSTMPTAG).append("/>");
148                 if (value != null) {
149                     ret.append(StringEscapeUtils.escapeHtml4(tmp));
150                 }
151                 ret.append("</textarea>");
152             } else {
153                 ret.append("<input type=\"text\" size=\"").append(field.getCols())
154                     .append("\" name=\"").append(field.getName())
155                     .append("\" value=\"").append(StringEscapeUtils.escapeHtml4(tmp)).append("\"")
156                     .append(UIInterface.EFAPSTMPTAG).append("/>");
157             }
158         }
159         return ret.toString();
160     }
161 
162     /**
163      * @param _formatter Formatter to be used
164      * @param _object object to be formatted
165      * @return String vor the object
166      */
167     private String evalString4Object(final DecimalFormat _formatter,
168                                      final Object _object)
169     {
170         final String ret;
171         if (_object == null) {
172             ret = "";
173         } else {
174             if (_object instanceof Number) {
175                 if (_object instanceof BigDecimal) {
176                     final int scale = ((BigDecimal) _object).scale();
177                     if (_formatter.getMinimumFractionDigits() < scale) {
178                         _formatter.setMinimumFractionDigits(scale);
179                     }
180                 }
181                 ret = _formatter.format(_object);
182             } else {
183                 ret = _object.toString();
184             }
185         }
186         return ret;
187     }
188 
189 
190     /**
191      * {@inheritDoc}
192      */
193     @Override
194     public String getStringValue(final FieldValue _fieldValue)
195         throws EFapsException
196     {
197         final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
198                         .getLocale());
199         if (_fieldValue.getAttribute() != null) {
200             formatter.setMaximumFractionDigits(_fieldValue.getAttribute().getScale());
201         }
202         return evalString4Object(formatter, _fieldValue.getValue());
203     }
204 
205     /**
206      * {@inheritDoc}
207      */
208     @Override
209     public Object getObject4Compare(final FieldValue _fieldValue)
210         throws EFapsException
211     {
212         return _fieldValue.getValue();
213     }
214 
215     /**
216      * {@inheritDoc}
217      */
218     @Override
219     public int compare(final FieldValue _fieldValue,
220                        final FieldValue _fieldValue2)
221     {
222         int ret = 0;
223         if (_fieldValue.getValue() instanceof BigDecimal && _fieldValue2.getValue() instanceof BigDecimal) {
224             final BigDecimal num = (BigDecimal) _fieldValue.getValue();
225             final BigDecimal num2 = (BigDecimal) _fieldValue2.getValue();
226             ret = num.compareTo(num2);
227         }
228         return ret;
229     }
230 
231     /**
232      * {@inheritDoc}
233      */
234     @Override
235     public String validateValue(final UIValue _value)
236     {
237         String ret = null;
238         try {
239             if (_value.getDbValue() != null) {
240                 DecimalType.parseLocalized(String.valueOf(_value.getDbValue()));
241             }
242         } catch (final EFapsException e) {
243             ret = DBProperties.getProperty(DecimalUI.class.getName() + ".InvalidValue");
244         }
245         return ret;
246     }
247 
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     public Object format(final Object _object,
253                          final String _pattern)
254         throws EFapsException
255     {
256         final DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Context.getThreadContext()
257                         .getLocale());
258         formatter.applyPattern(_pattern);
259         Object ret;
260         if (_object instanceof BigDecimal
261                         && formatter.getNegativeSuffix().isEmpty() && "-".equals(formatter.getNegativePrefix())
262                         && formatter.getPositiveSuffix().isEmpty() && formatter.getPositivePrefix().isEmpty()) {
263             int scale = formatter.getMinimumFractionDigits();
264             if (scale < formatter.getMaximumFractionDigits()) {
265                 scale = formatter.getMaximumFractionDigits();
266             }
267             ret = ((BigDecimal) _object).setScale(scale, BigDecimal.ROUND_HALF_UP);
268         } else {
269             ret = formatter.format(_object);
270         }
271         return ret;
272     }
273 }