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

History | View | Annotate | Download (26.9 KB)

1
package org.gvsig.expressionevaluator.spi;
2

    
3
import java.io.File;
4
import java.io.InputStream;
5
import java.net.MalformedURLException;
6
import java.net.URI;
7
import java.net.URISyntaxException;
8
import java.net.URL;
9
import java.time.LocalDateTime;
10
import java.time.ZoneId;
11
import java.time.temporal.TemporalAccessor;
12
import java.util.ArrayList;
13
import java.util.Date;
14
import java.util.List;
15
import java.util.Locale;
16
import java.util.Objects;
17
import javax.json.JsonArray;
18
import javax.json.JsonObject;
19
import javax.json.JsonStructure;
20
import org.apache.commons.io.IOUtils;
21
import org.apache.commons.lang3.BooleanUtils;
22
import org.apache.commons.lang3.Range;
23
import org.apache.commons.lang3.StringUtils;
24
import org.apache.commons.math.util.MathUtils;
25
import org.gvsig.expressionevaluator.Code;
26
import org.gvsig.expressionevaluator.Codes;
27
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
28
import org.gvsig.expressionevaluator.Formatter;
29
import org.gvsig.expressionevaluator.Function;
30
import org.gvsig.expressionevaluator.I18N;
31
import org.gvsig.expressionevaluator.Interpreter;
32
import org.gvsig.tools.ToolsLocator;
33
import org.gvsig.tools.i18n.I18nManager;
34
import org.gvsig.tools.util.GetItem;
35
import org.gvsig.tools.util.GetItem64;
36
import org.gvsig.tools.util.GetItemWithSize64;
37
import org.gvsig.tools.util.Size;
38
import org.gvsig.tools.util.Size64;
39
//import org.gvsig.fmap.geom.Geometry;
40
//import org.gvsig.fmap.geom.primitive.Point;
41
import org.json.JSONArray;
42
import org.json.JSONObject;
43

    
44
@SuppressWarnings("UseSpecificCatch")
45
public abstract class AbstractFunction implements Function {
46
 
47
    private final String name;
48
    private String group;
49
    private Range argc;
50
    private String description;
51
    private String[] descriptionArgs;
52
    private List<String> alias;
53
    private String template;
54
    private String returnType;
55
    private boolean sqlCompatible;
56

    
57
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType, boolean sqlCompatible) {
58
        this.name = name;
59
        this.group = group;
60
        this.argc = argc;
61
        this.description = description;
62
        this.template = template;
63
        this.descriptionArgs = descriptionArgs;
64
        this.returnType = returnType;
65
        this.sqlCompatible = sqlCompatible;
66
        load_from_resource();
67
    }
68
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType) {
69
        this(group, name, argc, description, template, descriptionArgs, returnType, false);
70
    }
71
    
72
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs) {
73
        this(group, name, argc, description, template, null, null);
74
    }
75

    
76
    protected AbstractFunction(String group, String name, Range argc, String description, String template) {
77
        this(group, name, argc, description, template, null, null);
78
    }
79

    
80
    protected AbstractFunction(String group, String name, Range argc) {
81
        this(group, name, argc, null, null, null, null);
82
    }
83

    
84
    @Override
85
    public String name() {
86
        return this.name;
87
    }
88

    
89
    @Override
90
    public String returnType() {
91
        return this.returnType;
92
    }
93

    
94
    @Override
95
    public String group() {
96
        return this.group;
97
    }
98

    
99
    @Override
100
    public Range argc() {
101
        return argc;
102
    }
103

    
104
    @Override
105
    public String description() {
106
        if( StringUtils.equalsIgnoreCase(System.getProperty("ExpressionEvaluatorReloadFunctionResources"), "true")) {
107
            load_from_resource();
108
        }
109
        return description;
110
    }
111

    
112
    @Override
113
    public String[] descriptionArgs() {
114
        return descriptionArgs;
115
    }
116

    
117
    @Override
