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 @ 2227

History | View | Annotate | Download (12.3 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
  private static final NumberPrecisionAndScale EMPTY_PRECISION_AND_SCALE = new DefaultNumberPrecisionAndScale(PRECISION_NONE, SCALE_NONE);
70

    
71
  private Coercion coercion;
72
  private Class defaultClass;
73
  private String subtype;
74
  private int type;
75
  private String name;
76
  private String iconName;
77
  private int max_precision;
78
  private int default_precision;
79
  private int default_scale;
80
  private int default_size;
81
  private int flags;
82

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

    
87
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName) {
88
    this(type, subtype, name, defaultClass, coercion, "datatype-any", 0, PRECISION_NONE, PRECISION_NONE, SCALE_NONE);
89
  }
90

    
91
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName, int psflag, int max_precision, int default_precision) {
92
    this(type, subtype, name, defaultClass, coercion, "datatype-any", psflag, max_precision, default_precision, SCALE_NONE);
93
  }
94

    
95
  DefaultDataType(int type, String subtype, String name, Class defaultClass, Coercion coercion, String iconName, int flags, int max_precision, int default_precision, int default_scale) {
96

    
97
    if (name == null) {
98
      LOG.trace("Can't register null type name for type {}.", new Object[]{Integer.toHexString(type).toUpperCase()});
99
      throw new IllegalArgumentException();
100
    }
101
    this.type = type;
102
    this.subtype = subtype;
103
    this.name = name;
104
    this.defaultClass = defaultClass;
105
    this.coercion = coercion;
106
    this.iconName = iconName == null ? "datatype-any" : iconName;
107
    
108
    this.flags = flags;
109
    if( (this.flags&FLAG_FLOATING_POINT)==FLAG_FLOATING_POINT ) {
110
      this.flags |= FLAG_NUMBER;
111
    }
112
    if( (this.flags&FLAG_SUPPORT_PRECISION)==FLAG_SUPPORT_PRECISION ) {
113
      this.max_precision = max_precision;
114
      if( this.default_precision>max_precision ) {
115
        this.default_precision = max_precision;
116
      } else {
117
        this.default_precision = default_precision;
118
      }
119
      if( (this.flags&FLAG_SUPPORT_SCALE)==FLAG_SUPPORT_SCALE ) {
120
        if( this.default_scale>this.max_precision ) {
121
          this.default_scale = this.max_precision -1;
122
        } else {
123
          this.default_scale = default_scale;
124
        }
125
      } else {
126
        this.default_scale = SCALE_NONE;
127
      }
128
    } else {
129
      this.max_precision = PRECISION_NONE;
130
      this.default_precision = PRECISION_NONE;
131
      this.default_scale = SCALE_NONE;
132
    }
133
  }
134

    
135
  @Override
136
  public DataType clone() throws CloneNotSupportedException {
137
    DefaultDataType other = (DefaultDataType) super.clone();
138
    if (other.coercion instanceof Coercions) {
139
      this.coercion = ((Coercions) this.coercion).clone();
140
    }
141
    return other;
142
  }
143

    
144
  @Override
145
  public String getLabel() {
146
    return this.getName();
147
  }
148

    
149
  @Override
150
  public DataType getValue() {
151
    return this;
152
  }
153

    
154
  @Override
155
  public Object coerce(Object value) throws CoercionException {
156
    // http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion
157

    
158
    if (this.coercion != null) {
159
      return this.coercion.coerce(value);
160
    }
161
    if (defaultClass == null) {
162
      return value; // ??
163
    }
164
    if (defaultClass.isInstance(value)) {
165
      return value;
166
    }
167
    throw new CoercionException();
168
  }
169

    
170
  @Override
171
  public Object coerce(Object value, CoercionContext context) throws CoercionException {
172
    // http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion
173
    if (this.coercion != null) {
174
      return this.coercion.coerce(value, context);
175
    }
176
    if (defaultClass == null) {
177
      return value; // ??
178
    }
179
    if (defaultClass.isInstance(value)) {
180
      return value;
181
    }
182
    throw new CoercionException();
183
  }
