Revision 19093 trunk/libraries/libTopology/src/org/gvsig/topology/Topology.java

View differences:

Topology.java
43 43
 */
44 44
/* CVS MESSAGES:
45 45
 *
46
 * $Id: 
47
 * $Log: 
46
 * $Id:
47
 * $Log:
48 48
 */
49 49
package org.gvsig.topology;
50 50

  
......
91 91
import com.iver.utiles.swing.threads.CancellableProgressTask;
92 92

  
93 93
/**
94
 * 
94
 *
95 95
 * This class represents a Topology, as a group of vectorial layers
96 96
 * and topology rules that checks geometries and their spatial relationships of
97 97
 * these layers.
98
 * 
98
 *
99 99
 * It extends FLayers to reuse all already existent code related with
100 100
 * groups of layers (TOC related, etc.)
101
 * 
101
 *
102 102
 * TODO Study if we must syncronize writing methods (validate, markAsException, addError,
103 103
 * ruleId++, etc)
104 104
 *
......
109 109
public class Topology extends FLayers implements ITopologyStatus, ITopologyErrorContainer, Cloneable {
110 110

  
111 111
	private static Logger logger = Logger.getLogger(Topology.class.getName());
112
		
113
	private final static ImageIcon NOT_VALIDATED_TOC_ICON = 
112

  
113
	private final static ImageIcon NOT_VALIDATED_TOC_ICON =
114 114
		new ImageIcon(Topology.class.getResource("images/topoicon.png"));
115
	
116
	private final static ImageIcon VALIDATED_TOC_ICON = 
115

  
116
	private final static ImageIcon VALIDATED_TOC_ICON =
117 117
		new ImageIcon(Topology.class.getResource("images/topoicon_validated.png"));
118
	
119
	private final static ImageIcon VALIDATED_WITH_ERRORS_TOC_ICON = 
118

  
119
	private final static ImageIcon VALIDATED_WITH_ERRORS_TOC_ICON =
120 120
		new ImageIcon(Topology.class.getResource("images/topoicon_validated_with_errors.png"));
121
	 
122
	private final static ImageIcon EMPTY_TOC_ICON = 
121

  
122
	private final static ImageIcon EMPTY_TOC_ICON =
123 123
		new ImageIcon(Topology.class.getResource("images/topoicon_empty.png"));
124 124

  
125
	private final static ImageIcon VALIDATED_WITH_DIRTY_ZONES_TOC_ICON = 
125
	private final static ImageIcon VALIDATED_WITH_DIRTY_ZONES_TOC_ICON =
126 126
		new ImageIcon(Topology.class.getResource("images/topoicon_validated_with_dirty_zones.png"));
127
	
128
	private final static ImageIcon VALIDATING_TOC_ICON = 
127

  
128
	private final static ImageIcon VALIDATING_TOC_ICON =
129 129
		new ImageIcon(Topology.class.getResource("images/topoicon_validating.png"));
130
	
130

  
131 131
	private ImageIcon statusIcon = EMPTY_TOC_ICON;
132
	
132

  
133 133
	/**
134 134
	 * topology name
135 135
	 */
......
137 137
	/**
138 138
	 * cluster tolerance of the topology
139 139
	 */
140
	
140

  
141 141
	private double clusterTolerance;
142 142

  
143 143
	/**
......
145 145
	 */
146 146
	private byte status = EMPTY;
147 147

  
148
	
148

  
149 149
	/**
150 150
	 * If during validation process a topoly exceeds this parameters, validation
151 151
	 * will be stopped.
152
	 * 
152
	 *
153 153
	 */
154 154
	private int maxNumberOfErrors = -1;
155 155

  
156
	
156

  
157 157
	/**
158 158
	 * topology rules of the topology
159 159
	 */
160 160
	private List<ITopologyRule> rules;
161 161

  
162
	
162

  
163 163
	/**
164 164
	 * Each layer of a topology must have a cluster tolerance rule
165 165
	 */
166 166
	private List<MustBeLargerThanClusterTolerance> clusterToleranceRules;
167 167

  
168
	
168

  
169 169
	/**
170 170
	 * Regions of the topology to be validated
171 171
	 */
......
176 176
	 * responsability.
177 177
	 */
178 178
	private ITopologyErrorContainer errorContainer;
179
	
179

  
180 180
	/**
181 181
	 * Collection of error layers created from topology errors in topology
182 182
	 * error container.
183 183
	 */
184 184
	private FLayer errorLayer;
185
	
185

  
186 186
	/**
187 187
	 * Registered class to listen for change status events.
188 188
	 */
189 189
	private List<ITopologyStatusListener> statusListeners;
190
	
191
	
190

  
191

  
192 192
	/**
193 193
	 * Map that relates a FLyrVect of the Topology with its rank (weight when we
194 194
	 * are going to snap many coordinates)
195 195
	 */
196 196
	private Map<FLyrVect, XYZLayerRank> layerRanks;
197
	
197

  
198 198
	/**
199 199
	 * Numerical identifier for rules of a topology
200 200
	 */
201 201
	private int ruleId = 0;
202
	
202

  
203 203
	/**
204 204
	 * Interface for all of these classes interested in listening topology change status
205 205
	 * events.
......
209 209
	public interface ITopologyStatusListener{
210 210
		public void statusChange(TopologyStatusEvent event);
211 211
	}
212
	
212

  
213 213
	/**
214 214
	 * Topology change status event. It contains old and new topology status.
215 215
	 * @author Alvaro Zabala
......
219 219
		int newStatus;
220 220
		int prevStatus;
221 221
	}
222
	
222

  
223 223
	/**
224 224
	 * Default constructor for a topology as a FLayers
225
	 * 
225
	 *
226 226
	 * @param fmap
227 227
	 * @param parent
228 228
	 */
