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

History | View | Annotate | Download (11.1 KB)

1
package org.gvsig.expressionevaluator.spi;
2

    
3
import java.io.InputStream;
4
import java.net.URL;
5
import java.util.ArrayList;
6
import java.util.List;
7
import java.util.Locale;
8
import java.util.Objects;
9
import org.apache.commons.io.IOUtils;
10
import org.apache.commons.lang3.BooleanUtils;
11
import org.apache.commons.lang3.Range;
12
import org.apache.commons.lang3.StringUtils;
13
import org.apache.commons.math.util.MathUtils;
14
import org.gvsig.expressionevaluator.Code;
15
import org.gvsig.expressionevaluator.Code.Caller.Arguments;
16
import org.gvsig.expressionevaluator.Function;
17
import org.gvsig.expressionevaluator.Interpreter;
18
import org.gvsig.fmap.geom.Geometry;
19
import org.gvsig.fmap.geom.primitive.Point;
20
import org.json.JSONArray;
21
import org.json.JSONObject;
22

    
23
@SuppressWarnings("UseSpecificCatch")
24
public abstract class AbstractFunction implements Function {
25
 
26
    private final String name;
27
    private String group;
28
    private Range argc;
29
    private String description;
30
    private String[] descriptionArgs;
31
    private List<String> alias;
32
    private String template;
33
    private String returnType;
34
    private boolean sqlCompatible;
35

    
36
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType, boolean sqlCompatible) {
37
        this.name = name;
38
        this.group = group;
39
        this.argc = argc;
40
        this.description = description;
41
        this.template = template;
42
        this.descriptionArgs = descriptionArgs;
43
        this.returnType = returnType;
44
        this.sqlCompatible = sqlCompatible;
45
        load_from_resource();
46
    }
47
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType) {
48
        this(group, name, argc, description, template, descriptionArgs, returnType, false);
49
    }
50
    
51
    protected AbstractFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs) {
52
        this(group, name, argc, description, template, null, null);
53
    }
54

    
55
    protected AbstractFunction(String group, String name, Range argc, String description, String template) {
56
        this(group, name, argc, description, template, null, null);
57
    }
58

    
59
    protected AbstractFunction(String group, String name, Range argc) {
60
        this(group, name, argc, null, null, null, null);
61
    }
62

    
63
    @Override
64
    public String name() {
65
        return this.name;
66
    }
67

    
68
    @Override
69
    public String returnType() {
70
        return this.returnType;
71
    }
72

    
73
    @Override
74
    public String group() {
75
        return this.group;
76
    }
77

    
78
    @Override
79
    public Range argc() {
80
        return argc;
81
    }
82

    
83
    @Override
84
    public String description() {
85
        return description;
86
    }
87

    
88
    @Override
89
    public String[] descriptionArgs() {
90
        return descriptionArgs;
91
    }
92

    
93
    @Override
94
    public void addAlias(String name) {
95
        if( StringUtils.isBlank(name) ) {
96
            return;
97
        }
98
        if( this.alias == null ) {
99
            this.alias = new ArrayList<>();
100
        }
101
        if( this.alias.contains(name) ) {
102
            return;
103
        }
104
        this.alias.add(name);
105
    }
106

    
107
    @Override
108
    public List<String> alias() {
109
        return this.alias;
110
    }
111

    
112
    @Override
113
    public String template() {
114
        return this.template;
115
    }
116

    
117
    @Override
118
    public boolean isOperator() {
119
        return false;
120
    }
121

    
122
    @Override
123
    public boolean useArgumentsInsteadObjects() {
124
        return false;
125
    }
126

    
127
    @Override
128
    public boolean isSQLCompatible() {
129
        return sqlCompatible;
130
    }
131
    
132
    @Override
133
    public Object call(Interpreter interpreter, Arguments args) throws Exception {
134
        return null;
135
    }
136
    
137
    protected int getInt(Object args[], int n) {
138
        if( args.length < n  ) {
139
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
140
        }
141
        if( !(args[n] instanceof Number) ) {
142
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
143
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Number and got " + type + ".");
144
        }
145
        return ((Number)args[n]).intValue();
146
    }
147

    
148
    protected long getLong(Object args[], int n) {
149
        if( args.length < n  ) {
150
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
151
        }
152
        if( !(args[n] instanceof Number) ) {
153
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
154
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Number and got " + type + ".");
155
        }
156
        return ((Number)args[n]).longValue();
157
    }
158

    
159
    protected double getDouble(Object args[], int n) {
160
        if( args.length < n  ) {
161
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
162
        }
163
        if( !(args[n] instanceof Number) ) {
164
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
165
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Number and got " + type + ".");
166
        }
167
        return ((Number)args[n]).doubleValue();
168
    }