118
    public String getFullDescription() {
119
        I18nManager i18n = ToolsLocator.getI18nManager();
120

    
121
        StringBuilder html = new StringBuilder();
122
        html.append("<html>\n");
123

    
124
        // Lo primero llamamos a description() para forzar la recarga de los
125
        // recursos si fuese necesaria.
126
        String functionDescription = this.description();
127

    
128
        html.append("<b>").append(i18n.getTranslation("_Function")).append("</b> ").append(this.name()).append("<br>\n<br>\n");
129
        List<String> aliases = this.aliases();
130
        if( aliases!=null && !aliases.isEmpty() ) {
131
            html.append("<b>").append(i18n.getTranslation("_Aliases")).append(":</b> ").append("<ul>\n");
132
            for (String theAlias : aliases) {
133
                html.append("<li>").append(theAlias).append("</li>\n");
134
            }
135
            html.append("</ul>\n");
136
        }
137
        html.append("<b>").append(i18n.getTranslation("_Return")).append("</b> ");
138
        html.append(StringUtils.isEmpty(this.returnType()) ? "Objec" : this.returnType());
139
        html.append("<br>\n");
140
        html.append("<b>").append(i18n.getTranslation("_Template")).append("</b> ");
141
        html.append(StringUtils.isEmpty(this.template()) ? this.name() + "()" : this.template());
142
        html.append("<br>\n");
143

    
144
        String[] args = this.descriptionArgs();
145
        if (args != null) {
146
            html.append("<b>").append(i18n.getTranslation("_Arguments")).append(":</b> ").append("<ul>\n");
147
            for (String arg : args) {
148
                html.append("<li>").append(arg).append("</li>\n");
149
            }
150
            html.append("</ul>\n");
151
            html.append("<br>\n");
152
        }
153
        if( !StringUtils.isBlank(functionDescription) ) {
154
            html.append("<b>").append(i18n.getTranslation("_Description")).append("</b><br>\n");
155
            html.append(functionDescription.replace("\n", "<br>")).append("<br>\n");
156
        }            
157

    
158
        html.append("</html>\n");
159
        return html.toString();
160
    }
161

    
162
    @Override
163
    public void addAlias(String name) {
164
        if( StringUtils.isBlank(name) ) {
165
            return;
166
        }
167
        if( this.alias == null ) {
168
            this.alias = new ArrayList<>();
169
        }
170
        if( this.alias.contains(name) ) {
171
            return;
172
        }
173
        this.alias.add(name);
174
    }
175

    
176
    @Override
177
    public List<String> aliases() {
178
        return this.alias;
179
    }
180

    
181
    @Override
182
    public String template() {
183
        return this.template;
184
    }
185

    
186
    @Override
187
    public boolean isOperator() {
188
        return false;
189
    }
190

    
191
    @Override
192
    public boolean isHidden() {
193
      return false;
194
    }
195
    
196
    @Override
197
    public boolean useArgumentsInsteadObjects() {
198
        return false;
199
    }
200

    
201
    @Override
202
    public boolean isSQLCompatible() {
203
        return sqlCompatible;
204
    }
205

    
206
    @Override
207
    public boolean allowConstantFolding() {
208
        return false;
209
    }
210

    
211
    @Override
212
    public Object call(Interpreter interpreter, Codes args) throws Exception {
213
        return null;
214
    }
215
    
216
    protected int getInt(Object args[], int n) {
217
        if( args.length < n  ) {
218
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
219
        }
220
        return getInt(args[n],n);
221
    }
222

    
223
    protected int getInt(Object value, int n) {
224
        if( value == null ) {
225
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
226
        }
227
        if( !(value instanceof Number) ) {
228
            String type = value.getClass().getCanonicalName();
229
            throw new IllegalArgumentException(
230
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
231
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
232
            );
233
        }
234
        return ((Number)value).intValue();
235
    }
236

    
237
    protected long getLong(Object args[], int n) {
238
        if( args.length < n  ) {
239
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
240
        }
241
        return getLong(args[n],n);
242
    }
243

    
244
    protected long getLong(Object value, int n) {
245
        if( value == null ) {
246
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
247
        }
248
        if( !(value instanceof Number) ) {
249
            String type = value.getClass().getCanonicalName();
250
            throw new IllegalArgumentException(
251
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
252
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
253
            );
254
        }
255
        return ((Number)value).longValue();
256
    }