229
	public Topology(MapContext fmap, 
230
					FLayers parent, 
231
					double clusterTolerance, 
229
	public Topology(MapContext fmap,
230
					FLayers parent,
231
					double clusterTolerance,
232 232
					int numberOfErrors,
233 233
					ITopologyErrorContainer errorContainer) {
234
		super(fmap, parent);
234
		super.setMapContext(fmap);
235
		super.setParentLayer(parent);
235 236
		this.clusterTolerance = clusterTolerance;
236 237
		this.maxNumberOfErrors = numberOfErrors;
237 238
		this.errorContainer = errorContainer;
238 239
		this.errorContainer.setTopology(this);
239
		
240

  
240 241
		rules = new ArrayList<ITopologyRule>();
241 242
		clusterToleranceRules = new ArrayList<MustBeLargerThanClusterTolerance>();
242 243
		dirtyZones = new ArrayList<Rectangle2D>();
243 244
		layerRanks = new HashMap<FLyrVect, XYZLayerRank>();
244
		
245

  
245 246
		statusListeners = new ArrayList<ITopologyStatusListener>();
246 247
		//This listener updates the icon status returneb by this kind of layer
247 248
		statusListeners.add(new ITopologyStatusListener(){
......
250 251
				case ITopologyStatus.VALIDATED:
251 252
					statusIcon = VALIDATED_TOC_ICON;
252 253
					break;
253
					
254

  
254 255
				case ITopologyStatus.NOT_VALIDATED:
255 256
					statusIcon = NOT_VALIDATED_TOC_ICON;
256 257
					break;
257
					
258

  
258 259
				case ITopologyStatus.VALIDATED_WITH_DIRTY_ZONES:
259 260
					statusIcon = VALIDATED_WITH_DIRTY_ZONES_TOC_ICON;
260 261
					break;
261
					
262

  
262 263
				case ITopologyStatus.VALIDATED_WITH_ERRORS:
263 264
					statusIcon = VALIDATED_WITH_ERRORS_TOC_ICON;
264 265
					break;
265
					
266

  
266 267
				case ITopologyStatus.VALIDATING:
267 268
					statusIcon = VALIDATING_TOC_ICON;
268 269
					break;
269 270
				}
270 271
			}});
271 272
	}
272
	
273

  
273 274
	public Topology(MapContext mapContext, FLayers layers){
274 275
		this(mapContext, layers, 0d, 1000, new SimpleTopologyErrorContainer());
275 276
	}
276
	
277
	
277

  
278

  
278 279
	public void addStatusListener(ITopologyStatusListener statusListener){
279 280
		this.statusListeners.add(statusListener);
280 281
	}
281
	
282

  
282 283
	/**
283 284
	 * Creates a topology from its XML representation
284 285
	 * @param xmlEntity
......
287 288
	public static Topology createFromXML(MapContext mapContext, XMLEntity xmlEntity){
288 289
		FLayers rootLyr = mapContext.getLayers();
289 290
		Topology solution = new Topology(mapContext, rootLyr);
290
		
291

  
291 292
		try {
292 293
			solution.setXMLEntity(xmlEntity);
293 294
			if(solution.getErrorContainer() == null){
......
298 299
		}
299 300
		return solution;
300 301
	}
301
	
302

  
302 303
	public ImageIcon getTocImageIcon() {
303 304
		return statusIcon;
304 305
	}
305
	
306

  
306 307
	public Image getTocStatusImage() {
307 308
		return statusIcon.getImage();
308 309
	}
309 310

  
310 311
	/**
311 312
	 * Changes the cluster tolerance of the topology
312
	 * 
313
	 * 
313
	 *
314
	 *
314 315
	 * This operation resets the status of the topology (it clears
315 316
	 * errors and dirty zones)
316
	 * 
317
	 *
317 318
	 * @param clusterTolerance
318 319
	 */
319 320
	public void setClusterTolerance(double clusterTolerance) {
......
326 327
			MustBeLargerThanClusterTolerance rule = rulesIt.next();
327 328
			rule.setClusterTolerance(clusterTolerance);
328 329
		}
329
		
330

  
330 331
	}
331 332

  
332 333
	public double getClusterTolerance() {
333 334
		return clusterTolerance;
334 335
	}
335
	
336

  
336 337
	public void resetStatus(){
337 338
		setStatus(NOT_VALIDATED);
338 339
		this.clear();
339 340
		this.dirtyZones.clear();
340
		
341

  
341 342
	}
342 343

  
343 344
	/**
344 345
	 * Adds a new topology rule to the topology.
345
	 * 
346
	 *
346 347
	 * The layers referenced by the rule must exist in the topology.
347
	 * 
348
	 *
348 349
	 * The state of the topology changes to "NON_VALIDATED", and a new dirty zone
349 350
	 * is added for the scope of the new rule (envelope of one or two layers).
350
	 * 
351
	 * 
351
	 *
352
	 *
352 353
	 * @throws TopologyRuleDefinitionException
353 354
	 */
354 355
	public void addRule(ITopologyRule rule) throws RuleNotAllowedException,
......
356 357

  
357 358
		if(status == VALIDATING)
358 359
			throw new RuleNotAllowedException("No se puede a?adir una regla si la topologia est? siendo validada");
359
		
360
		
360

  
361

  
361 362
		Rectangle2D ruleScope = null;
