Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.api / src / main / java / org / gvsig / expressionevaluator / spi / AbstractFunction.java @ 44389

History | View | Annotate | Download (15.5 KB)

1 43512 jjdelcerro
package org.gvsig.expressionevaluator.spi;
2
3 44389 jjdelcerro
import java.io.File;
4 44006 jjdelcerro
import java.io.InputStream;
5 44389 jjdelcerro
import java.net.URI;
6
import java.net.URISyntaxException;
7 44006 jjdelcerro
import java.net.URL;
8 44266 jjdelcerro
import java.time.LocalDateTime;
9
import java.time.ZoneId;
10
import java.time.temporal.TemporalAccessor;
11 43512 jjdelcerro
import java.util.ArrayList;
12 44266 jjdelcerro
import java.util.Date;
13 43512 jjdelcerro
import java.util.List;
14 44006 jjdelcerro
import java.util.Locale;
15 43512 jjdelcerro
import java.util.Objects;
16 44006 jjdelcerro
import org.apache.commons.io.IOUtils;
17 43939 jjdelcerro
import org.apache.commons.lang3.BooleanUtils;
18 43512 jjdelcerro
import org.apache.commons.lang3.Range;
19 44006 jjdelcerro
import org.apache.commons.lang3.StringUtils;
20 43939 jjdelcerro
import org.apache.commons.math.util.MathUtils;
21
import org.gvsig.expressionevaluator.Code;
22 44139 jjdelcerro
import org.gvsig.expressionevaluator.Codes;
23 43512 jjdelcerro
import org.gvsig.expressionevaluator.Function;
24 44098 jjdelcerro
import org.gvsig.expressionevaluator.I18N;
25 43939 jjdelcerro
import org.gvsig.expressionevaluator.Interpreter;
26 43512 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
27 43520 jjdelcerro
import org.gvsig.fmap.geom.primitive.Point;
28 44006 jjdelcerro
import org.json.JSONArray;
29
import org.json.JSONObject;
30 43512 jjdelcerro
31 44006 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
32 43512 jjdelcerro
public abstract class AbstractFunction implements Function {
33 43521 jjdelcerro
34 43512 jjdelcerro
    private final String name;
35 44006 jjdelcerro
    private String group;
36
    private Range argc;
37
    private String description;
38
    private String[] descriptionArgs;
39 43512 jjdelcerro
    private List<String> alias;
40 43521 jjdelcerro
    private String template;
41 43939 jjdelcerro
    private String returnType;
42 43989 jjdelcerro
    private boolean sqlCompatible;
43 43512 jjdelcerro
44 43989 jjdelcerro
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType, boolean sqlCompatible) {
45 43512 jjdelcerro
        this.name = name;
46
        this.group = group;
47
        this.argc = argc;
48
        this.description = description;
49 43521 jjdelcerro
        this.template = template;
50 43512 jjdelcerro
        this.descriptionArgs = descriptionArgs;
51 43939 jjdelcerro
        this.returnType = returnType;
52 43989 jjdelcerro
        this.sqlCompatible = sqlCompatible;
53 44006 jjdelcerro
        load_from_resource();
54 43512 jjdelcerro
    }
55 43989 jjdelcerro
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType) {
56
        this(group, name, argc, description, template, descriptionArgs, returnType, false);
57
    }
58
59 43939 jjdelcerro
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs) {
60
        this(group, name, argc, description, template, null, null);
61 43521 jjdelcerro
    }
62
63 43939 jjdelcerro
    protected AbstractFunction(String group, String name, Range argc, String description, String template) {
64
        this(group, name, argc, description, template, null, null);
65
    }
66
67 43512 jjdelcerro
    protected AbstractFunction(String group, String name, Range argc) {
68 43939 jjdelcerro
        this(group, name, argc, null, null, null, null);
69 43512 jjdelcerro
    }
70
71
    @Override
72
    public String name() {
73
        return this.name;
74
    }
75
76
    @Override