257

    
258
    protected double getDouble(Object args[], int n) {
259
        if( args.length < n  ) {
260
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
261
        }
262
        return getDouble(args[n],n);
263
    }
264

    
265
    protected double getDouble(Object value, int arg) {
266
        if( value == null ) {
267
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), arg));
268
        }
269
        if( !(value instanceof Number) ) {
270
            String type = value.getClass().getCanonicalName();
271
            throw new IllegalArgumentException(
272
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), arg) + " " +
273
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
274
            );
275
        }
276
        return ((Number)value).doubleValue();
277
    }
278
    
279
    protected float getFloat(Object args[], int n) {
280
        if( args.length < n  ) {
281
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
282
        }
283
        return getFloat(args[n],n);
284
    }
285

    
286
    protected float getFloat(Object value, int arg) {
287
        if( value == null ) {
288
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), arg));
289
        }
290
        if( !(value instanceof Number) ) {
291
            String type = value.getClass().getCanonicalName();
292
            throw new IllegalArgumentException(
293
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), arg) + " " +
294
                    I18N.Expected_XexpectedX_and_found_XfoundX("Number",type)
295
            );
296
        }
297
        return ((Number)value).floatValue();
298
    }
299
    
300
    protected String getStr(Object args[], int n) {
301
        if( args.length < n  ) {
302
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
303
        }
304
        return getStr(args[n],n);
305
    }
306
    
307
    protected String getStr(Object value, int n) {
308
        return Objects.toString(value, "");
309
    }
310
    
311
    protected File getFile(Object args[], int n) {
312
        if( args.length < n  ) {
313
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
314
        }
315
        return getFile(args[n],n);
316
    }
317
    
318
    protected File getFile(Object value, int n) {
319
        if( value == null ) {
320
            return null;
321
        }
322
        if( value instanceof File ) {
323
            return (File)value;
324
        }
325
        if( value instanceof URL ) {
326
            try {
327
                return new File(((URL)value).toURI());
328
            } catch (URISyntaxException ex) {
329
                return null;
330
            }
331
        }
332
        if( value instanceof URI ) {
333
            return new File(((URI)value));
334
        }
335
        String s = Objects.toString(value, null);
336
        if( s == null ) {
337
            return null;
338
        }
339
        File f = new File(s);
340
        return f;
341
    }
342

    
343
    protected boolean isNull(Object args[], int n) {
344
        return getObject(args, n)==null;
345
    }
346
    
347
    protected Object getObject(Object args[], int n) {
348
        if( args.length < n  ) {
349
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
350
        }
351
        return args[n];
352
    }
353
    
354
    protected JsonObject getJsonObject(Object args[], int n) {
355
        if( args.length < n  ) {
356
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
357
        }
358
        return getJsonObject(args[n],n);
359
    }
360

    
361
    protected JsonObject getJsonObject(Object value, int n) {
362
        if( value == null ) {
363
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
364
        }
365
        if( !(value instanceof JSONObject) ) {
366
            try {
367
                value = JsonUtils.toJsonObject(value);
368
            } catch(Throwable th) {
369
                String type = value.getClass().getCanonicalName();
370
                throw new IllegalArgumentException(
371
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
372
                    I18N.Expected_XexpectedX_and_found_XfoundX("JsonObject",type),
373
                    th
374
                );
375
            }
376
        }
377
        return (JsonObject) value;
378
    }
379

    
380
    protected JsonArray getJsonArray(Object args[], int n) {
381
        if( args.length < n  ) {
382
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
383
        }
384
        return getJsonArray(args[n],n);
385
    }
386

    
387
    protected JsonArray getJsonArray(Object value, int n) {
388
        if( value == null ) {
389
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
390
        }
391
        if( !(value instanceof JsonArray) ) {
392
            try {
393
                value = JsonUtils.toJsonArray(value);
394
            } catch(Throwable th) {
395
                String type = value.getClass().getCanonicalName();
396
                throw new IllegalArgumentException(
397
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
398
                    I18N.Expected_XexpectedX_and_found_XfoundX("JsonObject",type),
399
                    th
400
                );
401
            }
402
        }
403
        return (JsonArray) value;
404
    }