362 363
		try {
363 364
			if (rule instanceof IOneLyrRule) {
......
384 385
			e.printStackTrace();
385 386
			throw new TopologyRuleDefinitionException(e);
386 387
		}
387
		
388

  
388 389
		// before to add the rule we check if it verifies preconditions
389 390
		rule.checkPreconditions();
390 391
		rule.setTopology(this);
391 392
		rules.add(rule);
392
		
393

  
393 394
//   Si se a?ade una nueva regla, no es posible conservar los errores
394 395
//   y las zonas sucias previas
395 396
//		if(status == EMPTY)
......
405 406
		rule.setTopologyErrorContainer(this);
406 407
		rule.setId(this.ruleId++);
407 408
	}
408
	
409
	
410
	
411 409

  
410

  
411

  
412

  
412 413
	/*
413 414
	 * Overwrited implementations of FLayers methods
414 415
	 */
415
	
416

  
416 417
	public void addLayer(FLayer layer) {
417 418
		addLayer(layers.size(), layer);
418 419
	}
......
423 424
					"Intentando a?adir capa no vectorial a una topologia");
424 425
		super.addLayer(pos, layer);
425 426
		setRank((FLyrVect) layer, 1, 1);
426
		
427

  
427 428
		int shapeType = -1;
428 429
		try {
429 430
			shapeType = ((FLyrVect)layer).getShapeType();
......
433 434
			e.printStackTrace();
434 435
			throw new WrongLyrForTopologyException("Error al intentar verificar el tipo de geometria de la capa", e);
435 436
		}
436
		
437
		
438
		MustBeLargerThanClusterTolerance rule = new 
437

  
438

  
439
		MustBeLargerThanClusterTolerance rule = new
439 440
			MustBeLargerThanClusterTolerance(this, (FLyrVect) layer, clusterTolerance);
440 441
		rule.setId(this.ruleId++);
441 442
		Rectangle2D ruleScope;
......
443 444
			ruleScope = layer.getFullExtent();
444 445
//		 before to add the rule we check if it verifies preconditions
445 446
			rule.checkPreconditions();
446
			
447

  
447 448
			if(status == EMPTY)
448 449
				setStatus(NOT_VALIDATED);
449 450
			else if(status == VALIDATED ){
......
457 458
			}
458 459
			rule.setTopologyErrorContainer(this);
459 460
			clusterToleranceRules.add(rule);
460
			
461

  
461 462
			//finally, we connect edition with topology
462 463
			layer.addLayerListener(new LayerListener(){
463 464

  
......
466 467

  
467 468
				public void editionChanged(LayerEvent e) {
468 469
					FLayer editionLyr = e.getSource();
469
					
470

  
470 471
					if (editionLyr instanceof FLyrVect){
471
						
472

  
472 473
						final ArrayList<Rectangle2D> dirtyZones = new ArrayList<Rectangle2D>();
473
						
474

  
474 475
						FLyrVect fLyrVect = (FLyrVect)editionLyr;
475
						
476

  
476 477
						ReadableVectorial rv = fLyrVect.getSource();
477 478
						if(! (rv instanceof VectorialEditableAdapter))
478 479
							return;
479 480
						final VectorialEditableAdapter vea =
480 481
							(VectorialEditableAdapter)rv;
481
						
482

  
482 483
						vea.addEditionListener(new IEditionListener(){
483 484

  
484 485
							public void afterFieldEditEvent(
......
492 493
								if(e.getChangeType() == EditionEvent.ALPHANUMERIC)
493 494
									return;
494 495
								int numRow = (int) e.getNumRow();
495
								
496

  
496 497
								IGeometry geom;
497 498
								try {
498 499
									geom = vea.getShape(numRow);
......
528 529

  
529 530
				public void visibilityChanged(LayerEvent e) {
530 531
				}});
531
			
532
			
532

  
533

  
533 534
		} catch (ExpansionFileReadException e) {
534 535
			e.printStackTrace();
535 536
			throw new WrongLyrForTopologyException("No es posible acceder all FullExtent de la capa", e);
......
544 545

  
545 546
	/**
546 547
	 * Sets the rank/importance of a layer in xy and z planes.
547
	 * 
548
	 *
548 549
	 * @param lyr layer
549
	 * 
550
	 *
550 551
	 * @param xyRank importance of this layer coordinates in xy plane
551
	 * 
552
	 *
552 553
	 * @param zRank importante of this layer coordinates in z plane
553 554
	 */
554 555
	public void setRank(FLyrVect lyr, int xyRank, int zRank) {
555 556
		XYZLayerRank rank = new XYZLayerRank(lyr.getName(), xyRank, zRank);
556 557
		layerRanks.put(lyr, rank);
557 558
	}
558
	
559
	
559

  
560

  
560 561
	public XYZLayerRank getRank(FLyrVect lyr){
561 562
		return layerRanks.get(lyr);
562 563
	}
......
570 571
		this.addLayer(layer);
571 572
		setRank(layer, xyRank, zRank);
572 573
	}
573
	
574
	
574

  
575

  
575 576
	/**
576 577
	 * Remove a layer from a topology.
577
	 * 
578
	 *
578 579
	 * This task is more complex than removing a layer from a LayerCollection:
579 580
	 * -must remove all rules which references to this layer.
580 581
	 * -must recompute status and dirty zones.
581 582
	 * etc.
582
	 * 
583
	 *
583 584
	 * TODO Implement remove layer as a geoprocess.
584
	 * 
585
	 *
585 586
	 */
586 587
	public void removeLayer(FLayer lyr) throws CancelationException {
587 588
		callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(lyr));
588
		
589

  
589 590
		//remove cluster rules related with the layer
590 591
		Iterator<MustBeLargerThanClusterTolerance> clusterRulesIt = clusterToleranceRules.iterator();
591 592
		while(clusterRulesIt.hasNext()){
......
594 595
				clusterRulesIt.remove();
595 596
			}
596 597
		}//while
597
		
598

  
598 599
		//Remove normal rules related with the layer
599 600
		Iterator<ITopologyRule> rulesIt = this.rules.iterator();
600 601
		while(rulesIt.hasNext()){
......
606 607
					continue;
607 608
				}
608 609
			}
609
			
610

  
610 611
			if(rule instanceof ITwoLyrRule){
611 612
				ITwoLyrRule twoLyrRule = (ITwoLyrRule) rule;
612 613
				if(twoLyrRule.getOriginLyr().equals(lyr)){
......
614 615
				}
615 616
			}
616 617
		}//while
617
		
618

  
618 619
		this.errorContainer.removeErrorsByLayer((FLyrVect) lyr);
619
		this.layerRanks.remove(lyr);		
620
		this.layerRanks.remove(lyr);
620 621
		this.updateDirtyZones();
621 622
		callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(lyr));
622 623
	}