77 43939 jjdelcerro
    public String returnType() {
78
        return this.returnType;
79
    }
80
81
    @Override
82 43512 jjdelcerro
    public String group() {
83
        return this.group;
84
    }
85
86
    @Override
87
    public Range argc() {
88
        return argc;
89
    }
90
91
    @Override
92
    public String description() {
93
        return description;
94
    }
95
96
    @Override
97
    public String[] descriptionArgs() {
98
        return descriptionArgs;
99
    }
100
101
    @Override
102
    public void addAlias(String name) {
103 44006 jjdelcerro
        if( StringUtils.isBlank(name) ) {
104
            return;
105
        }
106 43512 jjdelcerro
        if( this.alias == null ) {
107
            this.alias = new ArrayList<>();
108
        }
109 44006 jjdelcerro
        if( this.alias.contains(name) ) {
110
            return;
111
        }
112 43512 jjdelcerro
        this.alias.add(name);
113
    }
114
115
    @Override
116 44139 jjdelcerro
    public List<String> aliases() {
117 43512 jjdelcerro
        return this.alias;
118
    }
119
120 43521 jjdelcerro
    @Override
121
    public String template() {
122
        return this.template;
123
    }
124
125
    @Override
126
    public boolean isOperator() {
127
        return false;
128
    }
129 43939 jjdelcerro
130
    @Override
131
    public boolean useArgumentsInsteadObjects() {
132
        return false;
133
    }
134
135
    @Override
136 43989 jjdelcerro
    public boolean isSQLCompatible() {
137
        return sqlCompatible;
138
    }
139 44009 jjdelcerro
140
    @Override
141
    public boolean allowConstantFolding() {
142
        return false;
143
    }
144 43989 jjdelcerro
145
    @Override
146 44139 jjdelcerro
    public Object call(Interpreter interpreter, Codes args) throws Exception {
147 43939 jjdelcerro
        return null;
148
    }
149 43521 jjdelcerro
150 43512 jjdelcerro
    protected int getInt(Object args[], int n) {
151
        if( args.length < n  ) {
152 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
153 43512 jjdelcerro
        }
154 44098 jjdelcerro
        Object value = args[n];
155
        if( value == null ) {
156
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
157 43512 jjdelcerro
        }
158 44098 jjdelcerro
        if( !(value instanceof Number) ) {
159
            String type = value.getClass().getCanonicalName();
160
            throw new IllegalArgumentException(
161
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
162
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
163
            );
164
        }
165
        return ((Number)value).intValue();
166 43512 jjdelcerro
    }
167
168
    protected long getLong(Object args[], int n) {
169
        if( args.length < n  ) {
170 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
171 43512 jjdelcerro
        }
172 44098 jjdelcerro
        Object value = args[n];
173
        if( value == null ) {
174
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
175 43512 jjdelcerro
        }
176 44098 jjdelcerro
        if( !(value instanceof Number) ) {
177
            String type = value.getClass().getCanonicalName();
178
            throw new IllegalArgumentException(
179
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
180
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
181
            );
182
        }
183
        return ((Number)value).longValue();
184 43512 jjdelcerro
    }
185
186
    protected double getDouble(Object args[], int n) {
187
        if( args.length < n  ) {
188 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
189 43512 jjdelcerro
        }
190 44098 jjdelcerro
        Object value = args[n];
191
        if( value == null ) {
192
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
193 43512 jjdelcerro
        }
194 44098 jjdelcerro
        if( !(value instanceof Number) ) {
195
            String type = value.getClass().getCanonicalName();
196
            throw new IllegalArgumentException(
197
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
198
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
199
            );
200
        }
201
        return ((Number)value).doubleValue();
202 43512 jjdelcerro
    }
203
204
    protected String getStr(Object args[], int n) {
205
        if( args.length < n  ) {
206 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
207 43512 jjdelcerro
        }
208
        return Objects.toString(args[n], "");
209
    }
