Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / dataTypes / impl / DefaultDataType.java @ 2083

History | View | Annotate | Download (11.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.tools.dataTypes.impl;
25

    
26
import java.text.MessageFormat;
27

    
28
import org.gvsig.tools.dataTypes.CoercionException;
29
import org.gvsig.tools.dataTypes.DataType;
30
import org.gvsig.tools.dataTypes.DataTypes;
31
import org.gvsig.tools.dataTypes.Coercion;
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
import org.gvsig.tools.dataTypes.CoercionContext;
35

    
36
public class DefaultDataType implements DataType {
37

    
38
  private static final Logger LOG = LoggerFactory.getLogger(DefaultDataTypesManager.class);
39

    
40
  private static class DefaultNumberPrecisionAndScale implements NumberPrecisionAndScale {
41

    
42
    private int precision;
43
    private int scale;
44

    
45
    public DefaultNumberPrecisionAndScale(int precision, int scale) {
46
      this.precision = precision;
47
      this.scale = scale;
48
    }
49

    
50
    @Override
51
    public int getPrecision() {
52
      return this.precision;
53
    }
54

    
55
    @Override
56
    public int getScale() {
57
      return this.scale;
58
    }
59

    
60
    public void setPrecision(int precision) {
61
      this.precision = precision;
62
    }
63

    
64
    public void setScale(int scale) {
65
      this.scale = scale;
66
    }
67
  }
68

    
69
  public static final int NO_SUPPORT_SCALE = -1;
70
  public static final int NO_SUPPORT_PRECISION = -1;
71
  
72
  private static final NumberPrecisionAndScale EMPTY_PRECISION_AND_SCALE = new DefaultNumberPrecisionAndScale(0, 0);
73

    
74
  private Coercion coercion;
75
  private Class defaultClass;
76
  private String subtype;
77
  private int type;
78
  private String name;
79
  private String iconName;
80
  private int max_precision;
81
  private int default_precision;
82
  private int default_scale;
83
  private boolean fixedPrecision;
84

    
85
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion) {
86
    this(type, subtype, name, defaultClass, coercion, "datatype-any");
87
  }
88

    
89
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName) {
90
    this(type, subtype, name, defaultClass, coercion, "datatype-any", false, NO_SUPPORT_PRECISION, NO_SUPPORT_PRECISION, NO_SUPPORT_SCALE);
91
  }
92

    
93
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName, boolean isFixedPrecision, int max_precision, int default_precision) {
94
    this(type, subtype, name, defaultClass, coercion, "datatype-any", isFixedPrecision, max_precision, default_precision, NO_SUPPORT_SCALE);
95
  }
96

    
97
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName, boolean isFixedPrecision, int max_precision, int default_precision, int default_scale) {
98

    
99
    if (name == null) {
100
      LOG.trace("Can't register null type name for type {}.", new Object[]{Integer.toHexString(type).toUpperCase()});
101
      throw new IllegalArgumentException();
102
    }
103
    this.type = type;
104
    this.subtype = subtype;
105
    this.name = name;
106
    this.defaultClass = defaultClass;
107
    this.coercion = coercion;
108
    this.iconName = iconName == null ? "datatype-any" : iconName;
109
    this.max_precision = max_precision;
110
    this.default_precision = default_precision;
111
    this.default_scale = default_scale;
112
    this.fixedPrecision = isFixedPrecision;
113
  }
114

    
115
  @Override
116
  public DataType clone() throws CloneNotSupportedException {
117
    DefaultDataType other = (DefaultDataType) super.clone();
118
    if (other.coercion instanceof Coercions) {
119
      this.coercion = ((Coercions) this.coercion).clone();
120
    }
121
    return other;
122
  }
123

    
124
  @Override
125
  public String getLabel() {
126
    return this.getName();
127
  }
128

    
129
  @Override
130
  public DataType getValue() {
131
    return this;
132
  }
133

    
134
  @Override
