OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 21 | Rev 67 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.openoffice;
15
 
21 ilm 16
import org.openconcerto.utils.FormatGroup;
25 ilm 17
import org.openconcerto.utils.TimeUtils;
21 ilm 18
import org.openconcerto.utils.XMLDateFormat;
19
 
17 ilm 20
import java.math.BigDecimal;
21 ilm 21
import java.text.Format;
17 ilm 22
import java.text.ParseException;
23
import java.text.SimpleDateFormat;
24
import java.util.Arrays;
25
import java.util.Calendar;
26
import java.util.Date;
27
import java.util.List;
28
 
21 ilm 29
import javax.xml.datatype.Duration;
30
 
17 ilm 31
/**
32
 * A type of value, as per 16.1 "Data Types" and 6.7.1 "Variable Value Types and Values"
33
 */
34
public enum ODValueType {
35
 
36
    /**
37
     * Parses to {@link BigDecimal} to return the exact number.
38
     */
39
    FLOAT("value", Number.class) {
40
 
41
        @Override
42
        public String format(Object o) {
43
            // avoid 1.23E+3
44
            if (o instanceof BigDecimal)
45
                return ((BigDecimal) o).toPlainString();
46
            else
47
                return ((Number) o).toString();
48
        }
49
 
50
        @Override
51
        public BigDecimal parse(String s) {
52
            return new BigDecimal(s);
53
        }
54
 
55
    },
56
    PERCENTAGE("value", Number.class) {
57
 
58
        @Override
59
        public String format(Object o) {
60
            return FLOAT.format(o);
61
        }
62
 
63
        @Override
64
        public Object parse(String s) {
65
            return FLOAT.parse(s);
66
        }
67
 
68
    },
69
    CURRENCY("value", Number.class) {
70
 
71
        @Override
72
        public String format(Object o) {
73
            return FLOAT.format(o);
74
        }
75
 
76
        @Override
77
        public Object parse(String s) {
78
            return FLOAT.parse(s);
79
        }
80
    },
81
    DATE("date-value", Date.class, Calendar.class) {
82
 
83
        @Override
84
        public String format(Object o) {
85
            final Date d = o instanceof Calendar ? ((Calendar) o).getTime() : (Date) o;
21 ilm 86
            return DATE_FORMAT.format(d);
17 ilm 87
        }
88
 
89
        @Override
90
        public Date parse(String date) {
91
            if (date.length() == 0)
92
                return null;
93
            else {
94
                try {
21 ilm 95
                    return (Date) DATE_FORMAT.parseObject(date);
17 ilm 96
                } catch (ParseException e) {
97
                    throw new IllegalStateException("wrong date: " + date, e);
98
                }
99
            }
100
        }
101
 
102
    },
21 ilm 103
    TIME("time-value", Duration.class, Calendar.class) {
104
 
17 ilm 105
        @Override
106
        public String format(Object o) {
21 ilm 107
            if (o instanceof Duration) {
108
                return o.toString();
109
            } else {
110
                final Calendar cal = (Calendar) o;
25 ilm 111
                return TimeUtils.timePartToDuration(cal).toString();
21 ilm 112
            }
17 ilm 113
        }
114
 
115
        @Override
21 ilm 116
        public Duration parse(String date) {
17 ilm 117
            if (date.length() == 0)
118
                return null;
119
            else {
25 ilm 120
                return TimeUtils.getTypeFactory().newDuration(date);
17 ilm 121
            }
122
        }
123
 
124
    },
125
    BOOLEAN("boolean-value", Boolean.class) {
126
 
127
        @Override
128
        public String format(Object o) {
129
            return ((Boolean) o).toString().toLowerCase();
130
        }
131
 
132
        @Override
133
        public Boolean parse(String s) {
134
            return Boolean.valueOf(s);
135
        }
136
 
137
    },
138
    STRING("string-value", String.class) {
139
 
140
        @Override
141
        public String format(Object o) {
142
            return o.toString();
143
        }
144
 
145
        @Override
146
        public String parse(String s) {
147
            return s;
148
        }
149
    };
150
 
151
    private final String attr;
152
    private final List<Class<?>> acceptedClasses;
153
 
154
    private ODValueType(String attr, Class<?>... classes) {
155
        this.attr = attr;
156
        this.acceptedClasses = Arrays.asList(classes);
157
    }
158
 
159
    /**
160
     * The name of the value attribute for this value type.
161
     *
162
     * @return the value attribute, eg "boolean-value".
163
     */
164
    public final String getValueAttribute() {
165
        return this.attr;
166
    }
167
 
168
    public boolean canFormat(Class<?> toFormat) {
169
        for (final Class<?> c : this.acceptedClasses)
170
            if (c.isAssignableFrom(toFormat))
171
                return true;
172
        return false;
173
    }
174
 
175
    public abstract String format(Object o);
176
 
177
    public abstract Object parse(String s);
178
 
179
    /**
180
     * The value for the value-type attribute.
181
     *
182
     * @return the value for the value-type attribute, eg "float".
183
     */
184
    public final String getName() {
185
        return this.name().toLowerCase();
186
    }
187
 
188
    /**
189
     * The instance for the passed value type.
190
     *
191
     * @param name the value of the value-type attribute, eg "date".
192
     * @return the corresponding instance, eg {@link #DATE}.
193
     */
194
    public static ODValueType get(String name) {
195
        return ODValueType.valueOf(name.toUpperCase());
196
    }
197
 
198
    /**
199
     * Try to guess the value type for the passed object.
200
     *
201
     * @param o the object.
202
     * @return a value type capable of formatting <code>o</code> or <code>null</code>.
25 ilm 203
     * @throws NullPointerException if <code>o</code> is <code>null</code>.
17 ilm 204
     */
25 ilm 205
    public static ODValueType forObject(Object o) throws NullPointerException {
206
        if (o == null)
207
            throw new NullPointerException();
17 ilm 208
        if (o instanceof Number)
209
            return FLOAT;
210
        else if (o instanceof Boolean)
211
            return BOOLEAN;
212
        else if (o instanceof String)
213
            return STRING;
25 ilm 214
        else if (o instanceof Duration)
17 ilm 215
            return TIME;
216
        else if (DATE.canFormat(o.getClass()))
217
            return DATE;
218
        else
219
            return null;
220
    }
221
 
21 ilm 222
    // see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#isoformats
223
 
224
    static private final Format DATE_FORMAT;
225
    static {
226
        // first date and time so we don't loose time information on format() or parse()
227
        // MAYBE add HH':'mm':'ss,SSS for OOo 1
228
        DATE_FORMAT = new FormatGroup(new XMLDateFormat(), new SimpleDateFormat("yyyy-MM-dd'T'HH':'mm':'ss"), new SimpleDateFormat("yyyy-MM-dd"));
229
    }
17 ilm 230
}