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

History | View | Annotate | Download (11.3 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
        for (TopologyDataSet dataSet : this.dataSets.values()) {
114
            if(dataSet instanceof DefaultTopologyDataSet){
115
                ((DefaultTopologyDataSet)dataSet).setTopologyServices(services);
116
            }
117
        }
118
    }
119
    
120
    @Override
121
    public TopologyServices getTopologyServices() {
122
        return this.services;
123
    }
124
    
125
    public SimpleTaskStatus getTaskStatus() {
126
        if( this.taskStatus == null ) {
127
            this.taskStatus = ToolsLocator.getTaskStatusManager()
128
                    .createDefaultSimpleTaskStatus(this.getName());
129
        }
130
        return this.taskStatus;
131
    }
132
    
133
    @Override
134
    public void execute() {
135
        SimpleTaskStatus theTaskStatus = this.getTaskStatus();
136
        try {
137
            theTaskStatus.restart();
138
            theTaskStatus.message("Preparing the execution of the plan");
139
            theTaskStatus.setAutoremove(true);
140
            theTaskStatus.setIndeterminate();
141
            for (TopologyDataSet dataSet : this.dataSets.values()) {
142
                dataSet.restart();
143
            }
144
            this.getReport().removeAllLines();
145
            long steps = 0;
146
            for (TopologyRule rule : this.rules) {
147
                steps += rule.getSteps();
148
                steps++;
149
            }
150

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

    
173
    @Override
174
    public TopologyDataSet addDataSet(String name, DataStore store) {
175
        TopologyDataSet dataSet = manager.createDataSet(name, store);
176
        return this.addDataSet(dataSet);
177
    }
178

    
179
    @Override
180
    public TopologyDataSet addDataSet(TopologyDataSet dataSet) {
181
        if( this.dataSets.containsKey(dataSet.getName()) ) {
182
            throw new IllegalArgumentException("Already exists a dataSet with this name ("+dataSet.getName()+").");
183
        }
184
        this.dataSets.put(dataSet.getName(), dataSet);
185
        return dataSet;
186
    }
187

    
188
    @Override
189
    public TopologyDataSet getDataSet(String name) {
190
        return this.dataSets.get(name);
191
    }
192

    
193
    @Override
194
    public boolean containsDataSet(String name) {
195
        return this.dataSets.containsKey(name);
196
    }
197

    
198
    @Override
199
    public Collection<TopologyDataSet> getDataSets() {
200
        Collection<TopologyDataSet> x = dataSets.values();
201
        return Collections.unmodifiableCollection(x);
202
    }
203

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

    
230
    @Override
231
    public TopologyRule addRule(TopologyRule rule) {
232
        this.rules.add(rule);
233
        return rule;
234
    }
235

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

    
263
    @Override
264
    public Collection<TopologyRule> getRules() {
265
        return Collections.unmodifiableList(rules);
266
    }
267
    
268
    @Override
269
    public boolean hasRules() {
270
        return !this.rules.isEmpty();
271
    }
272

    
273
    @Override
274
    public DefaultTopologyReport getReport() {
275
        if( this.report == null ) {
276
            this.report = new DefaultTopologyReport(this);
277
        }
278
        return this.report;
279
    }
280

    
281
    @Override
282
    public JSONObject toJSON() {
283
        JSONObject me = new JSONObject();
284

    
285
        me.put("name", this.name);
286
        me.put("tolerance", this.tolerance);
287
        
288
        JSONArray jsonDataSets=  new JSONArray();
289
        for (TopologyDataSet dataSet : this.dataSets.values()) {
290
            jsonDataSets.put(((DefaultTopologyDataSet)dataSet).toJSON());
291
        }
292
        me.put("dataSets", jsonDataSets);
293
        
294
        JSONArray jsonRules = new JSONArray();
295
        for (TopologyRule rule : this.rules) {
296
            JSONObject jsonRule = rule.toJSON();
297
            jsonRule.put("__factoryId", rule.getFactory().getId());
298
            jsonRules.put(jsonRule);
299
        }
300
        me.put("rules", jsonRules);
301
        
302
        return me;
303
    }
304

    
305
    @Override
306
    public void fromJSON(String json) {
307
        this.fromJSON(new JSONObject(json));
308
    }
309

    
310
    @Override
311
    public void fromJSON(JSONObject jsonPlan) {
312
        
313
        this.name = jsonPlan.getString("name");
314
        this.tolerance = jsonPlan.getDouble("tolerance");
315
        
316
        JSONArray jsonDataSets = jsonPlan.getJSONArray("dataSets");
317
        for (Object o : jsonDataSets) {
318
            TopologyDataSet dataSet = new DefaultTopologyDataSet();
319
            dataSet.fromJSON((JSONObject) o);
320
            this.dataSets.put(dataSet.getName(),dataSet);
321
        }
322
        
323
        JSONArray jsonRules = jsonPlan.getJSONArray("rules");
324
        for (Object o : jsonRules) {
325
            JSONObject jsonRule = (JSONObject) o;
326
            TopologyRuleFactory factory = this.manager.getRulefactory(jsonRule.getString("__factoryId"));
327
            TopologyRule rule = factory.createRule(this,null, null, -1);
328
            rule.fromJSON(jsonRule);
329
            this.addRule(rule);
330
        }        
331
    }
332

    
333
    @Override
334
    public void removeDataSet(TopologyDataSet dataSet) {
335
        this.dataSets.remove(dataSet.getName());
336
    }
337

    
338
    @Override
339
    public void removeRule(TopologyRule rule) {
340
        this.rules.remove(rule);
341
    }
342

    
343
    
344
}