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

History | View | Annotate | Download (11.8 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
      if( r.scale == SCALE_NONE ) {
316
        r.scale = default_scale;
317
      }
318
      // Soporta precision y escala.
319
      if (r.precision < 1) {
320
        // Sin precision
321
        if (r.scale < 1) {
322
          // Sin precision y sin escala 
323
          // Asinamos los valores por defecto.
324
          r.precision = default_precision;
325
          r.scale = default_scale;
326
        } else {
327
          // Sin precision y con escala.
328
          if (r.scale <= max_precision) {
329
            // Sin precision y con escala < maxima precision.
330
            // Asignamos la precision a la maxima.
331
            r.precision = max_precision;
332
          } else {
333
            // Sin precision y con escala > maxima precision.
334
            // Esto es un error.
335
            // Asignamos la precision a la maxima y reducimos la escala
336
            // a la maxima precision.
337
            r.precision = max_precision;
338
            r.scale = max_precision;
339
          }
340
        }
341
      } else {
342
        // Con precision
343
        if (r.scale < 1) {
344
          // Con precision y sin escala.
345
          if (r.precision < max_precision) {
346
            // Con precision < maxima precision y sin escala.
347
            // Ponemos escala a 0.
348
            r.scale = 0;
349
          } else {
350
            // Con precision >= maxima precision y sin escala.
351
            // Dejaremos la precision a la maxima y la escala a 0.
352
            // Perdemos precision.
353
            r.precision = max_precision;
354
            r.scale = 0;
355
          }
356
        } else {
357
          // Con precision y escala.     
358
          if (r.precision > max_precision) {
359
            // Con precision mayor que la maxima y con escala.
360
            // Reducimos la precision a la maxima.
361
            r.precision = max_precision;
362
          }
363
          if (r.precision >= r.scale) {
364
            // Con precision y escala menor que la precision.     
365
            // Es correcto, no hacemos nada.
366
          } else {
367
            // Con precision y escala mayor que la precision.
368
            if (r.scale <= max_precision) {
369
              // Con precision y escala mayor que la precision y menor que la maxima precision.
370
              // Aumentamos la precision para soportar la escala indicada.
371
              r.precision = r.scale;
372
            } else {
373
              // Con precision y escala mayor que la precision y mayor que la maxima precision.
374
              // Ponemos la maxima precision y reducimos la escala a esta.
375
              // Perdemos precision.
376
              r.precision = max_precision;
377
              r.scale = max_precision;
378
            }
379
          }
380
        }
381
      }
382
    }
383
    return r;
384
  }
385

    
386
  @Override
387
  public int getMaxPrecision() {
388
    return this.max_precision;
389
  }
390

    
391
  @Override
392
  public int getDefaultPrecision() {
393
    return this.default_precision;
394
  }
395

    
396
  @Override
397
  public int getDefaultScale() {
398
    return this.default_scale;
399
  }
400
  
401
  @Override
402
    public int getDefaultSize() {
403
        return this.default_size;
404
    }
405
  
406
  @Override
407
  public DataType setDefaultSize(int size) {
408
      this.default_size = size;
409
      return this;
410
  }
411
}
412