210
211 44389 jjdelcerro
    protected File getFile(Object args[], int n) {
212
        if( args.length < n  ) {
213
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
214
        }
215
        Object arg = args[n];
216
        if( arg == null ) {
217
            return null;
218
        }
219
        if( arg instanceof File ) {
220
            return (File)arg;
221
        }
222
        if( arg instanceof URL ) {
223
            try {
224
                return new File(((URL)arg).toURI());
225
            } catch (URISyntaxException ex) {
226
                return null;
227
            }
228
        }
229
        if( arg instanceof URI ) {
230
            return new File(((URI)arg));
231
        }
232
        String s = Objects.toString(arg, null);
233
        if( s == null ) {
234
            return null;
235
        }
236
        File f = new File(s);
237
        return f;
238
    }
239
240 43939 jjdelcerro
    protected Object getObject(Object args[], int n) {
241
        if( args.length < n  ) {
242 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
243 43939 jjdelcerro
        }
244
        return args[n];
245
    }
246
247 44139 jjdelcerro
    protected Object getObject(Interpreter interpreter, Codes args, int n) {
248
        if( args.size() < n  ) {
249
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.size(), n));
250 43939 jjdelcerro
        }
251
        Code arg = args.get(n);
252
        Object value = interpreter.run(arg);
253
        return value;
254
    }
255
256 43512 jjdelcerro
    protected Geometry getGeom(Object[] args, int n) {
257 44098 jjdelcerro
        return this.getGeom(args, n, false);
258
    }
259
260
    protected Geometry getGeom(Object[] args, int n, boolean allowNull) {
261 43512 jjdelcerro
        if( args.length < n  ) {
262 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
263 43512 jjdelcerro
        }
264 44098 jjdelcerro
        Object value = args[n];
265
        if( value == null ) {
266
            if( allowNull ) {
267
                return null;
268
            }
269
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
270 43512 jjdelcerro
        }
271 44098 jjdelcerro
        if( !(value instanceof Geometry) ) {
272
            String type = value.getClass().getCanonicalName();
273
            throw new IllegalArgumentException(
274
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
275
                    I18N.Expected_XexpectedX_and_found_XfoundX("Geometry",type)
276
            );
277
        }
278
        return (Geometry)value;
279 43512 jjdelcerro
    }
280 43520 jjdelcerro
281
    protected Point getPoint(Object[] args, int n) {
282
        if( args.length < n  ) {
283 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
284 43520 jjdelcerro
        }
285 44098 jjdelcerro
        Object value = args[n];
286
        if( value == null ) {
287
            return null;
288 43520 jjdelcerro
        }
289 44098 jjdelcerro
        if( !(value instanceof Point) ) {
290
            String type = value.getClass().getCanonicalName();
291
            throw new IllegalArgumentException(
292
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
293
                    I18N.Expected_XexpectedX_and_found_XfoundX("Point",type)
294
            );
295
        }
296
        return (Point)value;
297 43520 jjdelcerro
    }
298 43939 jjdelcerro
299 44266 jjdelcerro
    protected Date getDate(Object[] args, int n) {
300
        if( args.length < n  ) {
301
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
302
        }
303
        Object value = args[n];
304
        if( value == null ) {
305
            return null;
306
        }
307
        if( !(value instanceof Date) ) {
308
            String type = value.getClass().getCanonicalName();
309
            throw new IllegalArgumentException(
310
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
311
                    I18N.Expected_XexpectedX_and_found_XfoundX("Date",type)
312
            );
313
        }
314
        return (Date)value;
315
    }
316
317
    protected LocalDateTime getLocalDateTime(Object[] args, int n) {
318
        if( args.length < n  ) {
319
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
320
        }
321
        Object value = args[n];
322
        if( value == null ) {
323
            return null;
324
        }
325
        if( value instanceof Date ) {
326
            Date date = ((Date)value);
327
            return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
328
        }
329
        if( value instanceof LocalDateTime ) {
330
            return (LocalDateTime) value;
331
        }
332
        if( value instanceof TemporalAccessor ) {
333
            return LocalDateTime.from(((TemporalAccessor)value));
334
        }
335
        String type = value.getClass().getCanonicalName();
336
        throw new IllegalArgumentException(
337
                I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
338
                I18N.Expected_XexpectedX_and_found_XfoundX("Temporal/Date",type)
339
        );
340
    }
