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

History | View | Annotate | Download (14 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 44644 jjdelcerro
//import org.gvsig.fmap.geom.Geometry;
27
//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 44644 jjdelcerro
        if( StringUtils.equalsIgnoreCase(System.getProperty("ExpressionEvaluatorReloadFunctionResources"), "true")) {
94
            load_from_resource();
95
        }
96 43512 jjdelcerro
        return description;
97
    }
98
99
    @Override
100
    public String[] descriptionArgs() {
101
        return descriptionArgs;
102
    }
103
104
    @Override
105
    public void addAlias(String name) {
106 44006 jjdelcerro
        if( StringUtils.isBlank(name) ) {
107
            return;
108
        }
109 43512 jjdelcerro
        if( this.alias == null ) {
110
            this.alias = new ArrayList<>();
111
        }
112 44006 jjdelcerro
        if( this.alias.contains(name) ) {
113
            return;
114
        }
115 43512 jjdelcerro
        this.alias.add(name);
116
    }
117
118
    @Override
119 44139 jjdelcerro
    public List<String> aliases() {
120 43512 jjdelcerro
        return this.alias;
121
    }
122
123 43521 jjdelcerro
    @Override
124
    public String template() {
125
        return this.template;
126
    }
127
128
    @Override
129
    public boolean isOperator() {
130
        return false;
131
    }
132 43939 jjdelcerro
133
    @Override
134 44738 jjdelcerro
    public boolean isHidden() {
135
      return false;
136
    }
137
138
    @Override
139 43939 jjdelcerro
    public boolean useArgumentsInsteadObjects() {
140
        return false;
141
    }
142
143
    @Override
144 43989 jjdelcerro
    public boolean isSQLCompatible() {
145
        return sqlCompatible;
146
    }
147 44009 jjdelcerro
148
    @Override
149
    public boolean allowConstantFolding() {
150
        return false;
151
    }
152 44738 jjdelcerro
153
    @Override
154 44139 jjdelcerro
    public Object call(Interpreter interpreter, Codes args) throws Exception {
155 43939 jjdelcerro
        return null;
156
    }
157 43521 jjdelcerro
158 43512 jjdelcerro
    protected int getInt(Object args[], int n) {
159
        if( args.length < n  ) {
160 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
161 43512 jjdelcerro
        }
162 44098 jjdelcerro
        Object value = args[n];
163
        if( value == null ) {
164
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
165 43512 jjdelcerro
        }
166 44098 jjdelcerro
        if( !(value instanceof Number) ) {
167
            String type = value.getClass().getCanonicalName();
168
            throw new IllegalArgumentException(
169
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
170
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
171
            );
172
        }
173
        return ((Number)value).intValue();
174 43512 jjdelcerro
    }
175
176
    protected long getLong(Object args[], int n) {
177
        if( args.length < n  ) {
178 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
179 43512 jjdelcerro
        }
180 44098 jjdelcerro
        Object value = args[n];
181
        if( value == null ) {
182
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
183 43512 jjdelcerro
        }
184 44098 jjdelcerro
        if( !(value instanceof Number) ) {
185
            String type = value.getClass().getCanonicalName();
186
            throw new IllegalArgumentException(
187
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
188
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
189
            );
190
        }
191
        return ((Number)value).longValue();
192 43512 jjdelcerro
    }
193
194
    protected double getDouble(Object args[], int n) {
195
        if( args.length < n  ) {
196 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
197 43512 jjdelcerro
        }
198 44098 jjdelcerro
        Object value = args[n];
199
        if( value == null ) {
200
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
201 43512 jjdelcerro
        }
202 44098 jjdelcerro
        if( !(value instanceof Number) ) {
203
            String type = value.getClass().getCanonicalName();
204
            throw new IllegalArgumentException(
205
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
206
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
207
            );
208
        }
209
        return ((Number)value).doubleValue();
210 43512 jjdelcerro
    }
211
212
    protected String getStr(Object args[], int n) {
213
        if( args.length < n  ) {
214 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
215 43512 jjdelcerro
        }
216
        return Objects.toString(args[n], "");
217
    }
218
219 44389 jjdelcerro
    protected File getFile(Object args[], int n) {
220
        if( args.length < n  ) {
221
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
222
        }
223
        Object arg = args[n];
224
        if( arg == null ) {
225
            return null;
226
        }
227
        if( arg instanceof File ) {
228
            return (File)arg;
229
        }
230
        if( arg instanceof URL ) {
231
            try {
232
                return new File(((URL)arg).toURI());
233
            } catch (URISyntaxException ex) {
234
                return null;
235
            }
236
        }
237
        if( arg instanceof URI ) {
238
            return new File(((URI)arg));
239
        }
240
        String s = Objects.toString(arg, null);
241
        if( s == null ) {
242
            return null;
243
        }
244
        File f = new File(s);
245
        return f;
246
    }
247
248 43939 jjdelcerro
    protected Object getObject(Object args[], int n) {
249
        if( args.length < n  ) {
250 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
251 43939 jjdelcerro
        }
252
        return args[n];
253
    }
254
255 44139 jjdelcerro
    protected Object getObject(Interpreter interpreter, Codes args, int n) {
256
        if( args.size() < n  ) {
257
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.size(), n));
258 43939 jjdelcerro
        }