623
	
624

  
624 625
	public void removeLayer(int idLyr){
625 626
		FLayer lyr = (FLayer) layers.get(idLyr);
626 627
		removeLayer(lyr);
627 628
	}
628
	
629

  
629 630
	public void removeRule(ITopologyRule rule){
630 631
		if(rules.contains(rule)){
631 632
			rules.remove(rule);
......
633 634
			clusterToleranceRules.remove(rule);
634 635
		}
635 636
		this.errorContainer.removeErrorsByRule(rule.getName());
636
		
637

  
637 638
		this.updateDirtyZones();
638 639
	}
639
	
640
	
641
	
640

  
641

  
642

  
642 643
	private void updateDirtyZones() {
643 644
//		this.dirtyZones.clear(); //FIXME REVISAR SI ES NECESARIO BORRAR LAS ZONAS SUCIAS
644 645
		int errorNum = errorContainer.getNumberOfErrors();
......
651 652

  
652 653
	/**
653 654
	 * Ranks (in xy plane and z plane) for layers of the topology.
654
	 * 
655
	 *
655 656
	 * The rank of layer marks its weight for computing weihgted average
656 657
	 * coordinates.
657
	 * 
658
	 *
658 659
	 * @author azabala
659
	 * 
660
	 *
660 661
	 */
661 662
	class XYZLayerRank implements IPersistence {
662 663
		int xyRank;
......
668 669
			this.xyRank = xyRank;
669 670
			this.zRank = zRank;
670 671
		}
671
		
672

  
672 673
		XYZLayerRank(){}
673 674

  
674 675
		public String getClassName() {
......
686 687
		public void setXMLEntity(XMLEntity xml) {
687 688
			if(xml.contains("layerName"))
688 689
				layerName = xml.getStringProperty("layerName");
689
			
690

  
690 691
			if(xml.contains("xyRank"))
691 692
				xyRank = xml.getIntProperty("xyRank");
692
			
693

  
693 694
			if(xml.contains("zRank"))
694 695
				zRank = xml.getIntProperty("zRank");
695
			
696

  
696 697
		}
697 698
	}
698 699

  
......
701 702
		newStatusEvent.prevStatus = this.status;
702 703
		newStatusEvent.newStatus = newStatus;
703 704
		this.status = newStatus;
704
		
705

  
705 706
		fireStatusChange(newStatusEvent);
706 707
	}
707 708

  
708 709
	public byte getStatus() {
709 710
		return status;
710 711
	}
711
	
712

  
712 713
	public List<ITopologyRule> getAllRules(){
713 714
		List<ITopologyRule> solution = new ArrayList<ITopologyRule>();
714 715
		solution.addAll(this.rules);
......
740 741
				return;
741 742
			}
742 743
		}// while
743
		
744

  
744 745
		if(status == VALIDATED)
745 746
			setStatus(VALIDATED_WITH_DIRTY_ZONES);
746
		
747

  
747 748
		// at this point, we add the new dirty zone
748 749
		dirtyZones.add(newDirtyZone);
749 750
	}
750
	
751
	
751

  
752

  
752 753
	public void removeDirtyZone(Rectangle2D newDirtyZone) {
753 754
		if(status == NOT_VALIDATED)
754 755
			return;//maybe we must launch an inconsistent status exception
......
764 765
		// at this point, we add the new dirty zone
765 766
		dirtyZones.remove(newDirtyZone);
766 767
	}
767
	
768 768

  
769

  
769 770
	public Rectangle2D getDirtyZone(int i) {
770 771
		return dirtyZones.get(i);
771 772
	}
772
	
773

  
773 774
	public int getNumberOfDirtyZones(){
774 775
		return dirtyZones.size();
775 776
	}
776
	
777
	
777

  
778

  
778 779
	public void validate(){
779 780
		validate(null);
780 781
	}
781
	
782

  
782 783
	/**
783 784
	 * Validates the topology: it validates each topology rule for the given
784 785
	 * dirty zones. After the end of the process,
785 786
	 */
786 787
	public void validate(CancellableProgressTask progressMonitor) {
787
		
788

  
788 789
		if(progressMonitor != null){
789 790
			progressMonitor.setInitialStep(0);
790 791
			int numOfSteps = rules.size() + clusterToleranceRules.size();
......
793 794
			progressMonitor.setNote(Messages.getText("Validating_a_topology"));
794 795
			progressMonitor.setStatusMessage(Messages.getText(rules.get(0).getName()));
795 796
		}
796
		
797
		
797

  
798

  
798 799
		if (this.status == EMPTY) {
799 800
			//TODO Maybe we must do progressMonitor.setFinished(true)
800 801
			//or throw an exception
801 802
			return;
802 803
		} else if (this.status == VALIDATED) {
803 804
			return;
804
		} 
805
		
805
		}