341
342 43939 jjdelcerro
    protected boolean getBoolean(Object args[], int n, Double accuracy) {
343
        if( args.length < n  ) {
344 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
345 43939 jjdelcerro
        }
346
        Object value = args[n];
347
        return toBoolean(value, accuracy);
348
    }
349
350 44139 jjdelcerro
    protected boolean getBoolean(Interpreter interpreter, Codes args, int n) {
351 43939 jjdelcerro
        Object value = getObject(interpreter, args, n);
352
        return toBoolean(value, interpreter.getAccuracy());
353
    }
354
355
    protected boolean toBoolean(Object value, Double accuracy) {
356
        if( value == null ) {
357
            return false;
358
        }
359
        if( value instanceof Boolean ) {
360
            return (Boolean)value;
361
        }
362
        if( value instanceof Number ) {
363
            return MathUtils.compareTo(
364
                ((Number) value).doubleValue(),
365
                0,
366
                accuracy==null? MathUtils.EPSILON:accuracy
367
            ) == 0;
368
        }
369
        return BooleanUtils.toBoolean(value.toString());
370
    }
371 44006 jjdelcerro
372
    private void load_from_resource() {
373
        String lang = Locale.getDefault().getLanguage();
374
        URL url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/"+lang+"/"+this.name()+".json");
375
        if( url == null ) {
376
            url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/en/"+this.name()+".json");
377
            if( url == null ) {
378
                return;
379
            }
380
        }
381
        InputStream is = null;
382
        JSONObject json;
383
        try {
384
            is = url.openStream();
385
            List<String> lines = IOUtils.readLines(is);
386
            json = new JSONObject(StringUtils.join(lines,  "\n"));
387
        } catch (Exception ex) {
388
            return;
389
        } finally {
390
            IOUtils.closeQuietly(is);
391
        }
392
393
        if( json.has("group") ) {
394
            this.group = json.getString("group");
395
        }
396
        if( json.has("description") ) {
397
            Object x = json.get("description");
398
            if( x instanceof String ) {
399
                this.description = (String) x;
400
            } else if( x instanceof JSONArray ) {
401
                StringBuilder builder = new StringBuilder();
402
                for (int i = 0; i < ((JSONArray)x).length(); i++) {
403
                    if( i>0 ) {
404
                        builder.append(" ");
405
                    }
406
                    builder.append(((JSONArray)x).getString(i));
407
                }
408
                this.description = builder.toString();
409
            } else {
410
                this.description = x.toString();
411
            }
412
            this.description = StringUtils.replace(
413
                    this.description,
414
                    "@@@",
415
                    url.toString()
416
            );
417
        }
418
        if( json.has("template") ) {
419
            this.template = json.getString("template");
420
        }
421
        if( json.has("returnType") ) {
422
            this.returnType = json.getString("returnType");
423
        }
424
        if( json.has("sqlCompatible") ) {
425
            this.sqlCompatible = json.getBoolean("sqlCompatible");
426
        }
427
        if( json.has("args") ) {
428
            JSONArray x = json.getJSONArray("args");
429
            String[] args = new String[x.length()];
430
            for (int i = 0; i < x.length(); i++) {
431
                args[i] = x.getString(i);
432
            }
433
            this.descriptionArgs = args;
434
        }
435
        if( json.has("alias") ) {
436
            JSONArray x = json.getJSONArray("alias");
437
            for (int i = 0; i < x.length(); i++) {
438
                this.addAlias(x.getString(i));
439
            }
440
        }
441
    }
442 43512 jjdelcerro
}