Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / test / java / org / gvsig / fmap / dal / feature / BaseTestFeatureStore.java @ 42488

History | View | Annotate | Download (51.6 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.fmap.dal.feature;
25

    
26
import java.util.ArrayList;
27
import java.util.Collections;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.Random;
31
import java.util.TreeSet;
32

    
33
import org.gvsig.fmap.dal.DALLocator;
34
import org.gvsig.fmap.dal.DataManager;
35
import org.gvsig.fmap.dal.DataServerExplorer;
36
import org.gvsig.fmap.dal.DataStoreParameters;
37
import org.gvsig.fmap.dal.DataTypes;
38
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
39
import org.gvsig.fmap.dal.exception.DataException;
40
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
41
import org.gvsig.fmap.dal.feature.testmulithread.StoreTask;
42
import org.gvsig.fmap.dal.resource.ResourceManager;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dispose.DisposableIterator;
46
import org.gvsig.tools.dynobject.DynClass;
47
import org.gvsig.tools.dynobject.DynField;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.evaluator.Evaluator;
50
import org.gvsig.tools.evaluator.EvaluatorData;
51
import org.gvsig.tools.evaluator.EvaluatorException;
52
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
53
import org.gvsig.tools.junit.AbstractLibraryAutoInitTestCase;
54
import org.gvsig.tools.persistence.PersistentState;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

    
58
/**
59
 * @author jmvivo
60
 *
61
 */
62
public abstract class BaseTestFeatureStore extends
63
                AbstractLibraryAutoInitTestCase {
64

    
65
        private static Logger logger = null;
66

    
67
        protected DataManager dataManager = null;
68
        private static Random rnd;
69

    
70
        public Logger getLogger() {
71
                if (logger == null) {
72
                        logger = LoggerFactory.getLogger(this.getClass());
73
                }
74
                return logger;
75
        }
76

    
77
        public abstract boolean usesResources();
78

    
79
        public abstract boolean hasExplorer();
80

    
81
        public FeatureQuery getDefaultQuery(FeatureStore store)
82
                        throws DataException {
83
                FeatureQuery query = store.createFeatureQuery();
84
                FeatureAttributeDescriptor[] key = store.getDefaultFeatureType()
85
                                .getPrimaryKey();
86
                for (int i = 0; i < key.length; i++) {
87
                        query.getOrder().add(key[i].getName(), true);
88
                }
89

    
90
                return query;
91
        }
92

    
93

    
94
        public abstract DataStoreParameters getDefaultDataStoreParameters()
95
                        throws DataException;
96

    
97

    
98
        protected void doSetUp() throws Exception {
99
                dataManager = DALLocator.getDataManager();
100
        }
101

    
102

    
103
        //=================================================
104

    
105

    
106
        public void printFeature(Feature feature, int maxColSize) {
107
                printFeature(feature, true, maxColSize);
108
        }
109

    
110

    
111
        public void printFeature(Feature feature, boolean showColName,int maxColSize) {
112
                FeatureType fType = feature.getType();
113
                if (showColName){
114
                        this.printFeatureTypeColNames(feature.getType(), maxColSize);
115
                }
116
                StringBuffer row = new StringBuffer();
117
                Iterator iter = fType.iterator();
118
                FeatureAttributeDescriptor attr;
119

    
120
                while (iter.hasNext()) {
121
                        attr = (FeatureAttributeDescriptor) iter.next();
122
                        row.append(truncateOrFillString(feature.get(attr.getName()),
123
                                        maxColSize + 1, ' '));
124
                }
125
                System.out.println(row.toString());
126
        }
127

    
128
        public String truncateOrFillString(Object str, int max, char fillWith) {
129
                if (str == null) {
130
                        return truncateOrFillString("{null}", max, fillWith);
131
                }
132
                return truncateOrFillString(str.toString(), max, fillWith);
133
        }
134

    
135
        public String truncateOrFillString(String str, int max, char fillWith) {
136
                if (str.length() > max) {
137
                        return str.substring(0, max - 1) + " ";
138
                } else {
139
                        StringBuffer strB = new StringBuffer(str);
140
                        while (strB.length() < max) {
141
                                strB.append(fillWith);
142
                        }
143
                        return strB.toString();
144
                }
145

    
146
        }
147

    
148
        public void printFeatureTypeColNames(FeatureType fType, int maxColSize) {
149
                Iterator iter = fType.iterator();
150
                FeatureAttributeDescriptor attr;
151
                StringBuffer colNames = new StringBuffer();
152
                StringBuffer typeNames = new StringBuffer();
153
                StringBuffer sep = new StringBuffer();
154
                if (maxColSize < 1){
155
                        maxColSize = 15;
156
                }
157
                while (iter.hasNext()) {
158
                        attr = (FeatureAttributeDescriptor) iter.next();
159
                        colNames.append(truncateOrFillString(attr.getName(), maxColSize + 1, ' '));
160
                        typeNames.append(truncateOrFillString("(" + attr.getDataTypeName() + ")",
161
                                        maxColSize + 1, ' '));
162
                        sep.append(truncateOrFillString("", maxColSize, '='));
163
                        sep.append(' ');
164
                }
165

    
166
                System.out.println("");
167
                System.out.println("");
168
                System.out.println(colNames.toString());
169
                System.out.println(typeNames.toString());
170
                System.out.println(sep.toString());
171
        }
172

    
173
        protected FeatureAttributeDescriptor getFirstAttributeOfType(
174
                        FeatureType ftype, int dataType) {
175
                return getFirstAttributeOfType(ftype, new int[] { dataType });
176
        }
177

    
178
        protected FeatureAttributeDescriptor getFirstAttributeOfType(
179
                        FeatureType ftype, int[] dataTypes) {
180
                FeatureAttributeDescriptor attr;
181
                Iterator iter = ftype.iterator();
182
                int i;
183
                while (iter.hasNext()) {
184
                        attr = (FeatureAttributeDescriptor) iter.next();
185
                        for (i = 0; i < dataTypes.length; i++) {
186
                                if (attr.getType() == dataTypes[i]) {
187
                                        return attr;
188
                                }
189
                        }
190
                }
191
                return null;
192
        }
193

    
194
        protected boolean compareDynObject(DynObject obj1, DynObject obj2) {
195
                DynClass dynClass = obj1.getDynClass();
196
                if (!dynClass.getName().equals(obj2.getDynClass().getName())) {
197
                        return false;
198
                }
199

    
200
                DynField[] fields = dynClass.getDeclaredDynFields();
201
                String fieldName;
202
                Object v1, v2;
203
                for (int i = 0; i < fields.length; i++) {
204
                        fieldName = fields[i].getName();
205
                        v1 = obj1.getDynValue(fieldName);
206
                        v2 = obj2.getDynValue(fieldName);
207
                        if (v1 == v2) {
208
                                continue;
209
                        } else if (v1 != null) {
210
                                if (!v1.equals(v2)) {
211
                                        return false;
212
                                }
213
                        }
214
                }
215

    
216
                return true;
217
        }
218

    
219
        protected boolean compareStores(FeatureStore store1, FeatureStore store2)
220
                        throws DataException {
221
                if (store1.getParameters().getClass() != store2.getParameters()
222
                                .getClass()) {
223
                        return false;
224
                }
225
                if (!compareDynObject(store1.getParameters(), store2.getParameters())) {
226
                        return false;
227
                }
228

    
229
                if (store1.getEnvelope() != store2.getEnvelope()) {
230
                        if (store1.getEnvelope() != null) {
231
                                return store1.getEnvelope().equals(store2.getEnvelope());
232
                        } else {
233
                                return false;
234
                        }
235
                }
236

    
237
                if (!store1.getName().equals(store2.getName())) {
238
                        return false;
239
                }
240
                if (((FeatureSelection) store1.getSelection()).getSize() != ((FeatureSelection) store2
241
                                .getSelection()).getSize()) {
242
                        return false;
243
                }
244
                DisposableIterator iter1 = ((FeatureSelection) store1.getSelection())
245
                                .fastIterator();
246
                DisposableIterator iter2 = ((FeatureSelection) store2.getSelection())
247
                                .fastIterator();
248
                if (!compareFeatureIterators(iter1, iter2)) {
249
                        return false;
250
                }
251
                iter1.dispose();
252
                iter2.dispose();
253

    
254
                if (store1.getFeatureTypes().size() != store2.getFeatureTypes().size()) {
255
                        return false;
256
                }
257
                Iterator iterTypes1 = store1.getFeatureTypes().iterator();
258
                Iterator iterTypes2 = store2.getFeatureTypes().iterator();
259
                while (iterTypes1.hasNext()) {
260
                        if (!compareTypes((FeatureType) iterTypes1.next(),
261
                                        (FeatureType) iterTypes2
262
                                        .next())) {
263
                                return false;
264
                        }
265
                }
266
                if (!compareTypes(store1.getDefaultFeatureType(), store2
267
                                .getDefaultFeatureType())) {
268
                        return false;
269
                }
270

    
271
                if (store1.getLocks() != null) {
272
                        if (store1.getLocks().getLocksCount() != store2.getLocks()
273
                                        .getLocksCount()) {
274
                                return false;
275
                        }
276
                        if (!compareFeatureIterators(store1.getLocks().getLocks(), store2
277
                                        .getLocks().getLocks())) {
278
                                return false;
279
                        }
280

    
281
                } else if (store2.getLocks() != null) {
282
                        return false;
283
                }
284

    
285
                return true;
286
        }
287

    
288
        protected boolean compareFeatureIterators(Iterator iter1, Iterator iter2) {
289
                Feature feature;
290
                Feature ffeature;
291
                while (iter1.hasNext()) {
292
                        feature = (Feature) iter1.next();
293
                        ffeature = (Feature) iter2.next();
294
                        if (!this.compareFeatures(feature, ffeature)) {
295
                                return false;
296
                        }
297
                }
298

    
299
                if (!iter2.hasNext()) {
300
                        return true;
301
                } else {
302
                        getLogger().warn("size !=");
303
                        return false;
304
                }
305

    
306
        }
307

    
308
        protected boolean compareFeatureIterators(Iterator iter1, Iterator iter2,
309
                        String[] attrNames) {
310
                Feature feature;
311
                Feature ffeature;
312
                while (iter1.hasNext()) {
313
                        feature = (Feature) iter1.next();
314
                        ffeature = (Feature) iter2.next();
315
                        if (!this.compareFeatures(feature, ffeature, attrNames)) {
316
                                return false;
317
                        }
318
                }
319

    
320
                return !iter2.hasNext();
321

    
322
        }
323

    
324

    
325

    
326
        protected boolean compareTypes(FeatureType ft1, FeatureType ft2) {
327
                if (ft1.size() != ft2.size()) {
328
                        getLogger().warn("size !=");
329
                        return false;
330
                }
331
                if (ft1.getDefaultGeometryAttributeIndex() != ft2
332
                                .getDefaultGeometryAttributeIndex()) {
333
                        getLogger().warn(
334
                                        "getDefaultGeometryAttributeIndex "
335
                                                        + ft1.getDefaultGeometryAttributeIndex() +
336
                                        " !="+ ft2.getDefaultGeometryAttributeIndex());
337
                        return false;
338
                }
339
                if (ft1.getDefaultGeometryAttributeIndex() > -1) {
340
                        if (ft1.getDefaultSRS() != null) {
341
                                if (!ft1.getDefaultSRS().equals(ft2.getDefaultSRS())) {
342
                                        getLogger().warn("getDefaultSRS !=");
343
                                        return false;
344
                                }
345

    
346
                        } else {
347
                                if (ft2.getDefaultSRS() != null) {
348
                                        getLogger().warn("getDefaultSRS !=");
349
                                        return false;
350
                                }
351
                        }
352
                }
353

    
354
                if (ft1.getDefaultGeometryAttributeName() != null) {
355
                        if (!ft1.getDefaultGeometryAttributeName().equals(
356
                                        ft2.getDefaultGeometryAttributeName())) {
357
                                getLogger().warn("getDefaultGeometryAttributeName !=");
358

    
359
                                return false;
360
                        }
361
                } else {
362
                        if (ft2.getDefaultGeometryAttributeName() != null) {
363
                                getLogger().warn("getDefaultGeometryAttributeName !=");
364
                                return false;
365
                        }
366
                }
367

    
368

    
369

    
370
                FeatureAttributeDescriptor attr1, attr2;
371
                for (int i = 0; i < ft1.size(); i++) {
372
                        attr1 = ft1.getAttributeDescriptor(i);
373
                        attr2 = ft2.getAttributeDescriptor(i);
374

    
375
                        if (!compareAttributes(attr1, attr2)) {
376
                                return false;
377
                        }
378

    
379
                }
380
                return true;
381

    
382
        }
383

    
384
        protected boolean compareAttributes(FeatureAttributeDescriptor attr1,
385
                        FeatureAttributeDescriptor attr2) {
386
                if (attr1 == null || attr2 == null) {
387
                        getLogger().warn("attr1 == null || attr2 == null");
388
                        return false;
389
                }
390
                if (!attr1.getName().equals(attr2.getName())) {
391
                        getLogger().warn(
392
                                        "name '" + attr1.getName() + "' != '" + attr2.getName()
393
                                                        + "'");
394
                        return false;
395
                }
396

    
397
                if (attr1.getDataType() != attr2.getDataType()) {
398
                        getLogger().warn(
399
                                        attr1.getName() + ":" +
400
                                        "dataType '" + attr1.getDataTypeName() + "'["
401
                                                        + attr1.getDataType() + "] != '"
402
                                                        + attr2.getDataTypeName() + "'["
403
                                                        + attr2.getDataType() + "]");
404
                        return false;
405
                }
406

    
407
                if (attr1.getSize() != attr2.getSize()) {
408
                        getLogger().warn(
409
                                        attr1.getName() + ":" +
410
                                        "size " + attr1.getSize() + " != " + attr2.getSize());
411
                        return false;
412
                }
413

    
414
                if (attr1.getPrecision() != attr2.getPrecision()) {
415
                        getLogger().warn(
416
                                        attr1.getName() + ":" +
417
                                        "precision " + attr1.getPrecision() + " != "
418
                                                        + attr1.getPrecision());
419
                        return false;
420
                }
421

    
422
                if (attr1.getGeometryType() != attr2.getGeometryType()) {
423
                        getLogger().warn(
424
                                        attr1.getName() + ":" +
425
                                        "GeometryType " + attr1.getGeometryType() + " != "
426
                                                        + attr2.getGeometryType());
427
                        return false;
428
                }
429

    
430
                if (attr1.getGeometrySubType() != attr2.getGeometrySubType()) {
431
                        getLogger().warn(
432
                                        attr1.getName() + ":" +
433
                                        "GeometrySubType " + attr1.getGeometrySubType() + " != "
434
                                                        + attr2.getGeometrySubType());
435

    
436
                        return false;
437
                }
438

    
439
                if (attr1.getSRS() != null) {
440
                        if (!attr1.getSRS().equals(attr2.getSRS())) {
441
                                getLogger().warn(
442
                                                attr1.getName() + ":" +
443
                                                "srs " + attr1.getSRS() + " != " + attr2.getSRS());
444
                                return false;
445
                        }
446
                } else {
447
                        if (attr2.getSRS() != null) {
448
                                getLogger().warn(
449
                                                attr1.getName() + ":" +
450
                                                "srs " + attr1.getSRS() + " != " + attr2.getSRS());
451
                                return false;
452
                        }
453
                }
454

    
455
                return true;
456
        }
457

    
458
        protected boolean compareFeatures(Feature f1, Feature f2,
459
                        String[] attrsNames) {
460
                FeatureAttributeDescriptor attr1;
461
                FeatureAttributeDescriptor attr2;
462
                Object v1, v2;
463
                for (int i = 0; i < attrsNames.length; i++) {
464
                        attr1 = f1.getType().getAttributeDescriptor(attrsNames[i]);
465
                        attr2 = f2.getType().getAttributeDescriptor(attrsNames[i]);
466
                        if (attr1 != attr2) {
467
                                if (!compareAttributes(attr1, attr1)) {
468
                                        return false;
469
                                }
470
                        }
471
                        v1 = f1.get(attr1.getName());
472
                        v2 = f2.get(attr2.getName());
473
                        if (!compareFeatureValue(v1, v2, attr1)) {
474
                                return false;
475
                        }
476
                }
477

    
478
                return true;
479
        }
480

    
481
        protected boolean compareFeatures(Feature f1, Feature f2) {
482
                if (!compareTypes(f1.getType(), f2.getType())) {
483
                        return false;
484
                }
485
                Iterator iter = f1.getType().iterator();
486
                FeatureAttributeDescriptor attr;
487
                Object v1, v2;
488
                while (iter.hasNext()) {
489
                        attr = (FeatureAttributeDescriptor) iter.next();
490
                        v1 = f1.get(attr.getName());
491
                        v2 = f2.get(attr.getName());
492
                        if (!compareFeatureValue(v1, v2, attr)) {
493
                                return false;
494
                        }
495
                }
496

    
497
                return true;
498

    
499
        }
500

    
501
        protected boolean compareFeatureValue(Object v1, Object v2,
502
                        FeatureAttributeDescriptor attr) {
503

    
504
                if ((v1 == null || v2 == null) &&  !attr.allowNull() ){
505
                        getLogger().warn("null and !allowNull:"
506
                                                        + attr.getName());
507
                        return false;
508
                }
509

    
510
                if (v1 == v2) {
511
                        return true;
512
                } else if (v1 == null) {
513
                        getLogger().warn(" v1 == null and v2 != null:"
514
                                                        + attr.getName());
515
                        return false;
516
                } else if (v2 == null) {
517
                        getLogger().warn("v2 == null and v1 != null:"
518
                                                        + attr.getName());
519
                        return false;
520

    
521
                }
522
                switch (attr.getType()) {
523
                case DataTypes.GEOMETRY:
524
                        Geometry geom1 = (Geometry) v1;
525
                        Geometry geom2 = (Geometry) v2;
526
                        if (!geom1.equals(geom2)) {
527
                                getLogger().warn(" v1 != v2 (Geom):" + attr.getName());
528
                                return false;
529

    
530
                        }
531
                        return true;
532
                case DataTypes.DOUBLE:
533
                        double diff = ((Double) v1).doubleValue()
534
                                        - ((Double) v1).doubleValue();
535
                        if (!(Math.abs(diff) < 0.000001)) {
536
                                getLogger().warn(" v1 != v2 (Dobule):" + attr.getName());
537
                                return false;
538

    
539
                        }
540
                        return true;
541

    
542
                case DataTypes.OBJECT:
543
                        if (!v1.equals(v2)) {
544
                                getLogger().warn(
545
                                                " v1 != v2 (object):" + attr.getName() + " [ignored]");
546
                                return false;
547
                        }
548
                        return true;
549

    
550
                default:
551
                        if (!v1.equals(v2)) {
552
                                getLogger()
553
                                                .warn(
554
                                                                " v1 != v2:" + attr.getName() + ": " + v1
555
                                                                                + " != " + v2);
556
                                return false;
557
                        }
558
                }
559
                return true;
560

    
561
        }
562

    
563

    
564
        //------------------------------------------------
565

    
566
        public void testSimpleIteration(FeatureStore store) {
567
                this.testSimpleIteration(store, null);
568
        }
569

    
570
        protected String[] getRandomAttibuteList(FeatureType fType) {
571
                String[] attrNames = new String[fType.size()];
572
                Iterator iter = fType.iterator();
573
                int i = 0;
574
                while (iter.hasNext()) {
575
                        attrNames[i] = ((FeatureAttributeDescriptor) iter.next()).getName();
576
                        i++;
577
                }
578
                return this.getRandomAttibuteList(attrNames);
579
        }
580

    
581
        protected Random getRandom(){
582
                if (rnd == null){
583
                        rnd = new Random();
584
                        rnd.setSeed(System.currentTimeMillis());
585
                }
586
                return rnd;
587
        }
588

    
589
        protected String[] getRandomAttibuteList(String[] attrNames) {
590
                int nAttributes = getRandom().nextInt(
591
                                attrNames.length + (attrNames.length / 2)) + 1;
592
                TreeSet set = new TreeSet();
593
                for (int i = 0; i < nAttributes; i++) {
594
                        set.add(attrNames[getRandom().nextInt(attrNames.length)]);
595
                }
596
                return (String[]) set.toArray(new String[0]);
597
        }
598

    
599
        public void testIterationFastAndStandart(FeatureStore store)
600
                        throws Exception {
601
                this.testIterationFastAndStandart(store, null);
602

    
603
                FeatureQuery query = this.getDefaultQuery(store);
604
                // Random Attribute list
605
                query.setAttributeNames(getRandomAttibuteList(store
606
                                .getDefaultFeatureType()));
607
                this.testIterationFastAndStandart(store, query);
608

    
609
                // Sorted
610
                FeatureAttributeDescriptor attr = getFirstAttributeOfType(store
611
                                .getDefaultFeatureType(), new int[] { DataTypes.INT,
612
                                DataTypes.LONG, DataTypes.STRING, DataTypes.DOUBLE, DataTypes.FLOAT });
613
                {
614
                        // asure that attr is in query attributes
615
                        boolean attrFound = false;
616
                        String[] curAttrs = query.getAttributeNames();
617
                        for (int i = 0; i < curAttrs.length; i++) {
618
                                if (curAttrs[i].equals(attr.getName())) {
619
                                        attrFound = true;
620
                                        break;
621

    
622
                                }
623
                        }
624
                        if (!attrFound) {
625
                                String[] newAttrs = new String[curAttrs.length + 1];
626
                                for (int i = 0; i < curAttrs.length; i++) {
627
                                        newAttrs[i] = curAttrs[i];
628
                                }
629
                                newAttrs[curAttrs.length] = attr.getName();
630
                                query.setAttributeNames(newAttrs);
631
                        }
632
                }
633

    
634

    
635
                query.getOrder().add(attr.getName(), true);
636
                this.testIterationFastAndStandart(store, query);
637

    
638
                // Filter
639
                query = this.getDefaultQuery(store);
640

    
641
                query.setFilter(new Evaluator(){
642
                    private EvaluatorFieldsInfo evaluatorFieldsInfo = new EvaluatorFieldsInfo();
643
                    
644
                        public Object evaluate(EvaluatorData data)
645
                                        throws EvaluatorException {
646
                                // TODO Auto-generated method stub
647
                                return Boolean.TRUE;
648
                        }
649

    
650
                        public String getSQL() {
651
                                return "true = true";
652
                        }
653

    
654
                        public String getDescription() {
655
                                // TODO Auto-generated method stub
656
                                return null;
657
                        }
658

    
659
                        public String getName() {
660
                                return "AlwaysTrue";
661
                        }
662

    
663
                        public EvaluatorFieldsInfo getFieldsInfo() {                                
664
                                return evaluatorFieldsInfo;
665
                        }
666

    
667
                });
668
                this.testIterationFastAndStandart(store, query);
669

    
670
                // Filter + Sorted
671
                query.getOrder().add(attr.getName(), true);
672
                this.testIterationFastAndStandart(store, query);
673
        }
674

    
675
        public void testSimpleIteration(FeatureStore store, FeatureQuery query) {
676
                FeatureSet set;
677
                try {
678

    
679
                        if (query == null) {
680
                                query = this.getDefaultQuery(store);
681
                        }
682
                        set = store.getFeatureSet(query);
683
                        FeatureType type = set.getDefaultFeatureType();
684

    
685
                        DisposableIterator it = set.fastIterator();
686
                        Feature feature;
687
                        printFeatureTypeColNames(type, 15);
688
                        while (it.hasNext()) {
689

    
690
                                feature = (Feature) it.next();
691
                                printFeature(feature, false, 15);
692
                        }
693

    
694
                        it.dispose();
695
                        set.dispose();
696

    
697
                } catch (DataException e3) {
698
                        e3.printStackTrace();
699
                        fail();
700
                        return;
701
                }
702

    
703
        }
704

    
705
        public void testIterationFastAndStandart(FeatureStore store,
706
                        FeatureQuery query) {
707
                FeatureSet set;
708
                try {
709

    
710
                        if (query == null) {
711
                                query = this.getDefaultQuery(store);
712
                        }
713
                        set = store.getFeatureSet(query);
714

    
715
                        DisposableIterator it = set.fastIterator();
716
                        DisposableIterator fit = set.fastIterator();
717

    
718
                        assertTrue(this.compareFeatureIterators(it, fit));
719

    
720
                        it.dispose();
721
                        fit.dispose();
722
                        set.dispose();
723

    
724
                } catch (DataException e3) {
725
                        e3.printStackTrace();
726
                        fail();
727
                        return;
728
                }
729

    
730
        }
731

    
732
        public void testSimpleIteration(DataStoreParameters parameters)
733
                        throws Exception {
734
                FeatureStore store = null;
735
                store = (FeatureStore) dataManager.openStore(parameters
736
                                .getDataStoreName(), parameters);
737

    
738
                this.testSimpleIteration(store);
739

    
740
                store.dispose();
741

    
742
        }
743

    
744
        public void testIterationFastAndStandart(DataStoreParameters parameters)
745
                        throws Exception {
746
                FeatureStore store = null;
747
                store = (FeatureStore) dataManager.openStore(parameters
748
                                .getDataStoreName(), parameters);
749

    
750
                this.testIterationFastAndStandart(store);
751

    
752
                store.dispose();
753

    
754
        }
755

    
756
        /**
757
         *
758
         * @param count
759
         *            if (< 0) list.size() >= 1 else list.size() == count
760
         * @throws Exception
761
         */
762
        public void testExplorerList(int count) throws Exception {
763
                FeatureStore store = null;
764
                DataStoreParameters params = getDefaultDataStoreParameters();
765
                store = (FeatureStore) dataManager.openStore(params.getDataStoreName(),
766
                                params);
767

    
768
                DataServerExplorer explorer;
769
                explorer = store.getExplorer();
770

    
771
                if (count < 0) {
772
                        assertTrue(explorer.list().size() >= 1);
773
                } else {
774
                        assertTrue(explorer.list().size() == count);
775
                }
776

    
777
                store.dispose();
778

    
779
                explorer.dispose();
780
        }
781

    
782
        //=================================================
783
        //=================================================
784

    
785

    
786

    
787

    
788
        public void testIterationFastAndStandart() throws Exception {
789
                this.testIterationFastAndStandart(this.getDefaultDataStoreParameters());
790
        }
791

    
792
        public void testSimpleIteration() throws Exception {
793
                this.testSimpleIteration(this.getDefaultDataStoreParameters());
794
        }
795

    
796
        public void testInitializeStore() throws Exception {
797
                DataStoreParameters params = getDefaultDataStoreParameters();
798
                FeatureStore store = (FeatureStore) dataManager.openStore(params
799
                                .getDataStoreName(), params);
800

    
801
                assertNotNull(store.getMetadataID());
802
                assertNotNull(store.getName());
803
                assertEquals(store.getEnvelope(), store.getDynValue("Envelope"));
804
                assertTrue("Feature count not > 0", store.getFeatureCount() > 0);
805
                if (store.isLocksSupported()) {
806
                        assertNotNull(store.getLocks());
807
                } else {
808
                        assertNull(store.getLocks());
809
                }
810
                store.dispose();
811
        }
812

    
813

    
814
        public void testExplorer() throws Exception {
815
                if (!this.hasExplorer()) {
816
                        return;
817
                }
818
                this.testExplorerList(-1);
819

    
820
        }
821

    
822
        public void testSelection() throws Exception {
823
                DataStoreParameters parameters = this.getDefaultDataStoreParameters();
824

    
825
                FeatureStore store = (FeatureStore) dataManager.openStore(parameters
826
                                .getDataStoreName(), parameters);
827
                FeatureSet set = store.getFeatureSet();
828

    
829
                assertTrue(store.getFeatureSelection().isEmpty());
830
                store.setSelection(set);
831
                assertFalse(store.getFeatureSelection().isEmpty());
832

    
833
                assertEquals(set.getSize(), store.getFeatureSelection().getSize());
834

    
835
                DisposableIterator iter = set.fastIterator();
836
                while (iter.hasNext()) {
837
                        assertTrue(store.getFeatureSelection().isSelected(
838
                                        (Feature) iter.next()));
839
                }
840
                iter.dispose();
841

    
842
                store.getFeatureSelection().reverse();
843
                assertTrue(store.getFeatureSelection().isEmpty());
844
                assertEquals(0, store.getFeatureSelection().getSize());
845
                iter = set.fastIterator();
846
                while (iter.hasNext()) {
847
                        assertFalse(store.getFeatureSelection().isSelected(
848
                                        (Feature) iter.next()));
849
                }
850
                iter.dispose();
851

    
852
                store.getFeatureSelection().reverse();
853
                assertEquals(set.getSize(), store.getFeatureSelection().getSize());
854
                assertFalse(store.getFeatureSelection().isEmpty());
855

    
856
                set.dispose();
857

    
858
        }
859

    
860
        public void testCustomFTypeSet() throws Exception {
861
                DataStoreParameters dbfParameters = this
862
                                .getDefaultDataStoreParameters();
863

    
864
                FeatureStore store = (FeatureStore) dataManager.openStore(dbfParameters
865
                                .getDataStoreName(), dbfParameters);
866

    
867
                testCustomFTypeSet(store);
868

    
869
                store.dispose();
870
        }
871

    
872
        public void testCustomFTypeSet(FeatureStore store) throws Exception{
873

    
874
                FeatureSet set, set1;
875
                FeatureQuery query;
876
                DisposableIterator iter, iter1;
877
                Iterator attrIter;
878
                FeatureAttributeDescriptor attr;
879

    
880
                set = store.getFeatureSet(this.getDefaultQuery(store));
881
                attrIter = store.getDefaultFeatureType().iterator();
882

    
883
                String[] names;
884
                while (attrIter.hasNext()) {
885
                        attr = (FeatureAttributeDescriptor) attrIter.next();
886
                        int fieldIndex = attr.getIndex();
887

    
888
                        query = this.getDefaultQuery(store);
889
                        String fieldName = store.getDefaultFeatureType()
890
                        .getAttributeDescriptor(fieldIndex).getName();
891

    
892
                        names = new String[] { fieldName };
893
                        query.setAttributeNames(names);
894
                        set1 = store.getFeatureSet(query);
895

    
896
                        if (getRandom().nextBoolean()) {
897
                                iter = set.fastIterator();
898
                        } else {
899
                                iter = set.fastIterator();
900
                        }
901
                        if (getRandom().nextBoolean()) {
902
                                iter1 = set1.fastIterator();
903
                        } else {
904
                                iter1 = set1.fastIterator();
905
                        }
906

    
907
                        assertTrue(compareFeatureIterators(iter, iter1, names));
908

    
909
                        iter.dispose();
910
                        iter1.dispose();
911
                        set1.dispose();
912
                }
913

    
914
                int ntimes = getRandom().nextInt(10) + 5;
915
                FeatureType type = store.getDefaultFeatureType();
916
                query = this.getDefaultQuery(store);
917
                for (int i = 0; i < ntimes; i++) {
918
                        names = getRandomAttibuteList(type);
919

    
920
                        query.setAttributeNames(names);
921
                        set1 = store.getFeatureSet(query);
922

    
923
                        if (getRandom().nextBoolean()) {
924
                                iter = set.fastIterator();
925
                        } else {
926
                                iter = set.fastIterator();
927
                        }
928
                        if (getRandom().nextBoolean()) {
929
                                iter1 = set1.fastIterator();
930
                        } else {
931
                                iter1 = set1.fastIterator();
932
                        }
933

    
934
                        assertTrue(compareFeatureIterators(iter, iter1, names));
935

    
936
                        iter.dispose();
937
                        iter1.dispose();
938

    
939
                        iter1 = set1.fastIterator();
940
                        assertTrue(checksAttributesPositions(iter1, names));
941
                        iter1.dispose();
942

    
943
                        iter1 = set1.fastIterator();
944
                        assertTrue(checksAttributesPositions(iter1, names));
945
                        iter1.dispose();
946

    
947
                        set1.dispose();
948

    
949

    
950
                }
951

    
952

    
953

    
954
                set.dispose();
955

    
956
        }
957

    
958
        protected boolean checksAttributesPositions(DisposableIterator iter,
959
                        String[] names) {
960
                Feature feature;
961
                FeatureType type;
962
                FeatureAttributeDescriptor attr;
963
                while (iter.hasNext()) {
964
                        feature = (Feature) iter.next();
965
                        type = feature.getType();
966
                        for (int i = 0; i < names.length; i++) {
967
                                attr = type.getAttributeDescriptor(i);
968
                                if (!names[i].equals(attr.getName())) {
969
                                        getLogger().error(
970
                                                        "Error in attribute {} (expected: '{}' have: '{}'",
971
                                                        new Object[] { new Integer(i), names[i],
972
                                                                        attr.getName() });
973
                                        return false;
974
                                }
975
                        }
976
                }
977
                return true;
978
        }
979

    
980
         public void testPersistence() throws Exception {
981
                if (ToolsLocator.getPersistenceManager() == null) {
982
                        fail("Default Persistence Manager not register");
983
                }
984
                DataStoreParameters params = this.getDefaultDataStoreParameters();
985

    
986
                FeatureStore store = (FeatureStore) dataManager.openStore(params
987
                                .getDataStoreName(), params);
988

    
989
                testSimpleIteration(store);
990

    
991
                PersistentState state = ToolsLocator.getPersistenceManager().getState(
992
                                store);
993

    
994
                FeatureStore store2 = (FeatureStore) ToolsLocator
995
                                .getPersistenceManager().create(state);
996

    
997
                testSimpleIteration(store2);
998

    
999
                assertTrue(compareStores(store, store2));
1000

    
1001
                store.dispose();
1002
                store2.dispose();
1003

    
1004
        }
1005

    
1006

    
1007
        public void testSort() throws Exception {
1008
                DataStoreParameters dbfParameters = this
1009
                                .getDefaultDataStoreParameters();
1010

    
1011
                FeatureStore store = (FeatureStore) dataManager.openStore(dbfParameters
1012
                                .getDataStoreName(), dbfParameters);
1013

    
1014
                testSort(store);
1015

    
1016
                store.dispose();
1017

    
1018
        }
1019

    
1020
        public void testSort(FeatureStore store) throws Exception{
1021
                FeatureSet set1;
1022
                FeatureQuery query;
1023
                DisposableIterator iter1;
1024
                Iterator attrIter;
1025
                FeatureAttributeDescriptor attr;
1026

    
1027
                attrIter = store.getDefaultFeatureType().iterator();
1028

    
1029
                String[] names;
1030
                while (attrIter.hasNext()) {
1031
                        attr = (FeatureAttributeDescriptor) attrIter.next();
1032

    
1033
                        if (attr.getType() == DataTypes.GEOMETRY) {
1034
                                continue;
1035
                        }
1036
                        query = this.getDefaultQuery(store);
1037
                        String fieldName = attr.getName();
1038

    
1039

    
1040

    
1041
                        names = new String[] { fieldName };
1042
                        query.setAttributeNames(names);
1043
                        query.getOrder().add(fieldName, getRandom().nextBoolean());
1044

    
1045
                        set1 = store.getFeatureSet(query);
1046
                        if (getRandom().nextBoolean()) {
1047
                                iter1 = set1.fastIterator();
1048
                        } else {
1049
                                iter1 = set1.fastIterator();
1050
                        }
1051

    
1052
                        assertTrue(checkSort(iter1, query));
1053

    
1054
                        iter1.dispose();
1055
                        set1.dispose();
1056
                }
1057

    
1058
                int ntimes = getRandom().nextInt(10) + 5;
1059
                FeatureType type = store.getDefaultFeatureType();
1060
                query = this.getDefaultQuery(store);
1061
                for (int i = 0; i < ntimes; i++) {
1062
                        names = getRandomAttibuteList(type);
1063

    
1064
                        int nShortFields = getRandom().nextInt(names.length) + 1;
1065
                        query.getOrder().clear();
1066
                        for (int j = 0; j < nShortFields; j++) {
1067
                                attr = store.getDefaultFeatureType().getAttributeDescriptor(names[getRandom().nextInt(names.length)]);
1068
                                if (attr.getType() == DataTypes.INT
1069
                                                || attr.getType() == DataTypes.LONG
1070
                                                || attr.getType() == DataTypes.DOUBLE
1071
                                                || attr.getType() == DataTypes.STRING
1072
                                                || attr.getType() == DataTypes.DATE
1073
                                                || attr.getType() == DataTypes.BOOLEAN
1074
                                                || attr.getType() == DataTypes.BYTE
1075
                                                || attr.getType() == DataTypes.FLOAT) {
1076

    
1077
                                        query.getOrder().add(attr.getName(),
1078
                                                        getRandom().nextBoolean());
1079
                                }
1080
                        }
1081

    
1082
                        query.setAttributeNames(names);
1083
                        set1 = store.getFeatureSet(query);
1084

    
1085
                        // if (getRandom().nextBoolean()) {
1086
                                iter1 = set1.fastIterator();
1087
                                // } else {
1088
                                // iter1 = set1.iterator();
1089
                                // }
1090

    
1091
                                assertTrue(checkSort(iter1, query));
1092

    
1093
                                iter1.dispose();
1094
                                set1.dispose();
1095

    
1096
                }
1097

    
1098
        }
1099

    
1100

    
1101
        public boolean checkSort(Iterator iter, FeatureQuery query) {
1102

    
1103
                FeatureQueryOrderMember order;
1104
                Feature prevFeature = null;
1105
                Feature currFeature = null;
1106
                boolean isFirst = true;
1107
                Comparable v1, v2;
1108
                Object o1, o2;
1109
                int v;
1110
                FeatureQueryOrder queryOrder = query.getOrder();
1111

    
1112
                Iterator orderIter;
1113

    
1114
                //for debug only
1115
                /*
1116
                System.out.println("\nCheck order:");
1117
                Iterator orderIter = queryOrder.iterator();
1118
                while (orderIter.hasNext()) {
1119
                        order = (FeatureQueryOrderMember) orderIter.next();
1120
                        System.out.print(order.getAttributeName() + " ");
1121
                        if (order.getAscending()) {
1122
                                System.out.print("Asc, ");
1123
                        } else {
1124
                                System.out.print("Desc, ");
1125
                        }
1126
                }
1127
                System.out.println(";");
1128
                */
1129

    
1130
                while (iter.hasNext()) {
1131
                        currFeature = (Feature) iter.next();
1132
                        if (isFirst) {
1133
                                prevFeature = currFeature.getCopy();
1134
                                // printFeature(prevFeature, true, 15);
1135
                                isFirst = false;
1136
                                continue;
1137
                        }
1138
                        // printFeature(currFeature, false, 15);
1139
                        orderIter = queryOrder.iterator();
1140
                        while (orderIter.hasNext()) {
1141
                                order = (FeatureQueryOrderMember) orderIter.next();
1142
                                if (order.hasEvaluator()) {
1143
                                        try {
1144
                                                o1 = order.getEvaluator().evaluate(
1145
                                                                (EvaluatorData) prevFeature);
1146
                                                o2 = order.getEvaluator().evaluate(
1147
                                                                (EvaluatorData) currFeature);
1148
                                        } catch (EvaluatorException e) {
1149
                                                throw new DataEvaluatorRuntimeException(e);
1150
                                        }
1151
                                } else {
1152

    
1153
                                        o1 = prevFeature.get(order.getAttributeName());
1154
                                        o2 = currFeature.get(order.getAttributeName());
1155
                                }
1156
                                if (o1 instanceof Comparable && o2 instanceof Comparable) {
1157
                                        v1 = (Comparable) o1;
1158
                                        v2 = (Comparable) o2;
1159
                                } else {
1160
                                        // uncomparable objets
1161
                                        break;
1162
                                }
1163
                                if (v1 == null) {
1164
                                        if (v2 == null) {
1165
                                                break;
1166
                                        } else {
1167
                                                v = 1;
1168
                                        }
1169
                                } else {
1170
                                        v = v1.compareTo(v2);
1171
                                }
1172
                                if (v != 0) {
1173
                                        if (!order.getAscending()) {
1174
                                                v = -v;
1175
                                        }
1176
                                }
1177
                                if (v < 0) {
1178
                                        break;
1179
                                } else if (v > 0) {
1180
                                        // Checks for ignore case short
1181
                                        if (v1 instanceof String && v2 instanceof String) {
1182
                                                v1 = ((String)v1).toLowerCase();
1183
                                                v2 = ((String)v2).toLowerCase();
1184
                                                v = v1.compareTo(v2);
1185
                                                if (v != 0) {
1186
                                                        if (!order.getAscending()) {
1187
                                                                v = -v;
1188
                                                        }
1189
                                                }
1190
                                                if (v < 0) {
1191
                                                        getLogger()
1192
                                                                        .warn("Short compartor String ok with ignore case");
1193
                                                        break;
1194
                                                } else if (v > 0) {
1195
                                                        return false;
1196
                                                }
1197
                                        } else {
1198
                                                return false;
1199
                                        }
1200
                                }
1201
                        }
1202
                        prevFeature = currFeature.getCopy();
1203
                }
1204

    
1205
                return true;
1206
        }
1207

    
1208
        protected void fullStoreIteratorTest(FeatureStore store) throws Exception{
1209
                testIterationFastAndStandart(store);
1210
                testCustomFTypeSet(store);
1211
                testSort(store);
1212
        }
1213

    
1214

    
1215
        public void testTransformsData() throws Exception {
1216
                DataStoreParameters dbfParameters = this
1217
                                .getDefaultDataStoreParameters();
1218

    
1219
                FeatureStore store = (FeatureStore) dataManager.openStore(dbfParameters
1220
                                .getDataStoreName(), dbfParameters);
1221

    
1222
                FeatureStore store1 = (FeatureStore) dataManager.openStore(
1223
                                dbfParameters.getDataStoreName(), dbfParameters);
1224

    
1225
                FeatureStoreTransform transform = new StringsToLowerTransform();
1226
                transform.setFeatureStore(store);
1227

    
1228
                store.getTransforms().add(transform);
1229

    
1230
                FeatureSet set, set1;
1231
                DisposableIterator iter, iter1;
1232
                Iterator iterAttr;
1233
                FeatureAttributeDescriptor attr;
1234
                Feature feature, feature1;
1235
                int i, ntimes;
1236
                Object v1, v2;
1237

    
1238

    
1239
                fullStoreIteratorTest(store);
1240

    
1241
                set = store.getFeatureSet();
1242
                set1 = store1.getFeatureSet();
1243
                ntimes = getRandom().nextInt(3) + 1;
1244
                for (i = 0; i < ntimes; i++) {
1245
                        if (getRandom().nextBoolean()) {
1246
                                iter = set.fastIterator();
1247
                        } else {
1248
                                iter = set.fastIterator();
1249
                        }
1250
                        if (getRandom().nextBoolean()) {
1251
                                iter1 = set1.fastIterator();
1252
                        } else {
1253
                                iter1 = set1.fastIterator();
1254
                        }
1255
                        while (iter.hasNext()) {
1256
                                feature = (Feature) iter.next();
1257
                                feature1 = (Feature) iter1.next();
1258

    
1259
                                iterAttr = set.getDefaultFeatureType().iterator();
1260
                                while (iterAttr.hasNext()) {
1261
                                        attr = (FeatureAttributeDescriptor) iterAttr.next();
1262
                                        v1 = feature.get(attr.getIndex());
1263
                                        v2 = feature1.get(attr.getIndex());
1264
                                        if (attr.getType() == DataTypes.STRING) {
1265
                                                if (v2 != null) {
1266
                                                        v2 = ((String) v2).toLowerCase();
1267
                                                }
1268

    
1269
                                        }
1270
                                        assertTrue(compareFeatureValue(v1, v2, attr));
1271
                                }
1272
                        }
1273
                        assertFalse(iter1.hasNext());
1274
                        iter.dispose();
1275
                        iter1.dispose();
1276
                }
1277

    
1278

    
1279
                set.dispose();
1280
                set1.dispose();
1281

    
1282

    
1283
                transform = new StringsToUpperTransform();
1284
                transform.setFeatureStore(store);
1285

    
1286
                store.getTransforms().add(transform);
1287

    
1288
                fullStoreIteratorTest(store);
1289

    
1290
                set = store.getFeatureSet();
1291
                set1 = store1.getFeatureSet();
1292
                ntimes = getRandom().nextInt(3) + 1;
1293
                for (i = 0; i < ntimes; i++) {
1294
                        if (getRandom().nextBoolean()) {
1295
                                iter = set.fastIterator();
1296
                        } else {
1297
                                iter = set.fastIterator();
1298
                        }
1299
                        if (getRandom().nextBoolean()) {
1300
                                iter1 = set1.fastIterator();
1301
                        } else {
1302
                                iter1 = set1.fastIterator();
1303
                        }
1304
                        while (iter.hasNext()) {
1305
                                feature = (Feature) iter.next();
1306
                                feature1 = (Feature) iter1.next();
1307

    
1308
                                iterAttr = set.getDefaultFeatureType().iterator();
1309
                                while (iterAttr.hasNext()) {
1310
                                        attr = (FeatureAttributeDescriptor) iterAttr.next();
1311
                                        v1 = feature.get(attr.getIndex());
1312
                                        v2 = feature1.get(attr.getIndex());
1313
                                        if (attr.getType() == DataTypes.STRING) {
1314
                                                if (v2 != null) {
1315
                                                        v2 = ((String) v2).toUpperCase();
1316
                                                }
1317

    
1318
                                        }
1319
                                        compareFeatureValue(v1, v2, attr);
1320
                                }
1321
                        }
1322
                        assertFalse(iter1.hasNext());
1323
                        iter.dispose();
1324
                        iter1.dispose();
1325
                }
1326
                set.dispose();
1327
                set1.dispose();
1328

    
1329

    
1330
                transform = new AddPrefixAttributeName("_");
1331
                transform.setFeatureStore(store);
1332

    
1333
                store.getTransforms().add(transform);
1334

    
1335
                fullStoreIteratorTest(store);
1336

    
1337
                set = store.getFeatureSet();
1338
                set1 = store1.getFeatureSet();
1339
                ntimes = getRandom().nextInt(3) + 1;
1340
                for (i = 0; i < ntimes; i++) {
1341
                        if (getRandom().nextBoolean()) {
1342
                                iter = set.fastIterator();
1343
                        } else {
1344
                                iter = set.fastIterator();
1345
                        }
1346
                        if (getRandom().nextBoolean()) {
1347
                                iter1 = set1.fastIterator();
1348
                        } else {
1349
                                iter1 = set1.fastIterator();
1350
                        }
1351
                        while (iter.hasNext()) {
1352
                                feature = (Feature) iter.next();
1353
                                feature1 = (Feature) iter1.next();
1354

    
1355
                                iterAttr = set1.getDefaultFeatureType().iterator();
1356
                                while (iterAttr.hasNext()) {
1357
                                        attr = (FeatureAttributeDescriptor) iterAttr.next();
1358
                                        v1 = feature.get("_" + attr.getName());
1359
                                        v2 = feature1.get(attr.getIndex());
1360
                                        if (attr.getType() == DataTypes.STRING) {
1361
                                                if (v2 != null) {
1362
                                                        v2 = ((String) v2).toUpperCase();
1363
                                                }
1364

    
1365
                                        }
1366
                                        compareFeatureValue(v1, v2, attr);
1367
                                }
1368
                        }
1369
                        assertFalse(iter1.hasNext());
1370
                        iter.dispose();
1371
                        iter1.dispose();
1372
                }
1373
                set.dispose();
1374
                set1.dispose();
1375

    
1376
                transform = new AddAttribute("__new__", DataTypes.STRING, "$$OK$$", 10);
1377
                transform.setFeatureStore(store);
1378

    
1379
                store.getTransforms().add(transform);
1380

    
1381
                fullStoreIteratorTest(store);
1382

    
1383
                set = store.getFeatureSet();
1384
                set1 = store1.getFeatureSet();
1385
                ntimes = getRandom().nextInt(3) + 1;
1386
                for (i = 0; i < ntimes; i++) {
1387
                        if (getRandom().nextBoolean()) {
1388
                                iter = set.fastIterator();
1389
                        } else {
1390
                                iter = set.fastIterator();
1391
                        }
1392
                        if (getRandom().nextBoolean()) {
1393
                                iter1 = set1.fastIterator();
1394
                        } else {
1395
                                iter1 = set1.fastIterator();
1396
                        }
1397
                        while (iter.hasNext()) {
1398
                                feature = (Feature) iter.next();
1399
                                feature1 = (Feature) iter1.next();
1400

    
1401
                                iterAttr = set1.getDefaultFeatureType().iterator();
1402
                                while (iterAttr.hasNext()) {
1403
                                        attr = (FeatureAttributeDescriptor) iterAttr.next();
1404
                                        v1 = feature.get("_" + attr.getName());
1405
                                        v2 = feature1.get(attr.getIndex());
1406
                                        if (attr.getType() == DataTypes.STRING) {
1407
                                                if (v2 != null) {
1408
                                                        v2 = ((String) v2).toUpperCase();
1409
                                                }
1410

    
1411
                                        }
1412
                                        compareFeatureValue(v1, v2, attr);
1413
                                }
1414
                                compareFeatureValue(feature.get("__new__"), "$$OK$$", set1
1415
                                                .getDefaultFeatureType().getAttributeDescriptor(
1416
                                                                "__new__"));
1417
                        }
1418
                        assertFalse(iter1.hasNext());
1419
                        iter.dispose();
1420
                        iter1.dispose();
1421
                }
1422
                set.dispose();
1423
                set1.dispose();
1424

    
1425

    
1426
                transform = new RemoveAttribute("__new__");
1427
                transform.setFeatureStore(store);
1428

    
1429
                store.getTransforms().add(transform);
1430

    
1431
                fullStoreIteratorTest(store);
1432

    
1433
                set = store.getFeatureSet();
1434
                set1 = store1.getFeatureSet();
1435
                ntimes = getRandom().nextInt(3) + 1;
1436
                for (i = 0; i < ntimes; i++) {
1437
                        if (getRandom().nextBoolean()) {
1438
                                iter = set.fastIterator();
1439
                        } else {
1440
                                iter = set.fastIterator();
1441
                        }
1442
                        if (getRandom().nextBoolean()) {
1443
                                iter1 = set1.fastIterator();
1444
                        } else {
1445
                                iter1 = set1.fastIterator();
1446
                        }
1447
                        while (iter.hasNext()) {
1448
                                feature = (Feature) iter.next();
1449
                                feature1 = (Feature) iter1.next();
1450

    
1451
                                iterAttr = set1.getDefaultFeatureType().iterator();
1452
                                while (iterAttr.hasNext()) {
1453
                                        attr = (FeatureAttributeDescriptor) iterAttr.next();
1454
                                        v1 = feature.get("_" + attr.getName());
1455
                                        v2 = feature1.get(attr.getIndex());
1456
                                        if (attr.getType() == DataTypes.STRING) {
1457
                                                if (v2 != null) {
1458
                                                        v2 = ((String) v2).toUpperCase();
1459
                                                }
1460

    
1461
                                        }
1462
                                        compareFeatureValue(v1, v2, attr);
1463
                                }
1464
                                assertNull(feature.getType().getAttributeDescriptor("__new__"));
1465
                        }
1466
                        assertFalse(iter1.hasNext());
1467
                        iter.dispose();
1468
                        iter1.dispose();
1469
                }
1470
                set.dispose();
1471
                set1.dispose();
1472

    
1473
                store.getTransforms().clear();
1474

    
1475
                compareStores(store, store1);
1476

    
1477

    
1478
                store.dispose();
1479
                store1.dispose();
1480
        }
1481

    
1482
        abstract class myTransform extends AbstractFeatureStoreTransform {
1483
                protected FeatureStore store;
1484
                protected FeatureType orgDefaultFType;
1485
                protected List orgFTypes;
1486

    
1487
                public void applyTransform(Feature source, EditableFeature target)
1488
                                throws DataException {
1489

    
1490
                        Iterator iter = target.getType().iterator();
1491
                        FeatureAttributeDescriptor attr;
1492
                        while (iter.hasNext()) {
1493
                                attr = (FeatureAttributeDescriptor) iter.next();
1494
                                this.setValue(source, target, attr);
1495
                        }
1496

    
1497
                }
1498

    
1499
                protected void setValue(Feature source, EditableFeature target,
1500
                                FeatureAttributeDescriptor attrTarget) throws DataException {
1501
                        target.set(attrTarget.getIndex(), source.get(attrTarget.getName()));
1502
                }
1503

    
1504
                public FeatureType getDefaultFeatureType() throws DataException {
1505
                        return orgDefaultFType;
1506
                }
1507

    
1508
                public FeatureStore getFeatureStore() {
1509
                        return store;
1510
                }
1511

    
1512
                public List getFeatureTypes() throws DataException {
1513
                        return orgFTypes;
1514
                }
1515

    
1516
                public void setFeatureStore(FeatureStore featureStore) {
1517
                        this.store = featureStore;
1518
                        try {
1519
                                this.orgDefaultFType = this.store.getDefaultFeatureType();
1520
                                this.orgFTypes = this.store.getFeatureTypes();
1521

    
1522
                        } catch (DataException e) {
1523
                                throw new RuntimeException(e);
1524
                        }
1525

    
1526
                }
1527

    
1528
                public FeatureType getSourceFeatureTypeFrom(
1529
                                FeatureType targetFeatureType) {
1530

    
1531
                        return targetFeatureType;
1532
                }
1533
                
1534
        public String getName() {
1535
//            System.out
1536
//                .println("\nmyFeatureStore.getname(): " + store.getName());
1537
            return store.getName();
1538
        }
1539

    
1540
        public String getDescription() {
1541
//            System.out.println("\nmyFeatureStore.getDescription(getfullname): "
1542
//                + store.getFullName());
1543
            return store.getFullName();
1544
        }
1545

    
1546
        }
1547

    
1548
        abstract class TransformTypeTransform extends myTransform {
1549

    
1550
                private FeatureType myDefaultFeatureType = null;
1551
                private List myFeatureTypes = null;
1552

    
1553
                public FeatureType getDefaultFeatureType() throws DataException {
1554
                        if (this.myDefaultFeatureType == null) {
1555
                                this.myDefaultFeatureType = this.transformType(orgDefaultFType);
1556
                        }
1557

    
1558
                        return this.myDefaultFeatureType;
1559
                }
1560

    
1561
                protected abstract FeatureType transformType(FeatureType type);
1562

    
1563
                protected abstract FeatureType restoreType(FeatureType type);
1564

    
1565

    
1566
                public List getFeatureTypes() throws DataException {
1567
                        if (this.myFeatureTypes == null) {
1568
                                ArrayList list = new ArrayList();
1569
                                Iterator iter = orgFTypes.iterator();
1570
                                while (iter.hasNext()) {
1571
                                        FeatureType type = (FeatureType) iter.next();
1572
                                        if (type.getId().equals(
1573
                                                        this.getDefaultFeatureType().getId())) {
1574
                                                list.add(this.getDefaultFeatureType());
1575
                                        } else {
1576
                                                list.add(this.transformType(type));
1577
                                        }
1578
                                }
1579
                                this.myFeatureTypes = Collections.unmodifiableList(list);
1580
                        }
1581
                        return this.myFeatureTypes;
1582
                }
1583

    
1584
                public boolean isTransformsOriginalValues() {
1585
                        return false;
1586
                }
1587

    
1588
                public FeatureType getSourceFeatureTypeFrom(
1589
                                FeatureType targetFeatureType) {
1590
                        FeatureType org = null;
1591
                        FeatureType cur = null;
1592
                        Iterator iter = null;
1593
                        try {
1594
                                iter = this.getFeatureTypes().iterator();
1595
                        } catch (DataException e) {
1596
                                new RuntimeException(e);
1597
                        }
1598
                        while (iter.hasNext()) {
1599
                                cur = (FeatureType) iter.next();
1600
                                if (cur.getId().equals(targetFeatureType.getId())) {
1601
                                        org = cur;
1602
                                        break;
1603
                                }
1604
                        }
1605
                        if (org == null) {
1606
                                throw new RuntimeException();
1607
                        }
1608

    
1609
                        return this.restoreType(org);
1610
                }
1611

    
1612
        }
1613

    
1614
        abstract class TransformAttributeNameTransform extends
1615
                        TransformTypeTransform {
1616

    
1617
                protected void setValue(Feature source, EditableFeature target,
1618
                                FeatureAttributeDescriptor attrTarget) throws DataException {
1619
                        target.set(attrTarget.getIndex(), source.get(this
1620
                                        .restoreAttributeName(attrTarget.getName())));
1621
                }
1622

    
1623

    
1624
                protected FeatureType transformType(FeatureType type) {
1625
                        EditableFeatureType result = type.getEditable();
1626
                        Iterator iter = result.iterator();
1627
                        EditableFeatureAttributeDescriptor attr;
1628
                        while (iter.hasNext()) {
1629
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
1630
                                attr.setName(transformAttributeName(attr.getName()));
1631
                        }
1632
                        return result.getNotEditableCopy();
1633
                }
1634

    
1635
                protected abstract String transformAttributeName(String source);
1636

    
1637
                protected abstract String restoreAttributeName(String target);
1638

    
1639
                protected FeatureType restoreType(FeatureType type) {
1640
                        EditableFeatureType result;
1641
                        if (type instanceof EditableFeatureType) {
1642
                                result = (EditableFeatureType) type.getCopy();
1643
                        } else {
1644
                                result = type.getEditable();
1645
                        }
1646
                        Iterator iter = result.iterator();
1647
                        EditableFeatureAttributeDescriptor attr;
1648
                        while (iter.hasNext()) {
1649
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
1650

    
1651
                                attr.setName(restoreAttributeName(attr.getName()));
1652
                        }
1653
                        return result.getNotEditableCopy();
1654
                }
1655

    
1656
                public FeatureType getSourceFeatureTypeFrom(
1657
                                FeatureType targetFeatureType) {
1658
                        FeatureType org = null;
1659
                        FeatureType cur = null;
1660
                        Iterator iter = null;
1661
                        iter = this.orgFTypes.iterator();
1662
                        while (iter.hasNext()) {
1663
                                cur = (FeatureType) iter.next();
1664
                                if (cur.getId().equals(targetFeatureType.getId())) {
1665
                                        org = cur;
1666
                                        break;
1667
                                }
1668
                        }
1669
                        if (cur == null) {
1670
                                throw new RuntimeException();
1671
                        }
1672
                        EditableFeatureType r = org.getEditable();
1673
                        iter = r.iterator();
1674
                        FeatureAttributeDescriptor attr;
1675
                        while (iter.hasNext()) {
1676
                                attr = (FeatureAttributeDescriptor) iter.next();
1677
                                if (targetFeatureType.getIndex(transformAttributeName(attr
1678
                                                .getName())) == -1) {
1679
                                        iter.remove();
1680
                                }
1681
                        }
1682
                        return r.getNotEditableCopy();
1683
                }
1684

    
1685
        }
1686

    
1687

    
1688
        class AddPrefixAttributeName extends TransformAttributeNameTransform {
1689

    
1690
                private String prefix;
1691

    
1692
                AddPrefixAttributeName(String prefix) {
1693
                        this.prefix = prefix;
1694
                }
1695

    
1696
                protected String restoreAttributeName(String target) {
1697
                        return target.substring(getPrefix().length(), target.length());
1698
                }
1699

    
1700
                private String getPrefix() {
1701
                        return prefix;
1702
                }
1703

    
1704
                protected String transformAttributeName(String source) {
1705
                        return getPrefix() + source;
1706
                }
1707

    
1708
        }
1709

    
1710
        class AddAttribute extends TransformTypeTransform {
1711

    
1712
                private String name;
1713
                private int type;
1714
                private Object defValue;
1715
                private int size;
1716
                private Evaluator eval;
1717

    
1718
                AddAttribute(String name) {
1719
                        this(name, DataTypes.STRING, null, 15);
1720
                }
1721

    
1722
                AddAttribute(String name, int type) {
1723
                        this(name, type, null, 15);
1724
                }
1725

    
1726
                AddAttribute(String name, int type, Object defValue) {
1727
                        this(name, type, defValue, 15);
1728
                }
1729

    
1730
                AddAttribute(String name, int type, Evaluator evaluator, int size) {
1731
                        this.name = name;
1732
                        this.type = type;
1733
                        this.defValue = null;
1734
                        this.size = size;
1735
                        this.eval = evaluator;
1736
                }
1737

    
1738
                AddAttribute(String name, int type, Object defValue, int size) {
1739
                        this.name = name;
1740
                        this.type = type;
1741
                        this.defValue = defValue;
1742
                        this.size = size;
1743
                        this.eval = null;
1744
                }
1745

    
1746

    
1747

    
1748
                protected FeatureType restoreType(FeatureType type) {
1749
                        EditableFeatureType result;
1750
                        if (type instanceof EditableFeatureType) {
1751
                                result = (EditableFeatureType) type.getCopy();
1752
                        } else {
1753
                                result = type.getEditable();
1754
                        }
1755
                        result.remove(this.name);
1756
                        return result.getNotEditableCopy();
1757
                }
1758

    
1759
                protected FeatureType transformType(FeatureType type) {
1760
                        EditableFeatureType result = type.getEditable();
1761

    
1762
                        EditableFeatureAttributeDescriptor att;
1763
                        if (this.eval == null) {
1764
                                att = result.add(name, this.type)
1765
                                                .setDefaultValue(this.defValue);
1766
                        } else {
1767
                                att = result.add(name, this.type, this.eval);
1768
                        }
1769
                        att.setSize(size);
1770

    
1771

    
1772
                        return result.getNotEditableCopy();
1773
                }
1774

    
1775
                protected void setValue(Feature source, EditableFeature target,
1776
                                FeatureAttributeDescriptor attrTarget) throws DataException {
1777
                        if (attrTarget.getName().equals(this.name)) {
1778
                                target.set(attrTarget.getIndex(), attrTarget.getDefaultValue());
1779
                        } else {
1780
                                target.set(attrTarget.getIndex(), source.get(attrTarget
1781
                                                .getName()));
1782
                        }
1783
                }
1784
        }
1785

    
1786

    
1787
        class RemoveAttribute extends TransformTypeTransform {
1788

    
1789
                private String attributeName;
1790
                private String fTypeIdToRemoveAttribute = null;
1791
                private FeatureAttributeDescriptor attr;
1792

    
1793
                RemoveAttribute(String attributeName) {
1794
                        this.attributeName = attributeName;
1795
                }
1796

    
1797
                RemoveAttribute(String attributeName, FeatureType fType) {
1798
                        this.attributeName = attributeName;
1799
                }
1800

    
1801
                protected FeatureType restoreType(FeatureType type) {
1802
                        if (!type.getId().equals(this.fTypeIdToRemoveAttribute)) {
1803
                                return type;
1804
                        }
1805
                        EditableFeatureType result = type.getEditable();
1806

    
1807
                        EditableFeatureAttributeDescriptor att;
1808
                        if (this.attr.getEvaluator() == null) {
1809
                                att = result.add(attributeName, this.attr.getType())
1810
                                                .setDefaultValue(this.attr.getDefaultValue());
1811
                        } else {
1812
                                att = result.add(attributeName, this.attr.getType(),
1813
                                                this.attr.getEvaluator());
1814
                        }
1815
                        att.setSize(this.attr.getSize());
1816
                        att.setAllowNull(this.attr.allowNull());
1817
                        att.setGeometryType(this.attr.getGeometryType());
1818
                        att.setSRS(this.attr.getSRS());
1819
                        att.setPrecision(this.attr.getPrecision());
1820
                        // TODO
1821

    
1822

    
1823
                        return result.getNotEditableCopy();
1824
                }
1825

    
1826
                protected FeatureType transformType(FeatureType type) {
1827
                        if (!type.getId().equals(this.fTypeIdToRemoveAttribute)) {
1828
                                return type;
1829
                        }
1830

    
1831
                        EditableFeatureType result;
1832
                        if (type instanceof EditableFeatureType) {
1833
                                result = (EditableFeatureType) type.getCopy();
1834
                        } else {
1835
                                result = type.getEditable();
1836
                        }
1837
                        result.remove(this.attributeName);
1838
                        return result.getNotEditableCopy();
1839

    
1840
                }
1841

    
1842
                public void setFeatureStore(FeatureStore featureStore) {
1843
                        Iterator iter;
1844
                        try {
1845
                                iter = featureStore.getFeatureTypes().iterator();
1846
                        } catch (DataException e) {
1847
                                throw new RuntimeException(e);
1848
                        }
1849
                        FeatureType type;
1850
                        FeatureAttributeDescriptor attrTmp;
1851
                        while (iter.hasNext()) {
1852
                                type = (FeatureType) iter.next();
1853
                                attrTmp = type.getAttributeDescriptor(this.attributeName);
1854
                                if (attrTmp != null) {
1855
                                        this.fTypeIdToRemoveAttribute = type.getId();
1856
                                        this.attr = attrTmp;
1857
                                        break;
1858
                                }
1859
                        }
1860
                        super.setFeatureStore(featureStore);
1861
                }
1862

    
1863
                public void applyTransform(Feature source, EditableFeature target)
1864
                                throws DataException {
1865
                        // TODO Auto-generated method stub
1866
                        super.applyTransform(source, target);
1867
                }
1868

    
1869

    
1870

    
1871
        }
1872

    
1873

    
1874
        public class StringsToLowerTransform extends myTransform {
1875

    
1876
                public boolean isTransformsOriginalValues() {
1877
                        return true;
1878
                }
1879

    
1880
                protected void setValue(Feature source, EditableFeature target,
1881
                                FeatureAttributeDescriptor attr) throws DataException {
1882
                        if (attr.getType() == DataTypes.STRING) {
1883
                                String v = ((String) source.get(attr.getName()));
1884
                                if (v != null){
1885
                                        v = v.toLowerCase();
1886
                                } else if (!attr.allowNull()) {
1887
                                        v = (String) attr.getDefaultValue();
1888
                                        v = v.toLowerCase();
1889
                                }
1890
                                target.set(attr.getName(), v);
1891
                        } else {
1892
                                target.set(attr.getName(), source.get(attr.getName()));
1893
                        }
1894
                }
1895

    
1896
        }
1897

    
1898
        class StringsToUpperTransform extends StringsToLowerTransform {
1899
                protected void setValue(Feature source, EditableFeature target,
1900
                                FeatureAttributeDescriptor attr) throws DataException {
1901
                        if (attr.getType() == DataTypes.STRING) {
1902
                                String v = ((String) source.get(attr.getName()));
1903
                                if (v != null) {
1904
                                        v = v.toUpperCase();
1905
                                } else if (!attr.allowNull()) {
1906
                                        v = (String) attr.getDefaultValue();
1907
                                        v.toUpperCase();
1908
                                }
1909
                                target.set(attr.getName(), v);
1910
                        } else {
1911
                                target.set(attr.getName(), source.get(attr.getName()));
1912
                        }
1913
                }
1914

    
1915
        }
1916

    
1917

    
1918
        public void testFeatureReference() throws Exception {
1919
                DataStoreParameters dbfParameters = this
1920
                                .getDefaultDataStoreParameters();
1921

    
1922
                FeatureStore store = (FeatureStore) dataManager.openStore(dbfParameters
1923
                                .getDataStoreName(), dbfParameters);
1924

    
1925
                Feature feature, refered;
1926
                FeatureSet set;
1927
                int nTimes2 = getRandom().nextInt(2) + 1;
1928

    
1929
                for (int j = 0; j < nTimes2; j++) {
1930
                        set = store.getFeatureSet();
1931
                        DisposableIterator iter;
1932

    
1933
                        int nTimes = getRandom().nextInt(2) + 3;
1934
                        for (int i = 0; i < nTimes; i++) {
1935
                                if (getRandom().nextBoolean()) {
1936
                                        iter = set.fastIterator();
1937
                                } else {
1938
                                        iter = set.fastIterator();
1939
                                }
1940
                                while (iter.hasNext()) {
1941
                                        feature = (Feature) iter.next();
1942
                                        refered = feature.getReference().getFeature();
1943
                                        compareFeatures(feature, refered);
1944
                                }
1945
                                iter.dispose();
1946
                        }
1947

    
1948
                        set.dispose();
1949
                }
1950

    
1951
                nTimes2 = getRandom().nextInt(5) + 2;
1952
                FeatureQuery query = store.createFeatureQuery();
1953

    
1954
                for (int j = 0; j < nTimes2; j++) {
1955
                        DisposableIterator iter;
1956

    
1957
                        query.setAttributeNames(getRandomAttibuteList(store
1958
                                        .getDefaultFeatureType()));
1959
                        set = store.getFeatureSet(query);
1960

    
1961
                        int nTimes = getRandom().nextInt(3) + 3;
1962
                        for (int i = 0; i < nTimes; i++) {
1963
                                if (getRandom().nextBoolean()) {
1964
                                        iter = set.fastIterator();
1965
                                } else {
1966
                                        iter = set.fastIterator();
1967
                                }
1968
                                while (iter.hasNext()) {
1969
                                        feature = (Feature) iter.next();
1970
                                        refered = feature.getReference().getFeature(
1971
                                                        set.getDefaultFeatureType());
1972
                                        compareFeatures(feature, refered);
1973
                                }
1974
                                iter.dispose();
1975
                        }
1976

    
1977
                        set.dispose();
1978
                }
1979

    
1980

    
1981

    
1982
                store.dispose();
1983

    
1984
        }
1985

    
1986
        public void testResourcesLocks() throws Exception {
1987

    
1988
                if (!this.usesResources()) {
1989
                        return;
1990
                }
1991

    
1992
                DataStoreParameters dbfParameters = this
1993
                                .getDefaultDataStoreParameters();
1994

    
1995
                FeatureStore store = (FeatureStore) dataManager.openStore(dbfParameters
1996
                                .getDataStoreName(), dbfParameters);
1997

    
1998
                int nThreads = getRandom().nextInt(4) + 2;
1999
                List threads = new ArrayList();
2000
                TaskTestIterators task;
2001
                for (int i = 0; i < nThreads; i++) {
2002
                        task = new TaskTestIterators(this, "" + i, store);
2003
                        threads.add(task);
2004
                        task.start();
2005
                }
2006

    
2007
                Iterator iter;
2008
                List stillAlives = new ArrayList();
2009
                stillAlives.addAll(threads);
2010

    
2011
                while (!stillAlives.isEmpty()) {
2012
                        iter = stillAlives.iterator();
2013
                        while (iter.hasNext()) {
2014
                                task = (TaskTestIterators) iter.next();
2015
                                if (!task.isAlive()) {
2016
                                        iter.remove();
2017
                                } else if ((!task.isFinished()) && task.isOutOfDate()) {
2018
                                        iter.remove();
2019
                                        getLogger().error("task {} outOfDate", task.getName());
2020
                                } else {
2021
                                        Thread.yield();
2022
                                        Thread.sleep(100);
2023
                                }
2024
                        }
2025
                }
2026

    
2027
                store.dispose();
2028

    
2029
                iter = threads.iterator();
2030
                while (iter.hasNext()) {
2031
                        task = (TaskTestIterators) iter.next();
2032
                        assertTrue(task.isFinishedOk());
2033
                }
2034
        }
2035

    
2036
        class TaskTestIterators extends StoreTask {
2037
                private BaseTestFeatureStore testInstance;
2038

    
2039
                public TaskTestIterators(BaseTestFeatureStore testInstance,
2040
                                String name, FeatureStore store) {
2041
                        super(name, store);
2042
                        this.testInstance = testInstance;
2043
                }
2044

    
2045
                public TaskTestIterators(BaseTestFeatureStore testInstance,
2046
                                String name, FeatureStore store, int timeToWait) {
2047
                        super(name, store, timeToWait);
2048
                        this.testInstance = testInstance;
2049
                }
2050

    
2051
                public void run() {
2052
                        if (!this.startProcess()) {
2053
                                return;
2054
                        }
2055
                        try {
2056
                                this.testInstance.fullStoreIteratorTest(store);
2057

    
2058
                                finishedOk();
2059
                        } catch (Throwable e) {
2060
                                finishedError(e);
2061
                                return;
2062
                        }
2063
                }
2064

    
2065

    
2066
        }
2067

    
2068

    
2069
        protected void tearDown() throws Exception {
2070
                super.tearDown();
2071
                if (!usesResources()) {
2072
                        return;
2073
                }
2074

    
2075
                ResourceManager resMan = DALLocator.getResourceManager();
2076
                resMan.closeResources();
2077
        }
2078

    
2079

    
2080

    
2081
}