1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.convert;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.apache.myfaces.tobago.component.Attributes;
25
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import javax.faces.convert.Converter;
29 import javax.faces.convert.ConverterException;
30 import java.text.DecimalFormat;
31 import java.text.NumberFormat;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.StringTokenizer;
35
36 @org.apache.myfaces.tobago.apt.annotation.Converter(id = DurationConverter.CONVERTER_ID)
37 public class DurationConverter implements Converter {
38
39 private static final Logger LOG = LoggerFactory.getLogger(DurationConverter.class);
40
41 public static final String CONVERTER_ID = "org.apache.myfaces.tobago.Duration";
42
43 private static final String NANO = "nano";
44 private static final String MILLI = "milli";
45 private static final String SECOND = "second";
46 private static final String MINUTE = "minute";
47 private static final String HOUR = "hour";
48 private static final String DAY = "day";
49 private static final String YEAR = "year";
50
51 public String getAsString(
52 FacesContext facesContext, UIComponent component, Object object)
53 throws ConverterException {
54 if (object == null || object instanceof String) {
55 return (String) object;
56 }
57 double aDouble = ((Number) object).doubleValue();
58 boolean negative = false;
59 if (aDouble < 0) {
60 negative = true;
61 aDouble = -aDouble;
62 }
63 double factor = getUnitFactor(component);
64 aDouble = aDouble * factor;
65
66 NumberFormat format = new DecimalFormat("00");
67 long value = Double.valueOf(aDouble).longValue();
68 int seconds = (int) (value % 60);
69 value = value / 60;
70 int minutes = (int) (value % 60);
71 value = value / 60;
72 String string;
73 if (value > 0) {
74 string = (negative ? "-" : "") + value + ":"
75 + format.format(minutes) + ":"
76 + format.format(seconds);
77 } else {
78 string = (negative ? "-" : "") + minutes + ":"
79 + format.format(seconds);
80 }
81 if (LOG.isDebugEnabled()) {
82 LOG.debug("string = '{}'", string);
83 }
84 return string;
85 }
86
87 public Object getAsObject(
88 FacesContext facesContext, UIComponent component, String string)
89 throws ConverterException {
90 boolean negative = string.indexOf('-') > -1;
91 StringTokenizer tokenizer = new StringTokenizer(string, " :-");
92 List elements = new ArrayList();
93 while (tokenizer.hasMoreElements()) {
94 elements.add(tokenizer.nextElement());
95 }
96 int hours = 0;
97 int minutes;
98 int seconds;
99 switch (elements.size()) {
100 case 3:
101 hours = Integer.parseInt((String) elements.get(0));
102 minutes = Integer.parseInt((String) elements.get(1));
103 seconds = Integer.parseInt((String) elements.get(2));
104 break;
105 case 2:
106 minutes = Integer.parseInt((String) elements.get(0));
107 seconds = Integer.parseInt((String) elements.get(1));
108 break;
109 default:
110 throw new ConverterException("Cannot parse string='" + string + "'");
111 }
112 double factor = getUnitFactor(component);
113 long value = (long) (((hours * 60L + minutes) * 60L + seconds) / factor);
114 if (negative) {
115 return Long.valueOf(-value);
116 } else {
117 return Long.valueOf(value);
118 }
119 }
120
121 private static double getUnitFactor(UIComponent component) {
122 String unit = null;
123 if (component != null) {
124 unit = (String) component.getAttributes().get(Attributes.UNIT);
125 }
126 double factor;
127 if (unit == null) {
128 factor = 0.001;
129 } else if (NANO.equals(unit)) {
130 factor = 0.000000001;
131 } else if (MILLI.equals(unit)) {
132 factor = 0.001;
133 } else if (SECOND.equals(unit)) {
134 factor = 1.0;
135 } else if (MINUTE.equals(unit)) {
136 factor = 60.0;
137 } else if (HOUR.equals(unit)) {
138 factor = 3600.0;
139 } else if (DAY.equals(unit)) {
140 factor = 86400.0;
141 } else if (YEAR.equals(unit)) {
142 factor = 31556736.0;
143 } else {
144 LOG.warn("Unsupported unit: '" + unit + "'");
145 factor = 0.001;
146 }
147 return factor;
148 }
149
150 }