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

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.feature.FeatureStore;
34
import org.gvsig.fmap.geom.GeometryLocator;
35
import org.gvsig.fmap.geom.GeometryManager;
36
import org.gvsig.fmap.geom.type.GeometryType;
37
import org.gvsig.tools.ToolsLocator;
38
import org.gvsig.tools.task.SimpleTaskStatus;
39
import org.gvsig.topology.lib.api.TopologyDataSet;
40
import org.gvsig.topology.lib.api.TopologyManager;
41
import org.gvsig.topology.lib.api.TopologyPlan;
42
import org.gvsig.topology.lib.api.TopologyRule;
43
import org.gvsig.topology.lib.api.TopologyRuleFactory;
44
import org.gvsig.topology.lib.api.TopologyServices;
45
import org.json.JSONArray;
46
import org.json.JSONObject;
47
import org.slf4j.Logger;
48
import org.slf4j.LoggerFactory;
49

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
332
    
333
}