405

    
406
    protected JsonStructure getJsonStructure(Object args[], int n) {
407
        if( args.length < n  ) {
408
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
409
        }
410
        return getJsonStructure(args[n],n);
411
    }
412

    
413
    protected JsonStructure getJsonStructure(Object value, int n) {
414
        if( value == null ) {
415
            throw new IllegalArgumentException(I18N.Illegal_null_value_for_argument_XargnX_of_XIdentifierX_function(name(), n));
416
        }
417
        if( !(value instanceof JsonStructure) ) {
418
            try {
419
                value = JsonUtils.toJson(value);
420
            } catch(Throwable th) {
421
                String type = value.getClass().getCanonicalName();
422
                throw new IllegalArgumentException(
423
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
424
                    I18N.Expected_XexpectedX_and_found_XfoundX("JsonObject",type),
425
                    th
426
                );
427
            }
428
        }
429
        return (JsonStructure) value;
430
    }
431

    
432
    protected Object getObject(Interpreter interpreter, Codes args, int n) {
433
        if( args.size() < n  ) {
434
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.size(), n));
435
        }
436
        Code arg = args.get(n);
437
        if( arg==null ) {
438
            return null;
439
        }
440
        Object value = interpreter.run(arg);
441
        return value;
442
    }
443
    
444
    protected Comparable getComparable(Object[] args, int n) {
445
        if( args.length < n  ) {
446
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
447
        }
448
        return getComparable(args[n],n);
449
    }
450
    
451
    protected Comparable getComparable(Object value, int n) {
452
        if( value == null ) {
453
            return null;
454
        }
455
        if( !(value instanceof Comparable) ) {
456
            String type = value.getClass().getCanonicalName();
457
            throw new IllegalArgumentException(
458
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
459
                    I18N.Expected_XexpectedX_and_found_XfoundX("Comparable",type)
460
            );
461
        }
462
        return (Comparable)value;
463
    }
464

    
465
    protected Comparable getDate(Object[] args, int n) {
466
        if( args.length < n  ) {
467
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
468
        }
469
        return getDate(args[n],n);
470
    }
471
    
472
    protected Date getDate(Object value, int n) {
473
        if( value == null ) {
474
            return null;
475
        }
476
        if( !(value instanceof Date) ) {
477
            String type = value.getClass().getCanonicalName();
478
            throw new IllegalArgumentException(
479
                    I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
480
                    I18N.Expected_XexpectedX_and_found_XfoundX("Date",type)
481
            );
482
        }
483
        return (Date)value;
484
    }
485
    
486
    protected LocalDateTime getLocalDateTime(Object[] args, int n) {
487
        if( args.length < n  ) {
488
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
489
        }
490
        return getLocalDateTime(args[n],n);
491
    }
492
    
493
    protected LocalDateTime getLocalDateTime(Object value, int n) {
494
        if( value == null ) {
495
            return null;
496
        }
497
        if( value instanceof Date ) {
498
            Date date = ((Date)value);
499
            return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
500
        }
501
        if( value instanceof LocalDateTime ) {
502
            return (LocalDateTime) value;
503
        }
504
        if( value instanceof TemporalAccessor ) {
505
            return LocalDateTime.from(((TemporalAccessor)value));
506
        }
507
        String type = value.getClass().getCanonicalName();
508
        throw new IllegalArgumentException(
509
                I18N.The_type_of_the_argument_XargnX_for_the_XIdentifierX_function_is_incorrect(name(), n) + " " +
510
                I18N.Expected_XexpectedX_and_found_XfoundX("Temporal/Date",type)
511
        );
512
    }
513

    
514
    public URL getURL(Object[] args, int index) throws MalformedURLException {
515
        Object obj = getObject(args, index);
516
        if( obj == null ) {
517
            return null;
518
        }  
519
        URL url;
520
        if( obj instanceof URL ) {
521
            url = (URL) obj;        } else if( obj instanceof CharSequence ) {
522
            url = new URL(((CharSequence)obj).toString());
523
        } else if( obj instanceof File ) {
524
            url = ((File)obj).toURI().toURL();
525
        } else if( obj instanceof URI ) {
526
            url = ((URI)obj).toURL();
527
        } else {
528
            throw new ExpressionRuntimeException("The "+this.name()+" function require a File, URI or a String and a received a '"+obj.getClass().getSimpleName()+"'.");
529
        }  
530
        return url;
531
    }
