Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / ProjectSymbolTable.java @ 43987

History | View | Annotate | Download (12 KB)

1
package org.gvsig.app.project;
2

    
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.util.HashMap;
6
import java.util.Map;
7
import java.util.Properties;
8
import org.apache.commons.io.IOUtils;
9
import org.apache.commons.lang3.Range;
10
import org.gvsig.app.project.documents.view.ViewDocument;
11
import org.gvsig.app.project.documents.view.ViewManager;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
14
import org.gvsig.expressionevaluator.Interpreter;
15
import org.gvsig.expressionevaluator.spi.AbstractFunction;
16
import org.gvsig.expressionevaluator.spi.AbstractSymbolTable;
17
import org.gvsig.fmap.dal.feature.Feature;
18
import org.gvsig.fmap.dal.feature.FeatureQuery;
19
import org.gvsig.fmap.dal.feature.FeatureSelection;
20
import org.gvsig.fmap.dal.feature.FeatureSet;
21
import org.gvsig.fmap.dal.feature.FeatureStore;
22
import org.gvsig.fmap.mapcontext.layers.FLayer;
23
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
24

    
25
/**
26
 *
27
 * @author jjdelcerro
28
 */
29
@SuppressWarnings("UseSpecificCatch")
30
public class ProjectSymbolTable extends AbstractSymbolTable {
31

    
32
    private abstract class CachedValue<T> {
33

    
34
        T value = null;
35
        long lastAccess = 0;
36

    
37
        protected abstract void reload();
38

    
39
        public boolean isExpired() {
40
            long now = System.currentTimeMillis();
41
            return now - lastAccess > 3000;
42
        }
43

    
44
        public T get() {
45
            if (isExpired()) {
46
                reload();
47
            }
48
            lastAccess = System.currentTimeMillis();
49
            return value;
50
        }
51
    }
52

    
53
    private class ProjectValue extends CachedValue<Project> {
54

    
55
        @Override
56
        protected void reload() {
57
            value = ProjectManager.getInstance().getCurrentProject();
58
        }
59

    
60
    }
61

    
62
    private class PropertiesValue extends CachedValue<Map<File, Properties>> {
63

    
64
        @Override
65
        protected void reload() {
66
            value = new HashMap<>();
67
        }
68
    }
69

    
70
    private class CurrentProjectFunction extends AbstractFunction {
71

    
72
        public CurrentProjectFunction() {
73
            super(
74
                    "Project",
75
                    "project",
76
                    Range.is(0),
77
                    "Access to the current project loaded in gvSIG desktop.\n",
78
                    "project()",
79
                    null,
80
                    "Project"
81
            );
82
        }
83

    
84
        @Override
85
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
86
            return currentProject.get();
87
        }
88

    
89
    }
90

    
91
    private class FirstSelectedFeatureFunction extends AbstractFunction {
92

    
93
        public FirstSelectedFeatureFunction() {
94
            super(
95
                    "Project",
96
                    "firstSelectedFeature",
97
                    Range.between(3, 4),
98
                    "Access to the first selected feature of the layer, and "
99
                    + "return the value of the attribute.",
100
                    "firstSelectedFeature({{view}}, layer, attribute, defaulValue)",
101
                    new String[]{
102
                        "view - String value with the name of a view",
103
                        "layer - String value with the name of a layer in the indicated view",
104
                        "attribute - String value with the name of the attribute in the indicated layer",
105
                        "defaultValue - Optional. Value to use if the indicated "
106
                        + "attribute can not be accessed. For example, if the "
107
                        + "view or layer does not exist, or it does not have "
108
                        + "selected elements."
109
                    },
110
                    "Object"
111
            );
112
        }
113

    
114
        @Override
115
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
116
            Object defaultValue = null;
117
            String viewName = getStr(args, 0);
118
            String layerName = getStr(args, 1);
119
            String attrName = getStr(args, 2);
120
            if (args.length == 4) {
121
                defaultValue = getObject(args, 3);
122
            }
123
            try {
124
                Project project = currentProject.get();
125
                ViewDocument view = (ViewDocument) project.getDocument(viewName, ViewManager.TYPENAME);
126
                if (view == null) {
127
                    return defaultValue;
128
                }
129
                FLayer layer = view.getLayer(layerName);
130
                if (!(layer instanceof FLyrVect)) {
131
                    return defaultValue;
132
                }
133
                FeatureSelection selection = ((FLyrVect) layer).getFeatureStore().getFeatureSelection();
134
                if (selection == null || selection.isEmpty()) {
135
                    return defaultValue;
136
                }
137
                Feature feature = selection.first();
138
                if (feature == null) {
139
                    return defaultValue;
140
                }
141
                return feature.get(attrName);
142
            } catch (Exception ex) {
143
                return defaultValue;
144
            }
145
        }
146

    
147
    }