806

  
806 807
		else if (this.status == NOT_VALIDATED){
807 808
			setStatus(VALIDATING);
808
			
809
			
810
			//we make a local copy of dirty zones to avoid to use dirty zones created in 
809

  
810

  
811
			//we make a local copy of dirty zones to avoid to use dirty zones created in
811 812
			//the current validation.
812 813
			ArrayList<Rectangle2D> dirtyZonesCopy = new ArrayList<Rectangle2D>();
813 814
			Collections.copy(dirtyZonesCopy, this.dirtyZones);
814
			Iterator<MustBeLargerThanClusterTolerance> it = 
815
			Iterator<MustBeLargerThanClusterTolerance> it =
815 816
				clusterToleranceRules.iterator();
816 817
			while(it.hasNext()){
817 818
				MustBeLargerThanClusterTolerance rule = it.next();
......
824 825
   						Messages.getText(rule.getName()));
825 826
					progressMonitor.reportStep();
826 827
   				}
827
				
828

  
828 829
				if(getNumberOfErrors() >= this.maxNumberOfErrors){
829 830
					if(progressMonitor != null)
830 831
						progressMonitor.setCanceled(true);
831 832
					return;
832 833
				}
833
				
834

  
834 835
				rule.checkRule(progressMonitor);
835 836
			}
836
			
837

  
837 838
			Iterator<ITopologyRule> rulesIt = this.rules.iterator();
838 839
			while (rulesIt.hasNext()) {
839 840
				ITopologyRule rule = rulesIt.next();
840
				
841

  
841 842
				if(progressMonitor != null){
842 843
					if(progressMonitor.isCanceled()/*|| progressMonitor.isFinished()*/){
843 844
						resetStatus();
......
847 848
   						Messages.getText(rule.getName()));
848 849
					progressMonitor.reportStep();
849 850
   				}
850
				
851

  
851 852
				if(getNumberOfErrors() >= this.maxNumberOfErrors){
852 853
					if(progressMonitor != null)
853 854
						progressMonitor.setCanceled(true);
854 855
					return;
855 856
				}
856
				
857

  
857 858
				if(dirtyZonesCopy.size() == 0){
858 859
					rule.checkRule(progressMonitor);
859 860
				}else{
860 861
					//A topology is NON_VALIDATED with dirty zones when
861 862
					//it has VALIDATED status and we add a new rule.
862
					
863

  
863 864
					//TODO Check to add a new rule to a topology
864 865
					//with VALIDATED_WITH_ERROR status
865 866
					Iterator<Rectangle2D> dirtyZonesIt = dirtyZonesCopy.iterator();
......
873 874
				setStatus(VALIDATED_WITH_ERRORS);
874 875
				addErrorLyr();
875 876
			}else
876
				setStatus(VALIDATED);	
877
				setStatus(VALIDATED);
877 878
		}
878
		else if (this.status == VALIDATED_WITH_ERRORS || 
879
		else if (this.status == VALIDATED_WITH_ERRORS ||
879 880
				this.status == ITopologyStatus.VALIDATED_WITH_DIRTY_ZONES) {
880 881
			setStatus(VALIDATING);
881 882
			// this topology must have at least one dirty zone
......
888 889
			Iterator<Rectangle2D> dirtyZonesIt = this.dirtyZones.iterator();
889 890
			while (dirtyZonesIt.hasNext()) {
890 891
				Rectangle2D dirtyZone = dirtyZonesIt.next();
891
				
892

  
892 893
				Iterator<MustBeLargerThanClusterTolerance> it = this.clusterToleranceRules.iterator();
893 894
				while(it.hasNext()){
894 895
					MustBeLargerThanClusterTolerance rule = it.next();
......
901 902
	   						Messages.getText(rule.getName()));
902 903
						progressMonitor.reportStep();
903 904
	   				}
904
					
905

  
905 906
					if(getNumberOfErrors() >= this.maxNumberOfErrors){
906 907
						if(progressMonitor != null)
907 908
							progressMonitor.setCanceled(true);
908 909
						return;
909 910
					}
910
					
911

  
911 912
					rule.checkRule(dirtyZone);
912 913
				}
913
				
914

  
914 915
				Iterator<ITopologyRule> rulesIt = this.rules.iterator();
915 916
				while (rulesIt.hasNext()) {
916 917
					ITopologyRule rule = rulesIt.next();
......
923 924
	   						Messages.getText(rule.getName()));
924 925
						progressMonitor.reportStep();
925 926
	   				}
926
					
927

  
927 928
					if(getNumberOfErrors() >= this.maxNumberOfErrors){
928 929
						if(progressMonitor != null)
929 930
							progressMonitor.setCanceled(true);
......
931 932
					}
932 933
					rule.checkRule(dirtyZone);
933 934
				}//while
934
				
935
				
935

  
936

  
936 937
			}//while
937 938
			if(this.errorContainer.getNumberOfErrors() > 0){
938 939
				setStatus(VALIDATED_WITH_ERRORS);
......
942 943
		}//if
943 944
	}
