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

History | View | Annotate | Download (11.2 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 boolean allowConstantFolding() {
134
        return false;
135
    }
136
    
137
    @Override
138
    public Object call(Interpreter interpreter, Arguments args) throws Exception {
139
        return null;
140
    }
141
    
142
    protected int getInt(Object args[], int n) {
143
        if( args.length < n  ) {
144
            throw new IllegalArgumentException("Required argument "+n+" and only found " + args.length +" arguments in call to '"+name()+"'.");
145
        }
146
        if( !(args[n] instanceof Number) ) {
147
            String type = (args[n]==null)? "null" : args[n].getClass().getCanonicalName();
148
            throw new IllegalArgumentException("Type not allowed for argument " + n + " in '" + name() + "' function, expected Number and got " + type + ".");
149
        }
150
        return ((Number)args[n]).intValue();
151
    }
152

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

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

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

    
228
    protected boolean getBoolean(Interpreter interpreter, Arguments args, int n) {
229
        Object value = getObject(interpreter, args, n);
230
        return toBoolean(value, interpreter.getAccuracy());
231
    }
232

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

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