184

    
185
  @Override
186
  public Coercion getCoercion() {
187
    return this.coercion;
188
  }
189

    
190
  @Override
191
  public Class getDefaultClass() {
192
    return this.defaultClass;
193
  }
194

    
195
  @Override
196
  public String getSubtype() {
197
    return this.subtype;
198
  }
199

    
200
  @Override
201
  public int getType() {
202
    return this.type;
203
  }
204

    
205
  @Override
206
  public String getName() {
207
    return this.name;
208
  }
209

    
210
  @Override
211
  public String getIconName() {
212
    return this.iconName;
213
  }
214

    
215
  @Override
216
  public boolean isContainer() {
217
    return (type & DataTypes.CONTAINER) == DataTypes.CONTAINER;
218
  }
219

    
220
  @Override
221
  public boolean isObject() {
222
    return (type & DataTypes.OBJECT) == DataTypes.OBJECT;
223
  }
224

    
225
  @Override
226
  public boolean isDynObject() {
227
    return type == DataTypes.DYNOBJECT;
228
  }
229

    
230
//  @Override
231
  public void setCoercion(Coercion coercion) {
232
    this.coercion = coercion;
233
    LOG.trace("Add coercion operation for data type {}.", new Object[]{name});
234
  }
235

    
236
  @Override
237
  public void addCoercion(Coercion coercion) {
238
    if (this.coercion == null) {
239
      this.coercion = coercion;
240
      return;
241
    }
242
    Coercions coercions;
243
    if (this.coercion instanceof Coercions) {
244
      coercions = (Coercions) this.coercion;
245
    } else {
246
      coercions = new Coercions();
247
      coercions.add(this.coercion);
248
      this.coercion = coercions;
249
    }
250
    coercions.add(coercion);
251
    LOG.trace("Add coercion operation for data type {}.", new Object[]{name});
252
  }
253

    
254
  @Override
255
  public String toString() {
256
    return getLabel();
257
  }
258

    
259
  @Override
260
  public boolean isNumeric() {
261
    return (this.flags&FLAG_NUMBER) == FLAG_NUMBER;
262
  }
263

    
264
  @Override
265
  public boolean supportSize() {
266
    return (this.flags&FLAG_SUPPORT_SIZE) == FLAG_SUPPORT_SIZE;
267
  }
268

    
269
  @Override
270
  public boolean supportPrecision() {
271
    return (this.flags&FLAG_SUPPORT_PRECISION) == FLAG_SUPPORT_PRECISION;
272
  }
273

    
274
  @Override
275
  public boolean supportScale() {
276
    return (this.flags&FLAG_SUPPORT_SCALE) == FLAG_SUPPORT_SCALE;
277
  }
278

    
279
  @Override
280
  public boolean isPredefinedPrecision() {
281
    return (this.flags&FLAG_PREDEFINED_PRECISION) == FLAG_PREDEFINED_PRECISION ;
282
  }
283

    
284
  @Override
285
  public boolean isFloatingPoint() {
286
    return (this.flags&FLAG_FLOATING_POINT) == FLAG_FLOATING_POINT ;
287
  }
288
  
289
  @Override
290
  public int getFlags() {
291
    return this.flags;
292
  }
293

    
294
  @Override