135
  public Object coerce(Object value) throws CoercionException {
136
    // http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion
137

    
138
    if (this.coercion != null) {
139
      return this.coercion.coerce(value);
140
    }
141
    if (defaultClass == null) {
142
      return value; // ??
143
    }
144
    if (defaultClass.isInstance(value)) {
145
      return value;
146
    }
147
    throw new CoercionException();
148
  }
149

    
150
  @Override
151
  public Object coerce(Object value, CoercionContext context) throws CoercionException {
152
    // http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion
153
    if (this.coercion != null) {
154
      return this.coercion.coerce(value, context);
155
    }
156
    if (defaultClass == null) {
157
      return value; // ??
158
    }
159
    if (defaultClass.isInstance(value)) {
160
      return value;
161
    }
162
    throw new CoercionException();
163
  }
164

    
165
  @Override
166
  public Coercion getCoercion() {
167
    return this.coercion;
168
  }
169

    
170
  @Override
171
  public Class getDefaultClass() {
172
    return this.defaultClass;
173
  }
174

    
175
  @Override
176
  public String getSubtype() {
177
    return this.subtype;
178
  }
179

    
180
  @Override
181
  public int getType() {
182
    return this.type;
183
  }
184

    
185
  @Override
186
  public String getName() {
187
    return this.name;
188
  }
189

    
190
  @Override
191
  public String getIconName() {
192
    return this.iconName;
193
  }
194

    
195
  @Override
196
  public boolean isContainer() {
197
    return (type & DataTypes.CONTAINER) == DataTypes.CONTAINER;
198
  }
199

    
200
  @Override
201
  public boolean isObject() {
202
    return (type & DataTypes.OBJECT) == DataTypes.OBJECT;
203
  }
204

    
205
  @Override
206
  public boolean isDynObject() {
207
    return type == DataTypes.DYNOBJECT;
208
  }
209

    
210
//  @Override
211
  public void setCoercion(Coercion coercion) {
212
    this.coercion = coercion;
213
    LOG.trace("Add coercion operation for data type {}.", new Object[]{name});
214
  }
215

    
216
  @Override
217
  public void addCoercion(Coercion coercion) {
218
    if (this.coercion == null) {
219
      this.setCoercion(coercion);
220
      return;
221
    }
222
    Coercions coercions;
223
    if (this.coercion instanceof Coercions) {
224
      coercions = (Coercions) this.coercion;
225
    } else {
226
      coercions = new Coercions();
227
      coercions.add(this.coercion);
228
      this.coercion = coercions;
229
    }
230
    coercions.add(coercion);
231
    LOG.trace("Add coercion operation for data type {}.", new Object[]{name});
232
  }
233

    
234
  @Override
235
  public String toString() {
236
    return MessageFormat.format(
237
            "type=0x{0};subtype={1};name={2};class={3};coercion={4}",
238
            new Object[]{
239
              Integer.toHexString(type).toUpperCase(),
240
              subtype,
241
              name,
242
              defaultClass == null ? null : defaultClass.getName(),
243
              coercion == null ? null : coercion.getClass().getName()
244
            }
245
    );
246
  }
247

    
248
  @Override
249
  public boolean isNumeric() {
250
    if (type == DataTypes.DOUBLE
251
            || type == DataTypes.FLOAT
252
            || type == DataTypes.BYTE
253
            || type == DataTypes.INT
254
            || type == DataTypes.LONG
255
            || type == DataTypes.DECIMAL) {
256
      return true;
257
    }
258
    return false;
259
  }
260

    
261
  @Override
262
  public boolean supportSize() {
263
    switch (this.type) {
264
      case DataTypes.STRING:
265
      case DataTypes.BYTEARRAY:
266
        return true;
267
      default:
268
        return false;
269
    }
270
  }
271

    
272
  @Override
273
  public boolean supportPrecision() {
274
    return this.max_precision!=NO_SUPPORT_PRECISION;
275
  }
276

    
277
  @Override
278
  public boolean supportScale() {
279
    return this.default_scale!=NO_SUPPORT_SCALE;
280
  }