532
    
533
    protected boolean getBoolean(Object args[], int n, Double accuracy) {
534
        if( args.length < n  ) {
535
            throw new IllegalArgumentException(I18N.Required_argument_XargnX_and_only_found_XargcX_in_call_to_XIdentifierX(name(), args.length, n));
536
        }
537
        return getBoolean(args[n], n, accuracy);
538
    }
539

    
540
    protected boolean getBoolean(Object value, int n) {
541
        return getBoolean(value, n, MathUtils.EPSILON);
542
    }
543

    
544
    protected boolean getBoolean(Object value, int n, Double accuracy) {
545
        return toBoolean(value, accuracy);
546
    }
547

    
548
    protected boolean getBoolean(Interpreter interpreter, Codes args, int n) {
549
        Object value = getObject(interpreter, args, n);
550
        return toBoolean(value, interpreter.getAccuracy());
551
    }
552

    
553
    protected boolean toBoolean(Object value, Double accuracy) {
554
        if( value == null ) {
555
            return false;
556
        }
557
        if( value instanceof Boolean ) {
558
            return (Boolean)value;
559
        }        
560
        if( value instanceof Number ) {
561
            return MathUtils.compareTo(
562
                ((Number) value).doubleValue(), 
563
                0,
564
                accuracy==null? MathUtils.EPSILON:accuracy
565
            ) == 0;
566
        }
567
        return BooleanUtils.toBoolean(value.toString());
568
    } 
569
    
570
    protected GetItemWithSize64 getList(Object[] args, int index)  {
571
        Object value = getObject(args, index);
572
        if( value == null ) {
573
            return null;
574
        }  
575
        GetItemWithSize64 list = null;
576
        if (value instanceof List) {
577
            list = new GetItemWithSize64<Object>() {
578
                @Override
579
                public long size64() {
580
                    return ((List) value).size();
581
                }
582

    
583
                @Override
584
                public Object get64(long index) {
585
                    return ((List) value).get((int) index);
586
                }
587
            };
588
        } else if (value instanceof Object[]) {
589
            list = new GetItemWithSize64<Object>() {
590
                @Override
591
                public long size64() {
592
                    return ((Object[]) value).length;
593
                }
594

    
595
                @Override
596
                public Object get64(long index) {
597
                    return ((Object[]) value)[(int) index];
598
                }
599
            };
600
        } else if (value instanceof GetItemWithSize64 ) {
601
            list = (GetItemWithSize64) value;
602
            
603
        } else if (value instanceof GetItem && value instanceof Size) {
604
            list = new GetItemWithSize64<Object>() {
605
                @Override
606
                public long size64() {
607
                    return ((Size) value).size();
608
                }
609

    
610
                @Override
611
                public Object get64(long index) {
612
                    return ((GetItem) value).get((int) index);
613
                }
614
            };
615
        } else if (value instanceof GetItem64 && value instanceof Size64) {
616
            list = new GetItemWithSize64<Object>() {
617
                @Override
618
                public long size64() {
619
                    return ((Size64) value).size64();
620
                }
621

    
622
                @Override
623
                public Object get64(long index) {
624
                    return ((GetItem64) value).get64((int) index);
625
                }
626
            };
627
        }
628
        return list;
629
    }
630
    