944 945

  
945
	private void addErrorLyr() {	
946
	private void addErrorLyr() {
946 947
		IProjection proj = this.getProjection();
947 948
		int idx = 0;
948 949
		while(proj == null && idx < this.getLayerCount()){
......
955 956
	public int getLayerCount() {
956 957
		return super.getLayersCount();
957 958
	}
958
	
959

  
959 960
	public List getLayers(){
960 961
		return this.layers;
961 962
	}
......
971 972
	public ITopologyRule getRule(int ruleIndex) {
972 973
		return rules.get(ruleIndex);
973 974
	}
974
	
975

  
975 976
	public ITopologyRule getRuleById(int ruleId){
976 977
		for(int i = 0; i < rules.size(); i++){
977 978
			ITopologyRule rule = rules.get(i);
......
979 980
				return rule;
980 981
			}//if
981 982
		}//for
982
		
983

  
983 984
		for(int i = 0; i < clusterToleranceRules.size(); i++){
984 985
			MustBeLargerThanClusterTolerance rule = clusterToleranceRules.get(i);
985 986
			if(rule.getId() == ruleId){
......
988 989
		}
989 990
		return null;
990 991
	}
991
	
992

  
992 993
	/**
993 994
	 * Looks for all rules which has at least one reference to the given layer
994 995
	 * (as origin or destination layer in the rule)
995
	 * 
996
	 *
996 997
	 * @param lyr
997 998
	 * @return
998 999
	 */
......
1010 1011
					continue;//dont need to check for destination layer
1011 1012
				}
1012 1013
			}//if
1013
			
1014

  
1014 1015
			if(rule instanceof ITwoLyrRule){
1015 1016
				ITwoLyrRule twoLyrRule = (ITwoLyrRule) rule;
1016 1017
				FLyrVect destinationLyr = twoLyrRule.getDestinationLyr();
......
1018 1019
					solution.add(rule);
1019 1020
				}
1020 1021
			}
1021
			
1022

  
1022 1023
		}//while
1023
		
1024

  
1024 1025
		Iterator<MustBeLargerThanClusterTolerance> clusterIt = clusterToleranceRules.iterator();
1025 1026
		while(clusterIt.hasNext()){
1026 1027
			MustBeLargerThanClusterTolerance rule = clusterIt.next();
......
1033 1034
		}
1034 1035
		return solution;
1035 1036
	}
1036
	
1037

  
1037 1038
	/**
1038 1039
	 * Returns if a specified rectangle touch one of the existing dirty zones.
1039 1040
	 * If not, probably is needed to add to the dirty zones collection. If true,
......
1051 1052

  
1052 1053
	/**
1053 1054
	 * Modify the dirty zone of the specified index
1054
	 * 
1055
	 *
1055 1056
	 * TODO Make thread safe ?
1056 1057
	 */
1057 1058
	public void updateDirtyZone(int dirtyZoneIndex, Rectangle2D dirtyZone) {
......
1078 1079
	}
1079 1080

  
1080 1081
	/**
1081
	 * marks topologyErrors as an exception (and removes its bounds of the 
1082
	 * marks topologyErrors as an exception (and removes its bounds of the
1082 1083
	 * dirty zones list)
1083 1084
	 * @param topologyError error to mark as exceptions
1084 1085
	 */
......
1086 1087
		errorContainer.markAsTopologyException(topologyError);
1087 1088
		Rectangle2D rect = topologyError.getGeometry().getBounds2D();
1088 1089
		removeDirtyZone(rect);
1089
		
1090

  
1090 1091
		if(status == VALIDATED_WITH_DIRTY_ZONES){
1091 1092
			if(dirtyZones.size() == 0)
1092 1093
				setStatus(VALIDATED);
......
1095 1096
				setStatus(VALIDATED);
1096 1097
		}
1097 1098
	}
1098
	
1099

  
1099 1100
	public void demoteToError(TopologyError topologyError) {
1100 1101
		errorContainer.demoteToError(topologyError);
1101 1102
		Rectangle2D rect = topologyError.getGeometry().getBounds2D();
......
1104 1105
			setStatus(VALIDATED_WITH_ERRORS);
1105 1106
	}
1106 1107

  
1107
	
1108
	