259
        Code arg = args.get(n);
260 44592 jjdelcerro
        if( arg==null ) {
261
            return null;
262
        }
263 43939 jjdelcerro
        Object value = interpreter.run(arg);
264
        return value;
265
    }
266
267 44266 jjdelcerro
    protected Date getDate(Object[] args, int n) {
268
        if( args.length < n  ) {
269
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
270
        }
271
        Object value = args[n];
272
        if( value == null ) {
273
            return null;
274
        }
275
        if( !(value instanceof Date) ) {
276
            String type = value.getClass().getCanonicalName();
277
            throw new IllegalArgumentException(
278
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
279
                    I18N.Expected_XexpectedX_and_found_XfoundX("Date",type)
280
            );
281
        }
282
        return (Date)value;
283
    }
284
285
    protected LocalDateTime getLocalDateTime(Object[] args, int n) {
286
        if( args.length < n  ) {
287
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
288
        }
289
        Object value = args[n];
290
        if( value == null ) {
291
            return null;
292
        }
293
        if( value instanceof Date ) {
294
            Date date = ((Date)value);
295
            return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
296
        }
297
        if( value instanceof LocalDateTime ) {
298
            return (LocalDateTime) value;
299
        }
300
        if( value instanceof TemporalAccessor ) {
301
            return LocalDateTime.from(((TemporalAccessor)value));
302
        }
303
        String type = value.getClass().getCanonicalName();
304
        throw new IllegalArgumentException(
305
                I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
306
                I18N.Expected_XexpectedX_and_found_XfoundX("Temporal/Date",type)
307
        );
308
    }
309
310 43939 jjdelcerro
    protected boolean getBoolean(Object args[], int n, Double accuracy) {
311
        if( args.length < n  ) {
312 44098 jjdelcerro
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
313 43939 jjdelcerro
        }
314
        Object value = args[n];
315
        return toBoolean(value, accuracy);
316
    }
317
318 44139 jjdelcerro
    protected boolean getBoolean(Interpreter interpreter, Codes args, int n) {
319 43939 jjdelcerro
        Object value = getObject(interpreter, args, n);
320
        return toBoolean(value, interpreter.getAccuracy());
321
    }
322
323
    protected boolean toBoolean(Object value, Double accuracy) {
324
        if( value == null ) {
325
            return false;
326
        }
327
        if( value instanceof Boolean ) {
328
            return (Boolean)value;
329
        }
330
        if( value instanceof Number ) {
331
            return MathUtils.compareTo(
332
                ((Number) value).doubleValue(),
333
                0,
334
                accuracy==null? MathUtils.EPSILON:accuracy
335
            ) == 0;
336
        }
337
        return BooleanUtils.toBoolean(value.toString());
338
    }
339 44006 jjdelcerro
340
    private void load_from_resource() {
341
        String lang = Locale.getDefault().getLanguage();
342
        URL url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/"+lang+"/"+this.name()+".json");
343
        if( url == null ) {
344
            url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/en/"+this.name()+".json");
345
            if( url == null ) {
346
                return;
347
            }
348
        }
349
        InputStream is = null;
350
        JSONObject json;
351
        try {
352
            is = url.openStream();
353
            List<String> lines = IOUtils.readLines(is);
354
            json = new JSONObject(StringUtils.join(lines,  "\n"));
355
        } catch (Exception ex) {
356
            return;
357
        } finally {
358
            IOUtils.closeQuietly(is);
359
        }
360
361
        if( json.has("group") ) {
362
            this.group = json.getString("group");
363
        }
364
        if( json.has("description") ) {
365
            Object x = json.get("description");
366
            if( x instanceof String ) {
367
                this.description = (String) x;
368
            } else if( x instanceof JSONArray ) {
369
                StringBuilder builder = new StringBuilder();
370
                for (int i = 0; i < ((JSONArray)x).length(); i++) {
371
                    if( i>0 ) {
372
                        builder.append(" ");
373
                    }
374
                    builder.append(((JSONArray)x).getString(i));
375
                }
376
                this.description = builder.toString();
377
            } else {
378 44750 jjdelcerro
                this.description = Objects.toString(x, null);
379 44006 jjdelcerro
            }
380
            this.description = StringUtils.replace(
381
                    this.description,
382
                    "@@@",
383
                    url.toString()
384
            );
385
        }
386
        if( json.has("template") ) {
387
            this.template = json.getString("template");
388
        }
389
        if( json.has("returnType") ) {
390
            this.returnType = json.getString("returnType");
391
        }
392
        if( json.has("sqlCompatible") ) {
393
            this.sqlCompatible = json.getBoolean("sqlCompatible");
394
        }
395
        if( json.has("args") ) {
396
            JSONArray x = json.getJSONArray("args");
397
            String[] args = new String[x.length()];
398
            for (int i = 0; i < x.length(); i++) {
399
                args[i] = x.getString(i);
400
            }
401
            this.descriptionArgs = args;
402
        }
403
        if( json.has("alias") ) {
404
            JSONArray x = json.getJSONArray("alias");
405
            for (int i = 0; i < x.length(); i++) {
406
                this.addAlias(x.getString(i));
407
            }
408
        }
409
    }
410 43512 jjdelcerro
}