Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / feature / spi / ExpressionBuilderBase.java @ 43739

History | View | Annotate | Download (43.9 KB)

1
package org.gvsig.fmap.dal.feature.spi;
2

    
3
import java.text.MessageFormat;
4
import java.util.ArrayList;
5
import java.util.Collection;
6
import java.util.Collections;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Objects;
12
import java.util.Set;
13
import org.apache.commons.lang3.ObjectUtils;
14
import org.apache.commons.lang3.StringUtils;
15
import org.cresques.cts.IProjection;
16
import org.gvsig.fmap.dal.DataStoreParameters;
17
import org.gvsig.fmap.dal.DataTypes;
18
import org.gvsig.fmap.dal.ExpressionBuilder;
19
import org.gvsig.fmap.dal.ExpressionBuilder.BinaryOperator;
20
import org.gvsig.fmap.dal.ExpressionBuilder.Config;
21
import org.gvsig.fmap.dal.ExpressionBuilder.Constant;
22
import org.gvsig.fmap.dal.ExpressionBuilder.Custom;
23
import org.gvsig.fmap.dal.ExpressionBuilder.Function;
24
import org.gvsig.fmap.dal.ExpressionBuilder.GeometrySupportType;
25
import org.gvsig.fmap.dal.ExpressionBuilder.GeometryValue;
26
import org.gvsig.fmap.dal.ExpressionBuilder.Group;
27
import org.gvsig.fmap.dal.ExpressionBuilder.Parameter;
28
import org.gvsig.fmap.dal.ExpressionBuilder.ParameterType;
29
import org.gvsig.fmap.dal.ExpressionBuilder.Value;
30
import org.gvsig.fmap.dal.ExpressionBuilder.Variable;
31
import org.gvsig.fmap.dal.ExpressionBuilder.Visitable;
32
import org.gvsig.fmap.dal.ExpressionBuilder.Visitor;
33
import org.gvsig.fmap.dal.ExpressionBuilder.VisitorFilter;
34
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.geom.Geometry;
37
import org.gvsig.fmap.geom.primitive.Envelope;
38

    
39
@SuppressWarnings("UseSpecificCatch")
40
public class ExpressionBuilderBase implements ExpressionBuilder {
41

    
42
    public class ConfigBase implements Config {
43

    
44
        protected Map<String, Object> values;
45

    
46
        public ConfigBase() {
47
            this.values = new HashMap<>();
48

    
49
            this.set(Config.has_spatial_functions, false);
50
            this.set(Config.support_schemas, true);
51
            this.set(Config.constant_true, "(1=1)");
52
            this.set(Config.constant_false, "(1=2)");
53
            this.set(Config.quote_for_identifiers, "\"");
54
            this.set(Config.quote_for_strings, "'");
55
            this.set(Config.geometry_type_support, GeometrySupportType.WKT);
56
            this.set(Config.group, "( {0} )");
57

    
58
            this.set(Config.Find_SRID, "Find_SRID(({0}), ({1}), ({2}))");
59
            this.set(Config.ST_SRID, "ST_SRID({0})");
60
            this.set(Config.ST_AsText, "ST_AsText({0})");
61
            this.set(Config.ST_AsBinary, "ST_AsBinary({0})");
62
            this.set(Config.ST_AsEWKB, "ST_AsEWKB({0})");
63
            this.set(Config.ST_Contains, "ST_Contains(({0}), ({1}))");
64
            this.set(Config.ST_Crosses, "ST_Crosses(({0}), ({1}))");
65
            this.set(Config.ST_Disjoint, "ST_Disjoint(({0}), ({1}))");
66
            this.set(Config.ST_Equals, "ST_Equals(({0}), ({1}))");
67
            this.set(Config.ST_IsClosed, "ST_IsClosed({0})");
68
            this.set(Config.ST_Overlaps, "ST_Overlaps(({0}), ({1}))");
69
            this.set(Config.ST_Touches, "ST_Touches(({0}), ({1}))");
70
            this.set(Config.ST_Within, "ST_Within(({0}), ({1}))");
71
            this.set(Config.ST_Envelope, "ST_Envelope({0})");
72
            this.set(Config.ST_Intersects, "ST_Intersects(({0}), ({1}))");
73
            this.set(Config.ST_GeomFromText, "ST_GeomFromText({0}, ({1}))");
74
            this.set(Config.ST_GeomFromWKB, "ST_GeomFromWKB(({0}), ({1}))");
75
            this.set(Config.ST_GeomFromEWKB, "ST_GeomFromEWKB(({0}), ({1}))");
76
            
77
            // Por defecto no esta disponible la funcion ST_Simplify
78
            // El proveedor que la soporte que la defina.
79
            // this.set(Config.ST_Simplify, "ST_Simplify(({0}), ({1}))");
80
            this.remove_functionality(Config.ST_Simplify);
81
            
82
            this.set(Config.lcase, "LCASE({0})");
83
            this.set(Config.ucase, "UCASE({0})");
84
            this.set(Config.isNull, "( ({0}) IS NULL )");
85
            this.set(Config.notIsNull, "( ({0}) NOT IS NULL )");
86
            this.set(Config.operator_not, "( NOT ({0}) )");
87

    
88
            this.set(Config.operator_AND, "{0} AND {1}");
89
            this.set(Config.operator_OR, "{0} OR {1}");
90
            this.set(Config.operator_EQ, "( ({0}) = ({1}) )");
91
            this.set(Config.operator_NE, "( ({0}) <> ({1}) )");
92
            this.set(Config.operator_GT, "( ({0}) > ({1}) )");
93
            this.set(Config.operator_GE, "( ({0}) >= ({1}) )");
94
            this.set(Config.operator_LT, "( ({0}) < ({1}) )");
95
            this.set(Config.operator_LE, "( ({0}) <= ({1}) )");
96
            this.set(Config.operator_LIKE, "( ({0}) LIKE ({1}) )");
97
            this.set(Config.operator_ILIKE, "( ({0}) ILIKE ({1}) )");
98

    
99
            this.set(Config.operator_add, "{0} + {1}");
100
            this.set(Config.operator_subst, "{0} - {1}");
101
            this.set(Config.operator_mult, "{0} * {1}");
102
            this.set(Config.operator_div, "{0} / {1}");
103
            this.set(Config.operator_concat, "{0} || {1}");
104

    
105
        }
106

    
107
        @Override
108
        public boolean has_functionality(String functionality) {
109
            Object x = this.values.get(functionality);
110
            if (x == null) {
111
                return false;
112
            }
113
            if (x instanceof CharSequence && StringUtils.isEmpty((CharSequence) x)) {
114
                return false;
115
            }
116
            return true;
117
        }
118

    
119
        @Override
120
        public void remove_functionality(String functionality) {
121
            this.values.remove(functionality);
122
        }
123

    
124
        @Override
125
        public boolean has_spatial_functions() {
126
            return this.getBoolean(has_spatial_functions);
127
        }
128

    
129
        @Override
130
        public GeometrySupportType getGeometryTypeSupport() {
131
            return (GeometrySupportType) this.get(geometry_type_support);
132
        }
133

    
134
        @Override
135
        public boolean getBoolean(String name) {
136
            return (boolean) this.values.get(name);
137
        }
138

    
139
        @Override
140
        public String getString(String name) {
141
            return (String) this.values.get(name);
142
        }
143

    
144
        @Override
145
        public Object get(String name) {
146
            return this.values.get(name);
147
        }
148

    
149
        @Override
150
        public void set(String name, Object value) {
151
            this.values.put(name, value);
152
        }
153
    }
154

    
155
    public abstract class AbstractValue implements Value {
156

    
157
        @Override
158
        public void accept(Visitor visitor, VisitorFilter filter) {
159
            if (filter == null || filter.accept(this)) {
160
                visitor.visit(this);
161
            }
162
        }
163

    
164
    }
165

    
166
    public class ClassVisitorFilter implements VisitorFilter {
167

    
168
        private final Class classFilter;
169

    
170
        public ClassVisitorFilter(Class classFilter) {
171
            this.classFilter = classFilter;
172
        }
173

    
174
        @Override
175
        public boolean accept(Visitable visitable) {
176
            return classFilter.isInstance(visitable);
177
        }
178

    
179
    }
180

    
181
    public class GroupBase extends AbstractValue implements Group {
182

    
183
        protected Value value;
184

    
185
        public GroupBase(Value value) {
186
            this.value = value;
187
        }
188

    
189
        @Override
190
        public Value getValue() {
191
            return value;
192
        }
193

    
194
        @Override
195
        public void accept(Visitor visitor, VisitorFilter filter) {
196
            super.accept(visitor, filter);
197
            this.value.accept(visitor, filter);
198
        }
199

    
200
        @Override
201
        public String toString() {
202
            return MessageFormat.format(config.getString(Config.group), this.value.toString());
203
        }
204
    }
205
    protected class ColumnDescriptorBase implements ColumnDescriptor {
206

    
207
        private String name;
208
        private int type;
209
        private int type_p;
210
        private int type_s;
211
        private boolean isPk;
212
        private boolean _allowNulls;
213
        private boolean _isAutomatic;
214
        private Object defaultValue;
215
        private int geom_type;
216
        private int geom_subtype;
217
        private Object geom_srsdbcode;
218
        private boolean _isIndexed;
219
        private DataStoreParameters parameters = null;
220

    
221
        public ColumnDescriptorBase(String name, int type, Object defaultValue) {
222
            this.name = name;
223
            this.type = type;
224
            this.type_p = -1;
225
            this.type_s = -1;
226
            this.isPk = false;
227
            this._allowNulls = true;
228
            this._isAutomatic = false;
229
            this.defaultValue = defaultValue;
230
            this.geom_type = Geometry.TYPES.GEOMETRY;
231
            this.geom_subtype = Geometry.SUBTYPES.GEOM2D;
232
            this.geom_srsdbcode = null;
233
            this._isIndexed = false;
234
        }
235

    
236
        public ColumnDescriptorBase(String name, int type, int type_p, int type_s, boolean isPk, boolean isIndexed, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
237
            this.name = name;
238
            this.type = type;
239
            this.type_p = type_p;
240
            this.type_s = type_s;
241
            this.isPk = isPk;
242
            this._allowNulls = allowNulls;
243
            this._isAutomatic = isAutomatic;
244
            this.defaultValue = defaultValue;
245
            this.geom_type = Geometry.TYPES.GEOMETRY;
246
            this.geom_subtype = Geometry.SUBTYPES.GEOM2D;
247
            this.geom_srsdbcode = null;
248
            this._isIndexed = isIndexed;
249
        }
250
        
251
        public ColumnDescriptorBase(String name, int geom_type, int geom_subtype, IProjection proj, boolean isIndexed, boolean allowNulls) {
252
            this.name = name;
253
            this.type = DataTypes.GEOMETRY;
254
            this.type_p = 0;
255
            this.type_s = 0;
256
            this.isPk = false;
257
            this._allowNulls = allowNulls;
258
            this._isAutomatic = false;
259
            this.defaultValue = null;
260
            this.geom_type = geom_type;
261
            this.geom_subtype = geom_subtype;
262
            this.geom_srsdbcode = getSRSId(proj);
263
            this._isIndexed = isIndexed;
264
        }
265
        
266
        public ColumnDescriptorBase(String name, int geom_type, int geom_subtype, Object srsdbcode, boolean isIndexed, boolean allowNulls) {
267
            this.name = name;
268
            this.type = DataTypes.GEOMETRY;
269
            this.type_p = 0;
270
            this.type_s = 0;
271
            this.isPk = false;
272
            this._allowNulls = allowNulls;
273
            this._isAutomatic = false;
274
            this.defaultValue = null;
275
            this.geom_type = geom_type;
276
            this.geom_subtype = geom_subtype;
277
            this.geom_srsdbcode = srsdbcode;
278
            this._isIndexed = isIndexed;
279
        }
280
        
281
        @Override
282
        public String getName() {
283
            return this.name;
284
        }
285
        
286
        @Override
287
        public void setName(String name) {
288
            this.name = name;
289
        }
290

    
291
        @Override
292
        public int getType() {
293
            return this.type;
294
        }
295

    
296
        @Override
297
        public void setType(int type) {
298
            this.type = type;
299
        }
300

    
301
        @Override
302
        public int getPrecision() {
303
            return type_p;
304
        }
305

    
306
        @Override
307
        public void setPrecision(int precision) {
308
            this.type_p = precision;
309
        }
310

    
311
        @Override
312
        public int getSize() {
313
            return type_s;
314
        }
315

    
316
        @Override
317
        public void setSize(int size) {
318
            this.type_s = size;
319
        }
320

    
321
        @Override
322
        public boolean isPrimaryKey() {
323
            return isPk;
324
        }
325

    
326
        @Override
327
        public void setIsPrimaryKey(boolean isPk) {
328
            this.isPk = isPk;
329
        }
330

    
331
        @Override
332
        public boolean allowNulls() {
333
            return _allowNulls;
334
        }
335

    
336
        @Override
337
        public void setAllowNulls(boolean allowNulls) {
338
            this._allowNulls = allowNulls;
339
        }
340

    
341
        @Override
342
        public boolean isAutomatic() {
343
            return _isAutomatic;
344
        }
345

    
346
        @Override
347
        public boolean isIndexed() {
348
            return _isIndexed;
349
        }
350

    
351
        @Override
352
        public void setIsAutomatic(boolean isAutomatic) {
353
            this._isAutomatic = isAutomatic;
354
        }
355

    
356
        @Override
357
        public Object getDefaultValue() {
358
            return defaultValue;
359
        }
360

    
361
        @Override
362
        public void setDefaultValue(Object defaultValue) {
363
            this.defaultValue = defaultValue;
364
        }
365

    
366
        @Override
367
        public int getGeometryType() {
368
            return geom_type;
369
        }
370

    
371
        @Override
372
        public void setGeometryType(int geom_type) {
373
            this.geom_type = geom_type;
374
        }
375

    
376
        @Override
377
        public int getGeometrySubtype() {
378
            return geom_subtype;
379
        }
380

    
381
        @Override
382
        public void setGeometrySubtype(int geom_subtype) {
383
            this.geom_subtype = geom_subtype;
384
        }
385

    
386
        @Override
387
        public Object getGeometrySRSId() {
388
            return geom_srsdbcode;
389
        }
390

    
391
        @Override
392
        public void setGeometrySRSId(Object geom_srsid) {
393
            this.geom_srsdbcode = geom_srsid;
394
        }        
395

    
396
        @Override
397
        public boolean isGeometry() {
398
            return this.type == DataTypes.GEOMETRY;
399
        }
400

    
401
        private void setStoreParameters(DataStoreParameters parameters) {
402
            this.parameters = parameters;
403
        }
404

    
405
        @Override
406
        public DataStoreParameters getStoreParameters() {
407
            return this.parameters;
408
        }
409
    }
410

    
411
    public class VariableBase extends AbstractValue implements Variable {
412

    
413
        protected String name;
414
        protected ColumnDescriptor descriptor;
415

    
416
        public VariableBase(ColumnDescriptor descriptor) {
417
            this.descriptor = descriptor;
418
            this.name = descriptor.getName();
419
        }
420

    
421
        public VariableBase(String name) {
422
            this.descriptor = null;
423
            this.name = name;
424
        }
425

    
426
        @Override
427
        public ColumnDescriptor getDescriptor() {
428
            return descriptor;
429
        }
430
        
431
        @Override
432
        public String getName() {
433
            return this.name;
434
        }
435

    
436
        @Override
437
        public String toString() {
438
            return identifier(this.name);
439
        }
440

    
441
        @Override
442
        public int compareTo(Variable o) {
443
            return this.name.compareTo(o.getName());
444
        }
445

    
446
        @Override
447
        public boolean equals(Object obj) {
448
            if (!(obj instanceof Variable)) {
449
                return false;
450
            }
451
            return this.name.equals(((Variable) obj).getName());
452
        }
453

    
454
        @Override
455
        public int hashCode() {
456
            int hash = 7;
457
            hash = 37 * hash + Objects.hashCode(this.name);
458
            return hash;
459
        }
460
    }
461

    
462
    public class ParameterBase extends AbstractValue implements Parameter {
463

    
464
        protected String name;
465
        protected Object value;
466
        protected ParameterType type;
467
        protected Value srs;
468

    
469
        public ParameterBase() {
470
            this.type = ParameterType.Constant;
471
            this.name = null;
472
            this.value = null;
473
        }
474

    
475
        @Override
476
        public void accept(Visitor visitor, VisitorFilter filter) {
477
            super.accept(visitor, filter);
478
            if (this.srs != null) {
479
                this.srs.accept(visitor, filter);
480
            }
481
        }
482

    
483
        @Override
484
        public Parameter as_geometry_variable() {
485
            this.type = ParameterType.Geometry;
486
            if (this.value == null && this.name != null) {
487
                this.value = this.name;
488
            }
489
            return this;
490
        }
491

    
492
        @Override
493
        public Parameter as_constant() {
494
            this.type = ParameterType.Constant;
495
            if (this.value == null && this.name != null) {
496
                this.value = this.name;
497
            }
498
            return this;
499
        }
500

    
501
        @Override
502
        public Parameter as_variable() {
503
            this.type = ParameterType.Variable;
504
            if (this.value != null && this.name == null) {
505
                this.name = (String) this.value;
506
            }
507
            return this;
508
        }
509

    
510
        @Override
511
        public Parameter srs(Value srs) {
512
            this.srs = srs;
513
            if( this.type == ParameterType.Variable ) {
514
                this.type = ParameterType.Geometry;
515
            }
516
            return this;
517
        }
518

    
519
        @Override
520
        public Parameter srs(IProjection srs) {
521
            this.srs = constant(getSRSId(srs));
522
            if( this.type == ParameterType.Variable ) {
523
                this.type = ParameterType.Geometry;
524
            }
525
            return this;
526
        }
527

    
528
        @Override
529
        public String getName() {
530
            switch (this.type) {
531
                case Variable:
532
                case Geometry:
533
                    return this.name;
534
                case Constant:
535
                    if (this.value == null) {
536
                        return null;
537
                    }
538
                    return this.value.toString();
539
                default:
540
                    if (this.name != null) {
541
                        return this.name;
542
                    }
543
                    if (this.value != null) {
544
                        return this.value.toString();
545
                    }
546
                    return null;
547
            }
548
        }
549

    
550
        @Override
551
        public boolean is_constant() {
552
            return this.type == ParameterType.Constant;
553
        }
554

    
555
        @Override
556
        public boolean is_geometry_variable() {
557
            return this.type == ParameterType.Geometry;
558
        }
559

    
560
        @Override
561
        public boolean is_variable() {
562
            return this.type == ParameterType.Variable;
563
        }
564

    
565
        @Override
566
        public Parameter value(Object value) {
567
            this.value = value;
568
            return this;
569
        }
570

    
571
        @Override
572
        public Parameter name(String name) {
573
            this.type = ParameterType.Variable;
574
            this.name = name;
575
            return this;
576
        }
577

    
578
        @Override
579
        public Object getValue() {
580
            try {
581
                switch (this.type) {
582
                    case Constant:
583
                        if (this.value instanceof Geometry) {
584
                            switch (config.getGeometryTypeSupport()) {
585
                                case EWKB:
586
                                    return bytearray(((Geometry) this.value).convertToEWKB());
587
                                case NATIVE:
588
                                case WKB:
589
                                    return bytearray(((Geometry) this.value).convertToWKB());
590
                                case WKT:
591
                                default:
592
                                    return ((Geometry) this.value).convertToWKT();
593
                            }
594
                        } else if (this.value instanceof IProjection) {
595
                            return getSRSId((IProjection) this.value);
596
                        }
597
                        return this.value;
598
                    case Variable:
599
                    case Geometry:
600
                    default:
601
                        return this.value;
602
                }
603
            } catch (Exception ex) {
604
                throw new RuntimeException("Can't get value from parameter.", ex);
605
            }
606
        }
607

    
608
        @Override
609
        public ParameterType getType() {
610
            return this.type;
611
        }
612

    
613
        @Override
614
        public Value getSRS() {
615
            return this.srs;
616
        }
617

    
618
        @Override
619
        public String toString() {
620
            switch (this.type) {
621
                case Constant:
622
                case Variable:
623
                default:
624
                    return "?";
625
                case Geometry:
626
                    switch (config.getGeometryTypeSupport()) {
627
                        case EWKB:
628
                            return MessageFormat.format(
629
                                    config.getString(Config.ST_GeomFromEWKB),
630
                                    "?",
631
                                    String.valueOf(this.srs.toString())
632
                            );
633
                        case WKB:
634
                            return MessageFormat.format(
635
                                    config.getString(Config.ST_GeomFromWKB),
636
                                    "?",
637
                                    String.valueOf(this.srs.toString())
638
                            );
639
                        case WKT:
640
                        default:
641
                            return MessageFormat.format(
642
                                    config.getString(Config.ST_GeomFromText),
643
                                    "?",
644
                                    String.valueOf(this.srs.toString())
645
                            );
646
                    }
647
            }
648
        }
649
    }
650

    
651
    public class ConstantBase extends AbstractValue implements Constant {
652

    
653
        protected Object value;
654

    
655
        public ConstantBase(Object value) {
656
            this.value = value;
657
        }
658

    
659
        @Override
660
        public Object getValue() {
661
            return this.value;
662
        }
663

    
664
        @Override
665
        public String toString() {
666
            if (this.value instanceof String) {
667
                return string((String) this.value);
668
            }
669
            if (this.value instanceof Boolean) {
670
                if (((Boolean) this.value)) {
671
                    return config.getString(Config.constant_true);
672
                } else {
673
                    return config.getString(Config.constant_false);
674
                }
675
            }
676
            return ObjectUtils.toString(this.value, "");
677
        }
678
    }
679

    
680
    public class CustomBase extends AbstractValue implements Custom {
681

    
682
        protected Object value;
683

    
684
        // Esto es para permitir declarar parametros y columnas en una seccion
685
        // custom.
686
        protected List<Value> values;
687

    
688
        public CustomBase(Object value) {
689
            this.value = value;
690
        }
691

    
692
        @Override
693
        public void accept(Visitor visitor, VisitorFilter filter) {
694
            super.accept(visitor, filter);
695
            if (this.values != null) {
696
                for (Value value : values) {
697
                    value.accept(visitor, filter);
698
                }
699
            }
700
        }
701

    
702
        @Override
703
        public Object getValue() {
704
            return this.value;
705
        }
706

    
707
        @Override
708
        public Custom add(Variable variable) {
709
            if (this.values == null) {
710
                this.values = new ArrayList<>();
711
            }
712
            this.values.add(variable);
713
            return this;
714
        }
715

    
716
        @Override
717
        public Custom add(Parameter parameter) {
718
            if (this.values == null) {
719
                this.values = new ArrayList<>();
720
            }
721
            this.values.add(parameter);
722
            return this;
723
        }
724

    
725
        @Override
726
        public String toString() {
727
            return ObjectUtils.toString(this.value, "");
728
        }
729
    }
730

    
731
    public class GeometryValueBase extends AbstractValue implements GeometryValue {
732

    
733
        protected Geometry geometry;
734
        protected IProjection projection;
735

    
736
        public GeometryValueBase(Geometry geometry, IProjection projection) {
737
            this.geometry = geometry;
738
            this.projection = projection;
739
        }
740

    
741
        @Override
742
        public Geometry getGeometry() {
743
            return this.geometry;
744
        }
745

    
746
        @Override
747
        public IProjection getSRS() {
748
            return this.projection;
749
        }
750

    
751
        @Override
752
        public String toString() {
753
            try {
754
                switch (config.getGeometryTypeSupport()) {
755
                    case EWKB:
756
                        return MessageFormat.format(
757
                                config.getString(Config.ST_GeomFromEWKB),
758
                                bytearray(this.geometry.convertToEWKB()),
759
                                String.valueOf(getSRSId(this.projection))
760
                        );
761
                    case WKB:
762
                        return MessageFormat.format(
763
                                config.getString(Config.ST_GeomFromWKB),
764
                                bytearray(this.geometry.convertToWKB()),
765
                                String.valueOf(getSRSId(this.projection))
766
                        );
767
                    case WKT:
768
                    default:
769
                        return MessageFormat.format(
770
                                config.getString(Config.ST_GeomFromText),
771
                                string(this.geometry.convertToWKT()),
772
                                String.valueOf(getSRSId(this.projection))
773
                        );
774
                }
775
            } catch (Exception ex) {
776
                throw new RuntimeException("Can't convert geometry to string.", ex);
777
            }
778
        }
779
    }
780

    
781
    public class FunctionBase extends AbstractValue implements Function {
782

    
783
        protected String name;
784
        protected String format;
785
        protected List<Value> parameters;
786

    
787
        public FunctionBase(String name, String format) {
788
            this.name = name;
789
            this.format = format;
790
        }
791

    
792
        @Override
793
        public List<Value> parameters() {
794
            if (this.parameters == null) {
795
                this.parameters = new ArrayList<>();
796
            }
797
            return this.parameters;
798
        }
799

    
800
        @Override
801
        public Function parameter(Value parameter) {
802
            this.parameters().add(parameter);
803
            return this;
804
        }
805

    
806
        @Override
807
        public String getName() {
808
            return this.name;
809
        }
810

    
811
        @Override
812
        public void accept(Visitor visitor, VisitorFilter filter) {
813
            super.accept(visitor, filter);
814
            for (Value value : this.parameters) {
815
                value.accept(visitor, filter);
816
            }
817
        }
818

    
819
        @Override
820
        public String toString() {
821
            if (this.parameters != null && !this.parameters.isEmpty()) {
822
                List<String> values = new ArrayList<>();
823
                for (Value value : this.parameters) {
824
                    values.add(value.toString());
825
                }
826
                return MessageFormat.format(format, values.toArray());
827
            } else {
828
                return this.format;
829
            }
830
        }
831
    }
832

    
833
    public class BinaryOperatorBase extends AbstractValue implements BinaryOperator {
834

    
835
        protected String name;
836
        protected String format;
837
        protected Value left;
838
        protected Value right;
839

    
840
        public BinaryOperatorBase(String name, String format) {
841
            this.name = name;
842
            this.format = format;
843
        }
844

    
845
        @Override
846
        public String getName() {
847
            return this.name;
848
        }
849

    
850
        @Override
851
        public void accept(Visitor visitor, VisitorFilter filter) {
852
            super.accept(visitor, filter);
853
            this.left.accept(visitor, filter);
854
            this.right.accept(visitor, filter);
855
        }
856

    
857
        @Override
858
        public BinaryOperator setLeft(Value operand) {
859
            this.left = operand;
860
            return this;
861
        }
862

    
863
        @Override
864
        public BinaryOperator setRight(Value operand) {
865
            this.right = operand;
866
            return this;
867
        }
868

    
869
        @Override
870
        public Value getLeft() {
871
            return this.left;
872
        }
873

    
874
        @Override
875
        public Value getRight() {
876
            return this.right;
877
        }
878

    
879
        @Override
880
        public String toString() {
881
            return MessageFormat.format(
882
                    format,
883
                    this.left.toString(),
884
                    this.right.toString()
885
            );
886
        }
887
    }
888

    
889
    protected Value value;
890
    protected Config config;
891

    
892
    public ExpressionBuilderBase() {
893
        this.config = new ConfigBase();
894
    }
895

    
896
    @Override
897
    public ExpressionBuilder createExpressionBuilder() {
898
        return new ExpressionBuilderBase();
899
    }
900

    
901
    @Override
902
    public Config getConfig() {
903
        return this.config;
904
    }
905

    
906
    @Override
907
    public Value getValue() {
908
        return this.value;
909
    }
910

    
911
    @Override
912
    public ExpressionBuilder setValue(Value value) {
913
        this.value = value;
914
        return this;
915
    }
916

    
917
    @Override
918
    public String toString() {
919
        return this.value.toString();
920
    }
921

    
922
    @Override
923
    public void accept(Visitor visitor, VisitorFilter filter) {
924
        if( this.value == null) {
925
            return;
926
        }
927
        this.value.accept(visitor, filter);
928
    }
929

    
930
    @Override
931
    public boolean has_spatial_functions() {
932
        return this.config.getBoolean(Config.has_spatial_functions);
933
    }
934

    
935
    @Override
936
    public GeometrySupportType geometry_support_type() {
937
        return (GeometrySupportType) this.config.get(Config.geometry_type_support);
938
    }
939

    
940
    @Override
941
    public String string(String s) {
942
        String quote = this.config.getString(Config.quote_for_strings);
943
//        No se porque no esta disponible wrapIfMissing
944
//        return StringUtils.wrapIfMissing(s,quote);
945
        if (s.startsWith(quote)) {
946
            return s;
947
        }
948
        return quote + s + quote;
949
    }
950

    
951
    @Override
952
    public String identifier(String id) {
953
        String quote = this.config.getString(Config.quote_for_identifiers);
954
//        No se porque no esta disponible wrapIfMissing
955
//        return StringUtils.wrapIfMissing(id,quote);
956
        if (id.startsWith(quote)) {
957
            return id;
958
        }
959
        return quote + id + quote;
960
    }
961

    
962
    @Override
963
    public String bytearray(byte[] data) {
964
        return bytearray_0x(data);
965
    }
966
    
967
    protected String bytearray_hex(byte[] data) {
968
        StringBuilder builder = new StringBuilder();
969
        for (byte abyte : data) {
970
            int v = abyte & 0xff;
971
            builder.append(String.format("%02x", v));
972
        }
973
        return builder.toString();
974
    }
975

    
976
    protected String bytearray_0x(byte[] data) {
977
        return "0x" + bytearray_hex(data);
978
    }
979

    
980
    protected String bytearray_x(byte[] data) {
981
        return "x'" + bytearray_hex(data) + "'";
982
    }
983
    
984
    @Override
985
    public Object getSRSId(IProjection projection) {
986
        String abrev = projection.getAbrev();
987
        return abrev.split(":")[1].trim();
988
    }
989

    
990
    @Override
991
    public Constant srs(IProjection projection) {
992
        return constant(getSRSId(projection));
993
    }
994

    
995
    @Override
996
    public Variable variable(String name) {
997
        return new VariableBase(name);
998
    }
999

    
1000
    @Override
1001
    public Variable column(String name) {
1002
        return new VariableBase(name);
1003
    }
1004
    
1005
    @Override
1006
    public Variable column(FeatureAttributeDescriptor fad) {
1007
        ColumnDescriptorBase descriptor;
1008
        if( fad.getType()==org.gvsig.fmap.geom.DataTypes.GEOMETRY ) {
1009
            descriptor = new ColumnDescriptorBase(
1010
                    fad.getName(),
1011
                    fad.getGeomType().getType(),
1012
                    fad.getGeomType().getSubType(),
1013
                    fad.getSRS(),
1014
                    fad.isIndexed(),
1015
                    fad.allowNull()
1016
            );
1017
        } else {
1018
            descriptor = new ColumnDescriptorBase(
1019
                    fad.getName(),
1020
                    fad.getType(),
1021
                    fad.getSize(),
1022
                    fad.getPrecision(),
1023
                    fad.isPrimaryKey(),
1024
                    fad.isIndexed(),
1025
                    fad.allowNull(),
1026
                    fad.isAutomatic(),
1027
                    fad.getDefaultValue()
1028
            );
1029
        }
1030
        FeatureStore store = fad.getStore();
1031
        if( store!=null ) {
1032
            descriptor.setStoreParameters(store.getParameters());
1033
        }
1034
        return new VariableBase(descriptor);
1035
    }
1036
    
1037
    @Override
1038
    public Parameter parameter(String name) {
1039
        Parameters parameters = this.getParameters();
1040
        Parameter parameter = parameters.get(name);
1041
        if( parameter != null ) {
1042
            return parameter;
1043
        }
1044
        parameter = this.parameter();
1045
        parameter.name(name);
1046
        return parameter;
1047
    }
1048
    
1049
    @Override
1050
    public Parameter parameter() {
1051
        return new ParameterBase();
1052
    }
1053
    
1054
    @Override
1055
    public Constant constant(Object value) {
1056
        return new ConstantBase(value);
1057
    }
1058

    
1059
    @Override
1060
    public Group group(Value value) {
1061
        return new GroupBase(value);
1062
    }
1063

    
1064
    @Override
1065
    public GeometryValue geometry(Geometry geom, IProjection projection) {
1066
        return new GeometryValueBase(geom, projection);
1067
    }
1068

    
1069
    @Override
1070
    public GeometryValue envelope(Envelope envelope, IProjection projection) {
1071
        return new GeometryValueBase(envelope.getGeometry(), projection);
1072
    }
1073

    
1074
    @Override
1075
    public Custom custom(Object value) {
1076
        return new CustomBase(value);
1077
    }
1078

    
1079
    public Function function(String name, String format, Value... values) {
1080
        FunctionBase func = new FunctionBase(name, format);
1081
        for (Value value : values) {
1082
            func.parameter(value);
1083
        }
1084
        return func;
1085
    }
1086

    
1087
    public BinaryOperator binaryOperator(String name, String format, Value leftOperand, Value rightOperand) {
1088
        BinaryOperator operator = new BinaryOperatorBase(name, format);
1089
        operator.setLeft(leftOperand);
1090
        operator.setRight(rightOperand);
1091
        return operator;
1092
    }
1093

    
1094
    @Override
1095
    public List<Variable> getVariables() {
1096
        final Set<Variable> vars = new HashSet<>();
1097
        this.accept(new Visitor() {
1098
            @Override
1099
            public void visit(Visitable value) {
1100
                vars.add((Variable) value);
1101
            }
1102
        }, new ClassVisitorFilter(Variable.class));
1103
        List<Variable> lvars = new ArrayList<>(vars);
1104
        Collections.sort(lvars);
1105
        return lvars;
1106
    }
1107

    
1108
    private static class ParametersBase extends ArrayList<Parameter> implements Parameters {
1109

    
1110
        private static final long serialVersionUID = -2188534574151780470L;
1111

    
1112
        public ParametersBase() {
1113
            super();
1114
        }
1115

    
1116
        public ParametersBase(Collection parameters) {
1117
            super(parameters);
1118
        }
1119

    
1120
        @Override
1121
        public Parameter get(String name) {
1122
            if( name == null ) {
1123
                return null;
1124
            }
1125
            for (Parameter param : this) {
1126
                if( param.is_variable() || param.is_geometry_variable() ) {
1127
                    if( name.equalsIgnoreCase(param.getName()) ) {
1128
                        return param;
1129
                    }
1130
                }
1131
            }
1132
            return null;
1133
        }
1134

    
1135
        
1136
        @Override
1137
        public String toString() {
1138
            boolean first = true;
1139
            StringBuilder builder = new StringBuilder();
1140
            builder.append("{ ");
1141
            for (Parameter param : this) {
1142
                if (!first) {
1143
                    builder.append(", ");
1144
                } else {
1145
                    first = false;
1146
                }
1147
                String s;
1148
                Object value = param.getValue();
1149
                if (value == null) {
1150
                    s = "null";
1151
                } else if (value instanceof String) {
1152
                    s = "'" + (String) value + "'";
1153
                } else {
1154
                    s = value.toString();
1155
                }
1156
                switch (param.getType()) {
1157
                    case Constant:
1158
                        builder.append(s);
1159
                        break;
1160
                    case Geometry:
1161
                        builder.append("(Geometry)");
1162
                    case Variable:
1163
                    default:
1164
                        builder.append(param.getName());
1165
                        builder.append(": ");
1166
                        builder.append(s);
1167
                }
1168
            }
1169
            builder.append(" }");
1170
            return builder.toString();
1171
        }
1172
    }
1173

    
1174
    @Override
1175
    public Parameters getParameters() {
1176
        final Parameters params = new ParametersBase();
1177
        this.accept(new Visitor() {
1178
            @Override
1179
            public void visit(Visitable value) {
1180
                params.add((Parameter) value);
1181
            }
1182
        }, new ClassVisitorFilter(Parameter.class));
1183
        return params;
1184
    }
1185

    
1186
    @Override
1187
    public Function getAsGeometry(Value value) {
1188
        return function("ST_AsBinary", config.getString(Config.ST_AsBinary), value);
1189
    }
1190

    
1191
    @Override
1192
    public ExpressionBuilder set(Value value) {
1193
        this.value = value;
1194
        return this;
1195
    }
1196

    
1197
    @Override
1198
    public ExpressionBuilder and(Value value) {
1199
        if (this.value == null) {
1200
            return this.set(value);
1201
        }
1202
        BinaryOperator operator = binaryOperator("AND", config.getString(Config.operator_AND), this.value, value);
1203
        this.value = operator;
1204
        return this;
1205
    }
1206

    
1207
    @Override
1208
    public ExpressionBuilder or(Value value) {
1209
        if (this.value == null) {
1210
            return this.set(value);
1211
        }
1212
        BinaryOperator operator = binaryOperator("OR", config.getString(Config.operator_OR), this.value, value);
1213
        this.value = operator;
1214
        return this;
1215
    }
1216

    
1217
    @Override
1218
    public Function Find_SRID(Value schema, Value table, Value column) {
1219
        return function("Find_SRID", config.getString(Config.Find_SRID), schema, table, column);
1220
    }
1221

    
1222
    @Override
1223
    public Function ST_Intersects(Value geom1, Value geom2) {
1224
        return function("ST_Intersects", config.getString(Config.ST_Intersects), geom1, geom2);
1225
    }
1226

    
1227
    @Override
1228
    public Function ST_SRID(Value geom) {
1229
        return function("ST_SRID", config.getString(Config.ST_SRID), geom);
1230
    }
1231

    
1232
    @Override
1233
    public Function ST_Envelope(Value geom) {
1234
        return function("ST_Envelope", config.getString(Config.ST_Envelope), geom);
1235
    }
1236

    
1237
    @Override
1238
    public Function ST_AsText(Value geom) {
1239
        return function("ST_AsText", config.getString(Config.ST_AsText), geom);
1240
    }
1241

    
1242
    @Override
1243
    public Function ST_AsBinary(Value geom) {
1244
        return function("ST_AsBinary", config.getString(Config.ST_AsBinary), geom);
1245
    }
1246

    
1247
    @Override
1248
    public Function ST_AsEWKB(Value geom) {
1249
        return function("ST_AsEWKB", config.getString(Config.ST_AsEWKB), geom);
1250
    }
1251

    
1252
    @Override
1253
    public Function ST_GeomFromText(Value geom, Value crs) {
1254
        return function("ST_GeomFromText", config.getString(Config.ST_GeomFromText), geom, crs);
1255
    }
1256

    
1257
    @Override
1258
    public Function ST_GeomFromWKB(Value geom, Value crs) {
1259
        return function("ST_GeomFromWKB", config.getString(Config.ST_GeomFromWKB), geom, crs);
1260
    }
1261

    
1262
    @Override
1263
    public Function ST_GeomFromEWKB(Value geom, Value crs) {
1264
        return function("ST_GeomFromEWKB", config.getString(Config.ST_GeomFromEWKB), geom, crs);
1265
    }
1266

    
1267
    @Override
1268
    public Function ST_Simplify(Value geom, Value tolerance) {
1269
        return function("ST_Simplify", config.getString(Config.ST_Simplify), tolerance);
1270
    }
1271

    
1272
    @Override
1273
    public Function ST_Disjoint(Value geom1, Value geom2) {
1274
        return function("ST_Disjoint", config.getString(Config.ST_Disjoint), geom1, geom2);
1275
    }
1276

    
1277
    @Override
1278
    public Function ST_Contains(Value geom1, Value geom2) {
1279
        return function("ST_Contains", config.getString(Config.ST_Contains), geom1, geom2);
1280
    }
1281

    
1282
    @Override
1283
    public Function ST_Equals(Value geom1, Value geom2) {
1284
        return function("ST_Equals", config.getString(Config.ST_Equals), geom1, geom2);
1285
    }
1286

    
1287
    @Override
1288
    public Function ST_Crosses(Value geom1, Value geom2) {
1289
        return function("ST_Crosses", config.getString(Config.ST_Crosses), geom1, geom2);
1290
    }
1291

    
1292
    @Override
1293
    public Function ST_IsClosed(Value geom) {
1294
        return function("ST_IsClosed", config.getString(Config.ST_IsClosed), geom);
1295
    }
1296

    
1297
    @Override
1298
    public Function ST_Overlaps(Value geom1, Value geom2) {
1299
        return function("ST_Overlaps", config.getString(Config.ST_Overlaps), geom1, geom2);
1300
    }
1301

    
1302
    @Override
1303
    public Function ST_Touches(Value geom1, Value geom2) {
1304
        return function("ST_Touches", config.getString(Config.ST_Touches), geom1, geom2);
1305
    }
1306

    
1307
    @Override
1308
    public Function ST_Within(Value geom1, Value geom2) {
1309
        return function("ST_Within", config.getString(Config.ST_Within), geom1, geom2);
1310
    }
1311

    
1312
    @Override
1313
    public Function isNull(Value value) {
1314
        return function("IS NULL", config.getString(Config.isNull), value);
1315
    }
1316

    
1317
    @Override
1318
    public Function notIsNull(Value value) {
1319
        return function("NOT IS NULL", config.getString(Config.notIsNull), value);
1320
    }
1321

    
1322
    @Override
1323
    public Function not(Value value) {
1324
        return function("NOT", config.getString(Config.operator_not), value);
1325
    }
1326

    
1327
    @Override
1328
    public Function lcase(Value s) {
1329
        return function("LCASE", config.getString(Config.lcase), s);
1330
    }
1331

    
1332
    @Override
1333
    public Function ucase(Value s) {
1334
        return function("UCASE", config.getString(Config.ucase), s);
1335
    }
1336

    
1337
    @Override
1338
    public BinaryOperator and(Value leftOperand, Value rightOperand) {
1339
        return binaryOperator("AND", config.getString(Config.operator_AND), leftOperand, rightOperand);
1340
    }
1341

    
1342
    @Override
1343
    public BinaryOperator or(Value leftOperand, Value rightOperand) {
1344
        return binaryOperator("OR", config.getString(Config.operator_OR), leftOperand, rightOperand);
1345
    }
1346

    
1347
    @Override
1348
    public BinaryOperator eq(Value leftOperand, Value rightOperand) {
1349
        return binaryOperator("=", config.getString(Config.operator_EQ), leftOperand, rightOperand);
1350
    }
1351

    
1352
    @Override
1353
    public BinaryOperator ne(Value leftOperand, Value rightOperand) {
1354
        return binaryOperator("<>", config.getString(Config.operator_NE), leftOperand, rightOperand);
1355
    }
1356

    
1357
    @Override
1358
    public BinaryOperator gt(Value op1, Value op2) {
1359
        return binaryOperator(">", config.getString(Config.operator_GT), op1, op2);
1360
    }
1361

    
1362
    @Override
1363
    public BinaryOperator ge(Value op1, Value op2) {
1364
        return binaryOperator(">=", config.getString(Config.operator_GE), op1, op2);
1365
    }
1366

    
1367
    @Override
1368
    public BinaryOperator lt(Value op1, Value op2) {
1369
        return binaryOperator("<", config.getString(Config.operator_LT), op1, op2);
1370
    }
1371

    
1372
    @Override
1373
    public BinaryOperator le(Value op1, Value op2) {
1374
        return binaryOperator("<=", config.getString(Config.operator_LE), op1, op2);
1375
    }
1376

    
1377
    @Override
1378
    public BinaryOperator like(Value op1, Value op2) {
1379
        return binaryOperator("LIKE", config.getString(Config.operator_LIKE), op1, op2);
1380
    }
1381

    
1382
    @Override
1383
    public BinaryOperator ilike(Value op1, Value op2) {
1384
        return binaryOperator("ILIKE", config.getString(Config.operator_ILIKE), op1, op2);
1385
    }
1386

    
1387
    @Override
1388
    public BinaryOperator add(Value op1, Value op2) {
1389
        return binaryOperator("ADD", config.getString(Config.operator_add), op1, op2);
1390
    }
1391

    
1392
    @Override
1393
    public BinaryOperator subst(Value op1, Value op2) {
1394
        return binaryOperator("SUBST", config.getString(Config.operator_subst), op1, op2);
1395
    }
1396

    
1397
    @Override
1398
    public BinaryOperator mult(Value op1, Value op2) {
1399
        return binaryOperator("MULT", config.getString(Config.operator_mult), op1, op2);
1400
    }
1401

    
1402
    @Override
1403
    public BinaryOperator div(Value op1, Value op2) {
1404
        return binaryOperator("DIV", config.getString(Config.operator_div), op1, op2);
1405
    }
1406

    
1407
    @Override
1408
    public BinaryOperator concat(Value op1, Value op2) {
1409
        return binaryOperator("CONCAT", config.getString(Config.operator_concat), op1, op2);
1410
    }
1411

    
1412
}