1108

  
1109

  
1109 1110
	public List<TopologyError> getTopologyErrorsByLyr(FLyrVect layer,
1110
													IProjection desiredProjection, 
1111
													IProjection desiredProjection,
1111 1112
													boolean includeExceptions) {
1112
		
1113
		return errorContainer.getTopologyErrorsByLyr(layer, 
1114
										 desiredProjection,  
1113

  
1114
		return errorContainer.getTopologyErrorsByLyr(layer,
1115
										 desiredProjection,
1115 1116
										 includeExceptions);
1116 1117
	}
1117 1118

  
1118 1119
	public List<TopologyError> getTopologyErrorsByRule(String ruleName,
1119 1120
			IProjection desiredProjection, boolean includeExceptions) {
1120
		
1121
		return errorContainer.getTopologyErrorsByRule(ruleName, 
1122
												desiredProjection, 
1121

  
1122
		return errorContainer.getTopologyErrorsByRule(ruleName,
1123
												desiredProjection,
1123 1124
												includeExceptions);
1124 1125
	}
1125
	
1126 1126

  
1127

  
1127 1128
	public List<TopologyError> getTopologyErrorsByShapeType(int shapeType,
1128 1129
			IProjection desiredProjection, boolean includeExceptions) {
1129
		return errorContainer.getTopologyErrorsByShapeType(shapeType, 
1130
													desiredProjection, 
1131
													includeExceptions);	
1130
		return errorContainer.getTopologyErrorsByShapeType(shapeType,
1131
													desiredProjection,
1132
													includeExceptions);
1132 1133
	}
1133 1134

  
1134
	
1135

  
1135 1136
	/**
1136 1137
	 * Get TopologyError filtered byte shapeType, sourte layer of the rule which
1137 1138
	 * was violtated by this error.
......
1141 1142
			boolean includeExceptions) {
1142 1143

  
1143 1144
		return errorContainer.getTopologyErrors(ruleName,
1144
												shapeType, 
1145
												sourceLayer, 
1146
												desiredProjection, 
1145
												shapeType,
1146
												sourceLayer,
1147
												desiredProjection,
1147 1148
												includeExceptions);
1148 1149
	}
1149 1150

  
1150 1151
	/**
1151 1152
	 * Return an unique identifier for the error saved in this
1152 1153
	 * TopologyErrorContainer.
1153
	 * 
1154
	 *
1154 1155
	 * Until a new error would be added to this error container, it will
1155 1156
	 * return always the same error fid.
1156 1157
	 */
......
1165 1166
	public TopologyError getTopologyError(int index) {
1166 1167
		return errorContainer.getTopologyError(index);
1167 1168
	}
1168
	
1169

  
1169 1170
	public void clear() {
1170 1171
		errorContainer.clear();
1171 1172
	}
1172 1173

  
1173 1174
	public XMLEntity getXMLEntity() throws XMLException{
1174
		
1175

  
1175 1176
		//Topology is a subclass of FLayers, so the call to super
1176 1177
		//allows to persist layer status, toc information and layers
1177 1178
		XMLEntity xml = super.getXMLEntity();
1178
		
1179

  
1179 1180
		//Si no ponemos esto className ser? FLayerDefault, no??
1180 1181
		xml.putProperty("className", this.getClass().getName());
1181 1182
		xml.putProperty("name", name);
1182 1183
		xml.putProperty("clusterTolerance", clusterTolerance);
1183 1184
		xml.putProperty("status", status);
1184 1185
		xml.putProperty("maxNumberOfErrors", maxNumberOfErrors);
1185
		
1186

  
1186 1187
		int numberOfTopologyRules = rules.size();
1187 1188
		xml.putProperty("numberOfTopologyRules", numberOfTopologyRules);
1188 1189
		for(int i = 0; i < numberOfTopologyRules; i++){
1189 1190
			ITopologyRule rule = rules.get(i);
1190 1191
			xml.addChild(rule.getXMLEntity());
1191 1192
		}
1192
		
1193
		
1193

  
1194

  
1194 1195
		int numberOfClusterRules = clusterToleranceRules.size();
1195 1196
		xml.putProperty("numberOfClusterRules", numberOfClusterRules);
1196 1197
		for(int i = 0; i < numberOfClusterRules; i++){
1197 1198
			MustBeLargerThanClusterTolerance rule = clusterToleranceRules.get(i);
1198 1199
			xml.addChild(rule.getXMLEntity());
1199 1200
		}
1200
		
1201

  
1201 1202
		int numberOfDirtyZones = dirtyZones.size();
1202 1203
		xml.putProperty("numberOfDirtyZones", numberOfDirtyZones);
1203 1204
		for(int i = 0; i < numberOfDirtyZones; i++){
......
1207 1208
				dirtyZoneXML.putProperty("extent" + i + "X", rect.getX());
1208 1209
				dirtyZoneXML.putProperty("extent" + i + "Y", rect.getY());
1209 1210
				dirtyZoneXML.putProperty("extent" + i + "W", rect.getWidth());
1210
				dirtyZoneXML.putProperty("extent" + i + "H", rect.getHeight());	
1211
				
1211
				dirtyZoneXML.putProperty("extent" + i + "H", rect.getHeight());
1212

  
1212 1213
				xml.addChild(dirtyZoneXML);
1213 1214
			}//if
1214
			
1215

  
1215 1216
		}//for
1216
		
1217

  
1217 1218
		XMLEntity errorContainerXML = errorContainer.getXMLEntity();
1218 1219
		xml.addChild(errorContainerXML);
1219
		
1220

  
1220 1221
		Collection<XYZLayerRank> ranksVal = layerRanks.values();
1221 1222
		int numberOfRanks = ranksVal.size();
1222 1223
		xml.putProperty("numberOfRanks", numberOfRanks);
......
1228 1229
		}
1229 1230
		return xml;
1230 1231
	}
1231
	
1232 1232

  
1233

  
1233 1234
	public void setXMLEntity(XMLEntity xml) throws XMLException {
1234 1235
		super.setXMLEntity(xml);
1235
		
1236

  
1236 1237
		//FIXME Cambiar el uso de childrenCount por el empleo de propiedades
1237 1238
		int numLayers = this.getLayersCount();
1238 1239
		int numProperties = this.getExtendedProperties().size();
1239
		
1240

  
1240 1241
		int childrenCount = numLayers + numProperties;
1241
		
1242

  
1242 1243
		if(xml.contains("clusterTolerance"))
1243 1244
		{
1244 1245
			this.clusterTolerance = xml.getDoubleProperty("clusterTolerance");
1245 1246
		}
1246
		
1247

  
1247 1248
		if(xml.contains("name"))
1248 1249
		{
1249 1250
			this.name = xml.getStringProperty("name");
1250 1251
		}
1251
		
1252

  
1252 1253
		if(xml.contains("status"))
1253 1254
		{
1254 1255
			this.status = (byte) xml.getIntProperty("status");
1255 1256
		}
1256
		
1257

  
1257 1258
		if(xml.contains("maxNumberOfErrors"))
1258 1259
		{
1259 1260
			this.maxNumberOfErrors =  xml.getIntProperty("maxNumberOfErrors");
1260 1261
		}
1261
		
1262

  
1262 1263
		if(xml.contains("numberOfTopologyRules"))
1263 1264
		{
1264 1265
			int numberOfTopologyRules =   xml.getIntProperty("numberOfTopologyRules");
......
1268 1269
				this.rules.add(rule);
1269 1270
			}
1270 1271
		}