169
    
170
    protected String getStr(Object args[], int n) {
171
        if( args.length < n  ) {
172
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
173
        }
174
        return Objects.toString(args[n], "");
175
    }
176
    
177
    protected Object getObject(Object args[], int n) {
178
        if( args.length < n  ) {
179
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
180
        }
181
        return args[n];
182
    }
183
    
184
    protected Object getObject(Interpreter interpreter, Arguments args, int n) {
185
        if( args.count() < n  ) {
186
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.count() +" arguments in call to '"+name()+"'.");
187
        }
188
        Code arg = args.get(n);
189
        Object value = interpreter.run(arg);
190
        return value;
191
    }
192
    
193
    protected Geometry getGeom(Object[] args, int n) {
194
        if( args.length < n  ) {
195
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
196
        }
197
        if( !(args[n] instanceof Geometry) ) {
198
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
199
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Geometry and got " + type + ".");
200
        }
201
        return (Geometry)args[n];
202
    }
203

    
204
    protected Point getPoint(Object[] args, int n) {
205
        if( args.length < n  ) {
206
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
207
        }
208
        if( !(args[n] instanceof Point) ) {
209
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
210
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Point and got " + type + ".");
211
        }
212
        return (Point)args[n];
213
    }
214
    
215
    protected boolean getBoolean(Object args[], int n, Double accuracy) {
216
        if( args.length < n  ) {
217
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
218
        }
219
        Object value = args[n];
220
        return toBoolean(value, accuracy);
221
    }
222

    
223
    protected boolean getBoolean(Interpreter interpreter, Arguments args, int n) {
224
        Object value = getObject(interpreter, args, n);
225
        return toBoolean(value, interpreter.getAccuracy());
226
    }
227

    
228
    protected boolean toBoolean(Object value, Double accuracy) {
229
        if( value == null ) {
230
            return false;
231
        }
232
        if( value instanceof Boolean ) {
233
            return (Boolean)value;
234
        }        
235
        if( value instanceof Number ) {
236
            return MathUtils.compareTo(
237
                ((Number) value).doubleValue(), 
238
                0,
239
                accuracy==null? MathUtils.EPSILON:accuracy
240
            ) == 0;
241
        }
242
        return BooleanUtils.toBoolean(value.toString());
243
    } 
244

    
245
    private void load_from_resource() {
246
        String lang = Locale.getDefault().getLanguage();
247
        URL url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/"+lang+"/"+this.name()+".json");
248
        if( url == null ) {
249
            url = this.getClass().getResource("/org/gvsig/expressionevaluator/functions/en/"+this.name()+".json");
250
            if( url == null ) {
251
                return;
252
            }
253
        }
254
        InputStream is = null;
255
        JSONObject json;
256
        try {
257
            is = url.openStream();
258
            List<String> lines = IOUtils.readLines(is);
259
            json = new JSONObject(StringUtils.join(lines,  "\n"));
260
        } catch (Exception ex) {
261
            return;
262
        } finally {
263
            IOUtils.closeQuietly(is);
264
        }
265
        
266
        if( json.has("group") ) {
267
            this.group = json.getString("group");
268
        }
269
        if( json.has("description") ) {
270
            Object x = json.get("description");
271
            if( x instanceof String ) {
272
                this.description = (String) x;
273
            } else if( x instanceof JSONArray ) {
274
                StringBuilder builder = new StringBuilder();
275
                for (int i = 0; i < ((JSONArray)x).length(); i++) {
276
                    if( i>0 ) {
277
                        builder.append(" ");
278
                    }
279
                    builder.append(((JSONArray)x).getString(i));
280
                }
281
                this.description = builder.toString();
282
            } else {
283
                this.description = x.toString();
284
            }
285
            this.description = StringUtils.replace(
286
                    this.description, 
287
                    "@@@", 
288
                    url.toString()
289
            );
290
        }
291
        if( json.has("template") ) {
292
            this.template = json.getString("template");
293
        }
294
        if( json.has("returnType") ) {
295
            this.returnType = json.getString("returnType");
296
        }
297
        if( json.has("sqlCompatible") ) {
298
            this.sqlCompatible = json.getBoolean("sqlCompatible");
299
        }
300
        if( json.has("args") ) {
301
            JSONArray x = json.getJSONArray("args");
302
            String[] args = new String[x.length()];
303
            for (int i = 0; i < x.length(); i++) {
304
                args[i] = x.getString(i);
305
            }
306
            this.descriptionArgs = args;
307
        }
308
        if( json.has("alias") ) {
309
            JSONArray x = json.getJSONArray("alias");
310
            for (int i = 0; i < x.length(); i++) {
311
                this.addAlias(x.getString(i));
312
            }
313
        }
314
    }
315
}