295
  public NumberPrecisionAndScale fixPrecisionAndScale(int precision, int scale) {
296
    if ((this.flags & FLAG_SUPPORT_PRECISION) != FLAG_SUPPORT_PRECISION) {
297
      return EMPTY_PRECISION_AND_SCALE;
298
    }
299
    DefaultNumberPrecisionAndScale r = new DefaultNumberPrecisionAndScale(
300
            precision,
301
            scale
302
    );
303
    if ((this.flags & FLAG_PREDEFINED_PRECISION) == FLAG_PREDEFINED_PRECISION) {
304
      r.precision = max_precision;
305
    }
306
    if ((this.flags & FLAG_SUPPORT_SCALE) != FLAG_SUPPORT_SCALE) {
307
      // Soporta precision y no escala (byte, int, long... enteros)
308
      r.scale = 0;
309
      if (r.precision > max_precision) {
310
        r.precision = max_precision;
311
      } else if (r.precision < 1) {
312
        r.precision = default_precision;
313
      }
314
    } else {
315
      // Soporta precision y escala (BigDecimal)
316
      if (r.precision < 1) { 
317
        // Sin precision
318
        if (r.scale < 1) {
319
          // Sin precision y sin escala 
320
          // Asignamos los valores por defecto.
321
          r.precision = default_precision;
322
          r.scale = default_scale;
323
        } else {
324
          // Sin precision y con escala.
325
          if (r.scale <= default_scale) {
326
            // Sin precision y con escala < maxima precision.
327
            // Asignamos la precision a la maxima.
328
            r.precision = default_precision;
329
          } else if (r.scale < default_precision) {
330
            // Sin precision y con escala < maxima precision.
331
            // Asignamos la precision a la maxima.
332
            r.precision = default_precision;
333
          } else if (r.scale <= max_precision) {
334
            // Sin precision y con escala < maxima precision.
335
            // Asignamos la precision a la maxima.
336
            r.precision = max_precision;
337
          } else {
338
            // Sin precision y con escala > maxima precision.
339
            // Esto es un error.
340
            // Asignamos la precision a la maxima y reducimos la escala
341
            // a la maxima precision.
342
            r.precision = max_precision;
343
            r.scale = max_precision;
344
          }
345
        }
346
      } else {
347
        // Con precision
348
        if (r.scale < 1) {
349
          // Con precision y sin escala.
350
          if (r.precision < max_precision) {
351
            // Con precision < maxima precision y sin escala.
352
            // Ponemos escala a 0.
353
            r.scale = 0;
354
          } else {
355
            // Con precision >= maxima precision y sin escala.
356
            // Dejaremos la precision a la maxima y la escala a 0.
357
            // Perdemos precision.
358
            r.precision = max_precision;
359
            r.scale = 0;
360
          }
361
        } else {
362
          // Con precision y escala.     
363
          if (r.precision > max_precision) {
364
            // Con precision mayor que la maxima y con escala.
365
            // Reducimos la precision a la maxima.
366
            r.precision = max_precision;
367
          }
368
          if (r.precision >= r.scale) {
369
            // Con precision y escala menor que la precision.     
370
            // Es correcto, no hacemos nada.
371
          } else {
372
            // Con precision y escala mayor que la precision.
373
            if (r.scale <= max_precision) {
374
              // Con precision y escala mayor que la precision y menor que la maxima precision.
375
              // Aumentamos la precision para soportar la escala indicada.
376
              r.precision = r.scale;
377
            } else {
378
              // Con precision y escala mayor que la precision y mayor que la maxima precision.
379
              // Ponemos la maxima precision y reducimos la escala a esta.
380
              // Perdemos precision.
381
              r.precision = max_precision;
382
              r.scale = max_precision;
383
            }
384
          }
385
        }
386
      }
387
    }
388
    if( (this.flags & FLAG_FLOATING_POINT) == FLAG_FLOATING_POINT ) {
389
      if( r.scale<1 ) {
390
        r.scale = SCALE_NONE;
391
      }
392
    }
393
    return r;
394
  }
395

    
396
  @Override
397
  public int getMaxPrecision() {
398
    return this.max_precision;
399
  }
400

    
401
  @Override
402
  public int getDefaultPrecision() {
403
    return this.default_precision;
404
  }
405

    
406
  @Override
407
  public int getDefaultScale() {
408
    return this.default_scale;
409
  }
410
  
411
  @Override
412
    public int getDefaultSize() {
413
        return this.default_size;
414
    }
415
  
416
  @Override
417
  public DataType setDefaultSize(int size) {
418
      this.default_size = size;
419
      return this;
420
  }
421
}
422