281

    
282
  @Override
283
  public NumberPrecisionAndScale fixPrecisionAndScale(int precision, int scale) {
284
    if( this.max_precision==NO_SUPPORT_PRECISION ) {
285
       return EMPTY_PRECISION_AND_SCALE;
286
    }
287
    DefaultNumberPrecisionAndScale r = new DefaultNumberPrecisionAndScale(
288
            precision, 
289
            scale
290
    );
291
    if( this.fixedPrecision ) {
292
      r.precision = max_precision;
293
    }
294
    if( this.default_scale==NO_SUPPORT_SCALE ) {
295
      // Soporta precision y no escala (byte, int, long... enteros)
296
      r.scale = 0;
297
      if( r.precision > max_precision ) {
298
        r.precision = max_precision;
299
      }
300
    } else {
301
      // Soporta precision y escala.
302
      if (r.precision < 1) {
303
        // Sin precision
304
        if (r.scale < 1) {
305
          // Sin precision y sin escala 
306
          // Asinamos los valores por defecto.
307
          r.precision = default_precision;
308
          r.scale = default_scale;
309
        } else {
310
          // Sin precision y con escala.
311
          if (r.scale <= max_precision) {
312
            // Sin precision y con escala < maxima precision.
313
            // Asignamos la precision a la maxima.
314
            r.precision = max_precision;
315
          } else {
316
            // Sin precision y con escala > maxima precision.
317
            // Esto es un error.
318
            // Asignamos la precision a la maxima y reducimos la escala
319
            // a la maxima precision.
320
            r.precision = max_precision;
321
            r.scale = max_precision;
322
          }
323
        }
324
      } else {
325
        // Con precicion
326
        if (r.scale < 1) {
327
          // Con precision y sin escala.
328
          // Esto no es del todo correto. 
329
          // Probablemente algunos proveedores lo convertirian a int. 
330
          // Vamos a forzar que siempre tenga 1 decimal.
331
          if (r.precision < max_precision) {
332
            // Con precision < maxima precision y sin escala.
333
            // Aumentamos la precision en 1 para a?adirle un decimal.
334
            r.precision += 1;
335
            r.scale = 1;
336
          } else {
337
            // Con precision >= maxima precision y sin escala.
338
            // No podemos aumentar la precision para a?adirle un decimal. 
339
            // Le a?adiremos 1 decimal, y dejaremos la precision a la maxima.
340
            // Perdemos precision.
341
            r.precision = max_precision;
342
            r.scale = 1;
343
          }
344
        } else {
345
          // Con precision y escala.     
346
          if (r.precision > max_precision) {
347
            // Con precision mayor que la maxima y con escala.
348
            // Reducimos la precision a la maxima.
349
            r.precision = max_precision;
350
          }
351
          if (r.precision >= r.scale) {
352
            // Con precision y escala menor que la precision.     
353
            // Es correcto, no hacemos nada.
354
          } else {
355
            // Con precision y escala mayor que la precision.
356
            if (r.scale <= max_precision) {
357
              // Con precision y escala mayor que la precision y menor que la maxima precision.
358
              // Aumentamos la precision para soportar la escala indicada.
359
              r.precision = r.scale;
360
            } else {
361
              // Con precision y escala mayor que la precision y mayor que la maxima precision.
362
              // Ponemos la maxima precision y reducimos la escala a esta.
363
              // Perdemos precision.
364
              r.precision = max_precision;
365
              r.scale = max_precision;
366
            }
367
          }
368
        }
369
      }
370
    }
371
    return r;
372
  }
373

    
374
  @Override
375
  public int getMaxPrecision() {
376
    return this.max_precision;
377
  }
378

    
379
  @Override
380
  public int getDefaultPrecision() {
381
    return this.default_precision;
382
  }
383

    
384
  @Override
385
  public int getDefaultScale() {
386
    return this.default_scale;
387
  }
388

    
389
  public boolean isFixedPrecision() {
390
    return this.fixedPrecision;
391
  }
392
}