1271
		
1272
		
1272

  
1273

  
1273 1274
		if(xml.contains("numberOfClusterRules")){
1274 1275
			int numberOfClusterRules = xml.getIntProperty("numberOfClusterRules");
1275 1276
			for(int i = 0; i < numberOfClusterRules; i++){
......
1278 1279
				this.clusterToleranceRules.add(rule);
1279 1280
			}
1280 1281
		}
1281
		
1282

  
1282 1283
		if(xml.contains("numberOfDirtyZones")){
1283 1284
			int numberOfDirtyZones = xml.getIntProperty("numberOfDirtyZones");
1284 1285
			for(int i = 0; i < numberOfDirtyZones; i++){
......
1287 1288
				double y = dirtyZoneXml.getDoubleProperty("extent"+i+"Y");
1288 1289
				double w = dirtyZoneXml.getDoubleProperty("extent"+i+"W");
1289 1290
				double h = dirtyZoneXml.getDoubleProperty("extent"+i+"H");
1290
				
1291

  
1291 1292
				Rectangle2D.Double rect = new Rectangle2D.Double(x, y, w, h);
1292 1293
				dirtyZones.add(rect);
1293 1294
			}
1294 1295
		}
1295
		
1296
		
1297
		
1296

  
1297

  
1298

  
1298 1299
		XMLEntity errorContainerXML = xml.getChild(childrenCount++);
1299 1300
		if(errorContainerXML != null)
1300 1301
		{
1301 1302
			this.errorContainer = TopologyPersister.createErrorContainerFromXML(errorContainerXML);
1302 1303
		}
1303
		
1304

  
1304 1305
		if(xml.contains("numberOfRanks")){
1305 1306
			int numberOfRanks = xml.getIntProperty("numberOfRanks");
1306 1307
			for(int i = 0; i < numberOfRanks; i++){
......
1308 1309
				XYZLayerRank rank = new XYZLayerRank();
1309 1310
				rank.setXMLEntity(xmlRank);
1310 1311
			}
1311
		}		
1312
		}
1312 1313
	}
1313 1314

  
1314 1315
	public int getNumberOfExceptions() {
......
1326 1327
	public void setName(String name) {
1327 1328
		this.name = name;
1328 1329
	}
1329
	
1330

  
1330 1331
	public ITopologyErrorContainer getErrorContainer(){
1331 1332
		return this.errorContainer;
1332 1333
	}
1333
	
1334
	
1334

  
1335

  
1335 1336
	public FLayer getErrorLayer(){
1336 1337
		return this.errorLayer;
1337 1338
	}
1338
	
1339

  
1339 1340
	public void setErrorContainer(ITopologyErrorContainer errorContainer){
1340 1341
		this.errorContainer = errorContainer;
1341 1342
		this.errorContainer.setTopology(this);
1342 1343
	}
1343
	
1344

  
1344 1345
	private void fireStatusChange(TopologyStatusEvent event){
1345
		Iterator<ITopologyStatusListener> it = 
1346
		Iterator<ITopologyStatusListener> it =
1346 1347
			this.statusListeners.iterator();
1347 1348
		while(it.hasNext()){
1348 1349
			ITopologyStatusListener listener = it.next();
......
1357 1358
	public void removeErrorsByRule(String ruleName) {
1358 1359
		this.errorContainer.removeErrorsByRule(ruleName);
1359 1360
	}
1360
	
1361

  
1361 1362
	public void setRules(List<ITopologyRule> rules){
1362 1363
		this.rules = rules;
1363 1364
	}
1364
	
1365

  
1365 1366
	public void setDirtyZones(List<Rectangle2D> dirtyZones){
1366 1367
		this.dirtyZones = dirtyZones;
1367 1368
	}
1368
	
1369

  
1369 1370
	public void setStatusListeners(List<ITopologyStatusListener> statusListeners){
1370 1371
		this.statusListeners = statusListeners;
1371 1372
	}
1372
	
1373

  
1373 1374
	public void setLayerRanks(Map<FLyrVect, XYZLayerRank> layerRanks){
1374 1375
		this.layerRanks = layerRanks;
1375 1376
	}
1376
	
1377

  
1377 1378
	public Object clone(){
1378 1379
		Topology newTopology = new Topology(super.getMapContext(), super.getParentLayer());
1379 1380
		newTopology.setName(this.name);
......
1392 1393
		newTopology.setErrorContainer((ITopologyErrorContainer) errorContainer.clone());
1393 1394
		return newTopology;
1394 1395
	}
1395
	
1396

  
1396 1397
	public static void copyProperties(Topology from, Topology to){
1397 1398
		to.setName(from.name);
1398 1399
		to.ruleId = from.ruleId;
......
1403 1404
		to.setErrorContainer(from.errorContainer);
1404 1405
		to.setStatusListeners(from.statusListeners);
1405 1406
		to.setLayerRanks(from.layerRanks);
1406
		
1407

  
1407 1408
		List layers = from.layers;
1408 1409
		to.layers = new ArrayList();
1409 1410
		for(int i = 0; i < layers.size(); i++){
1410 1411
			to.addLayer((FLayer) layers.get(i));
1411 1412
		}
1412
		
1413

  
1413 1414
//		to.layers = from.layers;
1414 1415
	}
1415 1416

  
......
1419 1420

  
1420 1421
	/*
1421 1422
	 * Implementation of ITopologyErrorContanier
1422
	 * 
1423
	 *
1423 1424
	 */
1424 1425
	public Topology getTopology() {
1425 1426
		return this;

Also available in: Unified diff