631

    
632
    private void load_from_resource() {
633
        String lang = Locale.getDefault().getLanguage();
634
        URL url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/"+lang+"/"+this.name()+".json");
635
        if( url == null ) {
636
            url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/en/"+this.name()+".json");
637
            if( url == null ) {
638
                return;
639
            }
640
        }
641
        InputStream is = null;
642
        JSONObject json;
643
        try {
644
            is = url.openStream();
645
            List<String> lines = IOUtils.readLines(is);
646
            json = new JSONObject(StringUtils.join(lines,  "\n"));
647
        } catch (Exception ex) {
648
            return;
649
        } finally {
650
            IOUtils.closeQuietly(is);
651
        }
652
        
653
        if( json.has("group") ) {
654
            this.group = json.getString("group");
655
        }
656
        if( json.has("description") ) {
657
            Object x = json.get("description");
658
            if( x instanceof String ) {
659
                this.description = (String) x;
660
            } else if( x instanceof JSONArray ) {
661
                StringBuilder builder = new StringBuilder();
662
                for (int i = 0; i < ((JSONArray)x).length(); i++) {
663
                    if( i>0 ) {
664
                        builder.append(" ");
665
                    }
666
                    builder.append(((JSONArray)x).getString(i));
667
                }
668
                this.description = builder.toString();
669
            } else {
670
                this.description = Objects.toString(x, null);
671
            }
672
            this.description = StringUtils.replace(
673
                    this.description, 
674
                    "@@@", 
675
                    url.toString()
676
            );
677
        }
678
        if( json.has("template") ) {
679
            this.template = json.getString("template");
680
        }
681
        if( json.has("returnType") ) {
682
            this.returnType = json.getString("returnType");
683
        }
684
        if( json.has("sqlCompatible") ) {
685
            this.sqlCompatible = json.getBoolean("sqlCompatible");
686
        }
687
        if( json.has("args") ) {
688
            JSONArray x = json.getJSONArray("args");
689
            String[] args = new String[x.length()];
690
            for (int i = 0; i < x.length(); i++) {
691
                args[i] = x.getString(i);
692
            }
693
            this.descriptionArgs = args;
694
        }
695
        if( json.has("alias") ) {
696
            JSONArray x = json.getJSONArray("alias");
697
            for (int i = 0; i < x.length(); i++) {
698
                this.addAlias(x.getString(i));
699
            }
700
        }
701
    }
702
    protected static final int TYPE_INT =     0b00000001;
703
    protected static final int TYPE_LONG =    0b00000010;
704
    protected static final int TYPE_FLOAT =   0b00000100;
705
    protected static final int TYPE_DOUBLE =  0b00001000;
706
    protected static final int TYPE_BOOLEAN = 0b00010000;
707
    protected static final int TYPE_STRING =  0b00100000;
708
    protected static final int TYPE_DATE =    0b01000000;
709
    protected static final int TYPE_NULL =    0b10000000;
710
    
711
    protected int getType(Object op1, Object op2) {
712
        int r = 0;
713
        if( op1 == null ) {
714
            r |= TYPE_NULL;
715
        } else if( op1 instanceof Double ) {
716
            r |= TYPE_DOUBLE;
717
        } else if( op1 instanceof Float ) {
718
            r |= TYPE_FLOAT;
719
        } else if( op1 instanceof Long ) {
720
            r |= TYPE_LONG;
721
        } else if( op1 instanceof Integer ) {
722
            r |= TYPE_INT;
723
        } else if( op1 instanceof Boolean ) {
724
            r |= TYPE_BOOLEAN;
725
        } else if( op1 instanceof String ) {
726
            r |= TYPE_STRING;
727
        } else if( op1 instanceof Date ) {
728
            r |= TYPE_DATE;
729
        }
730
        if( op2 == null ) {
731
            r |= TYPE_NULL;
732
        } else if( op2 instanceof Double ) {
733
            r |= TYPE_DOUBLE;
734
        } else if( op2 instanceof Float ) {
735
            r |= TYPE_FLOAT;
736
        } else if( op2 instanceof Long ) {
737
            r |= TYPE_LONG;
738
        } else if( op2 instanceof Integer ) {
739
            r |= TYPE_INT;
740
        } else if( op2 instanceof Boolean ) {
741
            r |= TYPE_BOOLEAN;
742
        } else if( op2 instanceof String ) {
743
            r |= TYPE_STRING;
744
        } else if( op2 instanceof Date ) {
745
            r |= TYPE_DATE;
746
        }
747
        return r;
748
    }
749

    
750
    @Override
751
    public String toString(Codes args, Formatter<Code> formatter) {
752
        return null;
753
    }
754

    
755
}