Statistics
| Revision:

gvsig-projects-pool / org.gvsig.topology / trunk / org.gvsig.topology / org.gvsig.topology.lib / org.gvsig.topology.lib.impl / src / main / java / org / gvsig / topology / lib / impl / DefaultTopologyPlan.java @ 2067

History | View | Annotate | Download (10.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.topology.lib.impl;
25

    
26
import java.util.ArrayList;
27
import java.util.Collection;
28
import java.util.Collections;
29
import java.util.Date;
30
import java.util.HashMap;
31
import java.util.List;
32
import java.util.Map;
33
import org.gvsig.fmap.dal.DataStore;
34
import org.gvsig.fmap.dal.feature.FeatureStore;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.type.GeometryType;
38
import org.gvsig.tools.ToolsLocator;
39
import org.gvsig.tools.task.SimpleTaskStatus;
40
import org.gvsig.topology.lib.api.TopologyDataSet;
41
import org.gvsig.topology.lib.api.TopologyManager;
42
import org.gvsig.topology.lib.api.TopologyPlan;
43
import org.gvsig.topology.lib.api.TopologyRule;
44
import org.gvsig.topology.lib.api.TopologyRuleFactory;
45
import org.gvsig.topology.lib.api.TopologyServices;
46
import org.json.JSONArray;
47
import org.json.JSONObject;
48
import org.slf4j.Logger;
49
import org.slf4j.LoggerFactory;
50

    
51
/**
52
 *
53
 * @author jjdelcerro
54
 */
55
@SuppressWarnings("UseSpecificCatch")
56
public class DefaultTopologyPlan implements TopologyPlan {
57

    
58
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultTopologyPlan.class);
59
    
60
    private final TopologyManager manager;
61
    private final Map<String,TopologyDataSet> dataSets;
62
    private final List<TopologyRule> rules;
63

    
64
    private String name;
65
    private DefaultTopologyReport report;
66
    private TopologyServices services;
67
    private double tolerance;
68
    private SimpleTaskStatus taskStatus;
69
    
70
    public DefaultTopologyPlan(TopologyManager manager, TopologyServices services) {
71
        this.manager = manager;
72
        this.services = services;
73
        this.dataSets = new HashMap<>();
74
        this.rules = new ArrayList<>();
75
        this.report = null;
76
        this.name = "TopologyPlan-" + String.format("%08X", new Date().getTime());
77
        this.tolerance = 0;
78
    }
79

    
80
    @Override
81
    public void setName(String name) {
82
        this.name = name;
83
    }
84

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

    
90
    @Override
91
    public void clear() {
92
        this.name = "";
93
        this.tolerance = 0;
94
        this.services = null;
95
        this.report = null;
96
        this.dataSets.clear();
97
        this.rules.clear();
98
    }
99

    
100
    @Override
101
    public double getTolerance() {
102
        return tolerance;
103
    }
104

    
105
    @Override
106
    public void setTolerance(double tolerance) {
107
        this.tolerance = tolerance;
108
    }
109

    
110
    @Override
111
    public void setTopologyServices(TopologyServices services) {
112
        this.services = services;
113
    }
114
    
115
    @Override
116
    public TopologyServices getTopologyServices() {
117
        return this.services;
118
    }
119
    
120
    public SimpleTaskStatus getTaskStatus() {
121
        if( this.taskStatus == null ) {
122
            this.taskStatus = ToolsLocator.getTaskStatusManager()
123
                    .createDefaultSimpleTaskStatus(this.getName());
124
        }
125
        return this.taskStatus;
126
    }
127
    
128
    @Override
129
    public void execute() {
130
        SimpleTaskStatus theTaskStatus = this.getTaskStatus();
131
        try {
132
            theTaskStatus.restart();
133
            theTaskStatus.message("Preparing the execution of the plan");
134
            theTaskStatus.setAutoremove(true);
135
            theTaskStatus.setIndeterminate();
136
            for (TopologyDataSet dataSet : this.dataSets.values()) {
137
                dataSet.restart();
138
            }
139
            this.getReport().removeAllLines();
140
            long steps = 0;
141
            for (TopologyRule rule : this.rules) {
142
                steps += rule.getSteps();
143
                steps++;
144
            }
145

    
146
            theTaskStatus.setRangeOfValues(0, steps);
147
            theTaskStatus.setCurValue(0);
148
            for (TopologyRule rule : this.rules) {
149
                if( theTaskStatus.isCancellationRequested() ) {
150
                    theTaskStatus.cancel();
151
                    break;
152
                }
153
                theTaskStatus.message(rule.getName());
154
                rule.execute(theTaskStatus, this.getReport());
155
                theTaskStatus.incrementCurrentValue();
156
            }
157
        } catch(Exception ex) {
158
            LOGGER.warn("Problems executing topology plan '"+this.getName()+"'.", ex);
159
            theTaskStatus.abort();
160
        } finally {
161
            if( theTaskStatus.isRunning() ) {
162
                theTaskStatus.terminate();
163
            }
164
            this.getReport().setCompleted(true);
165
        }
166
    }
167

    
168
    @Override
169
    public TopologyDataSet addDataSet(String name, DataStore store) {
170
        TopologyDataSet dataSet = manager.createDataSet(name, store);
171
        return this.addDataSet(dataSet);
172
    }
173

    
174
    @Override
175
    public TopologyDataSet addDataSet(TopologyDataSet dataSet) {
176
        if( this.dataSets.containsKey(dataSet.getName()) ) {
177
            throw new IllegalArgumentException("Already exists a dataSet with this name ("+dataSet.getName()+").");
178
        }
179
        this.dataSets.put(dataSet.getName(), dataSet);
180
        return dataSet;
181
    }
182

    
183
    @Override
184
    public TopologyDataSet getDataSet(String name) {
185
        return this.dataSets.get(name);
186
    }
187

    
188
    @Override
189
    public boolean containsDataSet(String name) {
190
        return this.dataSets.containsKey(name);
191
    }
192

    
193
    @Override
194
    public Collection<TopologyDataSet> getDataSets() {
195
        Collection<TopologyDataSet> x = dataSets.values();
196
        return Collections.unmodifiableCollection(x);
197
    }
198

    
199
    @Override
200
    public Collection<TopologyDataSet> getSecondaryDataSets(TopologyRuleFactory ruleFactory) {
201
        List<TopologyDataSet> secondaryDataSets = new ArrayList<>();
202
        for (TopologyDataSet dataSet : dataSets.values()) {
203
            if( ruleFactory.canApplyToSecondaryDataSet(dataSet) ) {
204
                secondaryDataSets.add(dataSet);
205
            }
206
        }
207
        return secondaryDataSets;
208
    }
209
    
210
    @Override
211
    public TopologyRule addRule(String id, String dataSet1, String dataSet2, double tolerance) {
212
        TopologyRuleFactory factory = this.manager.getRulefactory(id);
213
        if( factory == null ) {
214
            throw new IllegalArgumentException("Can't locate factory for rule '"+id+"'.");
215
        }
216
        if( ! this.canApplyRule(factory, dataSet1, dataSet2) ) {
217
            throw new IllegalArgumentException(
218
                    "Can't apply rule '"+factory.getName()+"' to the datasets '"+dataSet1+"/"+dataSet2+"'."
219
            );
220
        }
221
        TopologyRule rule = factory.createRule(this, dataSet1, dataSet2, tolerance);
222
        return this.addRule(rule);
223
    }
224

    
225
    @Override
226
    public TopologyRule addRule(TopologyRule rule) {
227
        this.rules.add(rule);
228
        return rule;
229
    }
230

    
231
    private boolean canApplyRule(TopologyRuleFactory factory, String dataSet1, String dataSet2) {
232
        try {
233
            GeometryManager geomManager = GeometryLocator.getGeometryManager();
234
            TopologyDataSet dataset = this.getDataSet(dataSet1);
235
            FeatureStore store = (FeatureStore) dataset.getStore();
236
            GeometryType gt = store.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType();
237
            for (Integer geometryType1 : factory.getGeometryTypeDataSet1()) {
238
                if( gt.isTypeOf(geometryType1) ) {
239
                    if( factory.getGeometryTypeDataSet2()==null ) {
240
                        return true;
241
                    }
242
                    dataset = this.getDataSet(dataSet2);
243
                    store = (FeatureStore) dataset.getStore();
244
                    gt = store.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType();
245
                    for (Integer geometryType2 : factory.getGeometryTypeDataSet2()) {
246
                        if( gt.isTypeOf(geometryType2) ) {
247
                            return true;
248
                        }
249
                    }
250
                }
251
            }
252
            return false;
253
        } catch(Exception ex) {
254
            return false;
255
        }
256
    }    
257

    
258
    @Override
259
    public Collection<TopologyRule> getRules() {
260
        return Collections.unmodifiableList(rules);
261
    }
262

    
263
    @Override
264
    public DefaultTopologyReport getReport() {
265
        if( this.report == null ) {
266
            this.report = new DefaultTopologyReport(this);
267
        }
268
        return this.report;
269
    }
270

    
271
    @Override
272
    public JSONObject toJSON() {
273
        JSONObject me = new JSONObject();
274

    
275
        me.put("name", this.name);
276
        me.put("tolerance", this.tolerance);
277
        
278
        JSONArray jsonDataSets=  new JSONArray();
279
        for (TopologyDataSet dataSet : this.dataSets.values()) {
280
            jsonDataSets.put(((DefaultTopologyDataSet)dataSet).toJSON());
281
        }
282
        me.put("dataSets", jsonDataSets);
283
        
284
        JSONArray jsonRules = new JSONArray();
285
        for (TopologyRule rule : this.rules) {
286
            JSONObject jsonRule = rule.toJSON();
287
            jsonRule.put("__factoryId", rule.getFactory().getId());
288
            jsonRules.put(jsonRule);
289
        }
290
        me.put("rules", jsonRules);
291
        
292
        return me;
293
    }
294

    
295
    @Override
296
    public void fromJSON(String json) {
297
        this.fromJSON(new JSONObject(json));
298
    }
299

    
300
    @Override
301
    public void fromJSON(JSONObject jsonPlan) {
302
        
303
        this.name = jsonPlan.getString("name");
304
        this.tolerance = jsonPlan.getDouble("tolerance");
305
        
306
        JSONArray jsonDataSets = jsonPlan.getJSONArray("dataSets");
307
        for (Object o : jsonDataSets) {
308
            TopologyDataSet dataSet = new DefaultTopologyDataSet();
309
            dataSet.fromJSON((JSONObject) o);
310
            this.dataSets.put(dataSet.getName(),dataSet);
311
        }
312
        
313
        JSONArray jsonRules = jsonPlan.getJSONArray("rules");
314
        for (Object o : jsonRules) {
315
            JSONObject jsonRule = (JSONObject) o;
316
            TopologyRuleFactory factory = this.manager.getRulefactory(jsonRule.getString("__factoryId"));
317
            TopologyRule rule = factory.createRule(this,null, null, -1);
318
            rule.fromJSON(jsonRule);
319
            this.addRule(rule);
320
        }        
321
    }
322

    
323
    @Override
324
    public void removeDataSet(TopologyDataSet dataSet) {
325
        this.dataSets.remove(dataSet.getName());
326
    }
327

    
328
    @Override
329
    public void removeRule(TopologyRule rule) {
330
        this.rules.remove(rule);
331
    }
332

    
333
    
334
}