148

    
149
    private class FirstFeatureFunction extends AbstractFunction {
150

    
151
        public FirstFeatureFunction() {
152
            super(
153
                    "Project",
154
                    "firstFeature",
155
                    Range.between(3, 6),
156
                    "Access to the first feature of the layer, and "
157
                    + "return the value of the attribute.",
158
                    "firstFeature({{view}}, layer, attribute, filter, order, defaulValue)",
159
                    new String[]{
160
                        "view - String value with the name of a view",
161
                        "layer - String value with the name of a layer in the indicated view",
162
                        "attribute - String value with the name of the attribute in the indicated layer",
163
                        "filter - Optional. String value with a filter expression",
164
                        "order - Optional. String value with the order. must be a string with the names of separate fields with commas",
165
                        "defaultValue - Optional. Value to use if the indicated "
166
                        + "attribute can not be accessed. For example, if the "
167
                        + "view or layer does not exist."
168
                    },
169
                    "Object"
170
            );
171
        }
172

    
173
        @Override
174
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
175
            Object defaultValue = null;
176
            String filter = null;
177
            String order = null;
178
            String viewName = getStr(args, 0);
179
            String layerName = getStr(args, 1);
180
            String attrName = getStr(args, 2);
181
            switch(args.length ) {
182
                case 4:
183
                    filter = getStr(args, 3);
184
                    break;
185
                case 5:
186
                    filter = getStr(args, 3);
187
                    order = getStr(args, 4);
188
                    break;
189
                case 6:
190
                    filter = getStr(args, 3);
191
                    order = getStr(args, 4);
192
                    defaultValue = getObject(args, 6);
193
                    break;
194
            }
195
            try {
196
                Project project = currentProject.get();
197
                ViewDocument view = (ViewDocument) project.getDocument(viewName, ViewManager.TYPENAME);
198
                if (view == null) {
199
                    return defaultValue;
200
                }
201
                FLayer layer = view.getLayer(layerName);
202
                if (!(layer instanceof FLyrVect)) {
203
                    return defaultValue;
204
                }
205
                FeatureStore store = ((FLyrVect) layer).getFeatureStore();
206
                FeatureSet set;
207
                if( filter==null && order==null ) {
208
                    set = store.getFeatureSet();
209
                } else {
210
                    FeatureQuery query = store.createFeatureQuery();
211
                    if( filter != null ) {
212
                        query.addFilter(filter);
213
                    }
214
                    if( order!=null ) {
215
                        query.getOrder().add(order);
216
                    }
217
                    set = store.getFeatureSet(query);
218
                }
219
                Feature feature = set.first();
220
                if (feature == null) {
221
                    return defaultValue;
222
                }
223
                return feature.get(attrName);
224
            } catch (Exception ex) {
225
                return defaultValue;
226
            }
227
        }
228

    
229
    }
230

    
231
    private class ViewFunction extends AbstractFunction {
232

    
233
        public ViewFunction() {
234
            super(
235
                    "Project",
236
                    "view",
237
                    Range.is(1),
238
                    "Access to the indicated view",
239
                    "view({{viewName}})",
240
                    new String[]{
241
                        "view - String value with the name of a view"
242
                    },
243
                    "DocumentView"
244
            );
245
        }
246

    
247
        @Override
248
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
249
            String viewName = getStr(args, 0);
250
            Project project = currentProject.get();
251
            ViewDocument view = (ViewDocument) project.getDocument(viewName, ViewManager.TYPENAME);
252
            return view;
253
        }
254

    
255
    }
256

    
257
    private class PropertyFunction extends AbstractFunction {
258

    
259
        public PropertyFunction() {
260
            super(
261
                    "Project",
262
                    "property",
263
                    Range.between(2, 3),
264
                    "Access to a property value in a properties file. If the"
265
                    + "indicated filename is not absolute, access it relative"
266
                    + "to the project.",
267
                    "property({{filename}}, name, defaultValue)",
268
                    new String[]{
269
                        "filename - String value with the name of the properties file",
270
                        "name - String value with the name of the property to retrieve from the file",
271
                        "defaultValue - Optional. Default value if can't access the file or the property",},
272
                    "String"
273
            );
274
        }
275

    
276
        @Override
277
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
278
            String filename = getStr(args, 0);
279
            String name = getStr(args, 1);
280
            String defaultValue = null;
281
            if (args.length == 3) {
282
                defaultValue = getStr(args, 2);
283
            }
284

    
285
            File file = new File(filename);
286
            if (!file.isAbsolute()) {
287
                Project project = currentProject.get();
288
                if (project.getFile() == null) {
289
                    return defaultValue;
290
                }
291
                file = new File(project.getFile().getParent(), filename);
292
            }
293
            Map<File, Properties> x = propertiesFiles.get();
294
            Properties properties = x.get(file);
295
            if (properties == null) {
296
                properties = new Properties();
297
                FileInputStream in = null;
298
                try {
299
                    in = new FileInputStream(file);
300
                    properties.load(in);
301
                } catch (Exception ex) {
302
                    return defaultValue;
303
                } finally {
304
                    IOUtils.closeQuietly(in);
305
                }
306
                x.put(file, properties);
307
            }
308
            String value = properties.getProperty(name, defaultValue);
309
            return value;
310
        }
311

    
312
    }
313

    
314
    ProjectValue currentProject = new ProjectValue();
315
    PropertiesValue propertiesFiles = new PropertiesValue();
316

    
317
    @SuppressWarnings("OverridableMethodCallInConstructor")
318
    public ProjectSymbolTable() {
319
        super("Project");
320
        this.addFunction(new CurrentProjectFunction());
321
        this.addFunction(new FirstSelectedFeatureFunction());
322
        this.addFunction(new FirstFeatureFunction());
323
        this.addFunction(new ViewFunction());
324
        this.addFunction(new PropertyFunction());
325
    }
326

    
327
    public static void selfRegister() {
328
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
329
        manager.registerSymbolTable(new ProjectSymbolTable(), true);
330
    }
331
}