Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / persistence / impl / AbstractPersistentState.java @ 1861

History | View | Annotate | Download (36.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
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
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2009 IVER T.I   {{Task}}
27
 */
28
package org.gvsig.tools.persistence.impl;
29

    
30
import org.gvsig.tools.util.FileTools;
31
import java.io.File;
32
import java.lang.reflect.Array;
33
import java.net.MalformedURLException;
34
import java.net.URI;
35
import java.net.URISyntaxException;
36
import java.net.URL;
37
import java.util.ArrayList;
38
import java.util.Arrays;
39
import java.util.Collection;
40
import java.util.Collections;
41
import java.util.Date;
42
import java.util.HashMap;
43
import java.util.Iterator;
44
import java.util.LinkedHashMap;
45
import java.util.LinkedHashSet;
46
import java.util.List;
47
import java.util.Map;
48
import java.util.Map.Entry;
49
import java.util.Set;
50
import java.util.regex.Pattern;
51
import org.apache.commons.io.FileUtils;
52

    
53
import org.gvsig.tools.dataTypes.DataTypes;
54
import org.gvsig.tools.dynobject.DynField;
55
import org.gvsig.tools.dynobject.DynStruct;
56
import org.gvsig.tools.persistence.PersistenceFactory;
57
import org.gvsig.tools.persistence.PersistenceManager;
58
import org.gvsig.tools.persistence.Persistent;
59
import org.gvsig.tools.persistence.PersistentContext;
60
import org.gvsig.tools.persistence.PersistentState;
61
import org.gvsig.tools.persistence.exception.PersistenceException;
62
import org.gvsig.tools.persistence.exception.PersistenceTypeNotSupportedException;
63
import org.gvsig.tools.persistence.impl.exception.PersistenceIllegalStateTheClassNameNotSetException;
64
import org.gvsig.tools.persistence.impl.exception.PersistenceInvalidPropertyNameException;
65
import org.gvsig.tools.persistence.impl.exception.PersistenceInvalidTypeForPropertyException;
66
import org.gvsig.tools.persistence.impl.exception.PersistenceUnsuportedMapKeyTypeException;
67
import org.gvsig.tools.persistence.impl.exception.PersistenceValueNotFoundException;
68
import org.gvsig.tools.persistence.spi.PersistenceManagerServices;
69
import org.gvsig.tools.persistence.spi.PersistentContextServices;
70
import org.gvsig.tools.persistence.spi.PersistentContextServices.ObjectReference;
71
import org.gvsig.tools.persistence.spi.PersistentIdentifier;
72
import org.gvsig.tools.persistence.spi.PersistentStateServices;
73
import org.slf4j.Logger;
74
import org.slf4j.LoggerFactory;
75

    
76
public abstract class AbstractPersistentState implements
77
        PersistentStateServices {
78

    
79
    private static final Logger logger = LoggerFactory.getLogger(PersistentState.class);
80

    
81
    private static final Pattern VALID_NAME_PATTERN = Pattern
82
            .compile("[\\w][\\d\\w_]*"
83
            );
84

    
85
    private static final List validStdTypeClasses = Collections.unmodifiableList(
86
            Arrays.asList(
87
                    new Class[]{ // All need to be immutable
88
                        Integer.class, Long.class, Float.class, Double.class,
89
                        Boolean.class, String.class, Date.class,
90
                        File.class, URL.class, URI.class, Byte.class
91
                    }
92
            )
93
    );
94

    
95
    private Map values = new LinkedHashMap();
96
    private final PersistentContextServices context;
97
    private final PersistentIdentifier id;
98
    private final PersistenceManagerServices manager;
99
    private String theClassName = null;
100
    private PersistenceFactory factory;
101

    
102
    public AbstractPersistentState(PersistenceManagerServices manager,
103
            PersistentContextServices context, PersistentIdentifier id) {
104
        this.manager = manager;
105
        this.context = context;
106
        this.id = id;
107
        values = new HashMap();
108
    }
109

    
110
    @Override
111
    public void setFactory(PersistenceFactory factory) {
112
        this.factory = factory;
113
    }
114

    
115
    @Override
116
    public DynStruct getDefinition() {
117
        if (this.factory == null) {
118
            return null;
119
        }
120
        DynStruct definition = this.factory.getDefinition(this.theClassName);
121
        return definition;
122
    }
123

    
124
    private DynStruct getDefinitionCheckNull() {
125
        DynStruct definition = getDefinition();
126
        if (definition == null) {
127
            throw new NullPointerException(
128
                    "Can't locate definition for the class '"
129
                    + this.theClassName + "' in the factory '"
130
                    + this.factory.getClass().getName()
131
                    + "', managed classes are '"
132
                    + this.factory.getManagedClasses().toString()
133
                    + "'.");
134
        }
135
        return definition;
136
    }
137

    
138
    @Override
139
    public Object get(String name) throws PersistenceException {
140
        Object ret = values.get(name);
141
        if (ret == null) {
142
            // We are asked for an attribute not defined in the dynstruct
143
            if (!values.containsKey(name) && !definitionHasField(name)) {
144
                throw new PersistenceValueNotFoundException(name);
145
            }
146
            return getDefaultValue(name);
147
        }
148
        return get(ret);
149
    }
150

    
151
    public boolean isNull(String name) {
152
        Object ret = values.get(name);
153
        return ret == null;
154
    }
155

    
156
    @Override
157
    public List getList(String name) throws PersistenceException {
158
        return (List) get(name);
159
    }
160

    
161
    @Override
162
    public Map getMap(String name) throws PersistenceException {
163
        return (Map) get(name);
164
    }
165

    
166
    @Override
167
    public Set getSet(String name) throws PersistenceException {
168
        return (Set) get(name);
169
    }
170

    
171
    private Object get(Object obj) throws PersistenceException {
172
        if (obj instanceof ObjectReference) {
173
            ObjectReference ref = (ObjectReference) obj;
174
            return ref.getObject();
175
        }
176
        if (obj instanceof Persistent) {
177
            return obj;
178
        }
179
        /*
180
                 *
181
         */
182
        if (obj instanceof List) {
183
            if ((manager.getFactories().get(obj)) == null) {
184
                List result = new ArrayList(((List) obj).size());
185
                getValues(result, (((List) obj).iterator()));
186
                return result;
187
            }
188
        }
189
        return obj;
190
    }
191

    
192
    private void getValues(List result, Iterator iterator)
193
            throws PersistenceException {
194
        while (iterator.hasNext()) {
195
            result.add(get(iterator.next()));
196
        }
197
    }
198

    
199
    @Override
200
    public boolean getBoolean(String name) throws PersistenceException {
201
        return ((Boolean) get(name));
202
    }
203

    
204
    @Override
205
    public double getDouble(String name) throws PersistenceException {
206
        return ((Double) get(name));
207
    }
208

    
209
    @Override
210
    public File getFile(String name) throws PersistenceException {
211
        Object obj = get(name);
212
        if (obj instanceof String) {
213
            return new File((String) obj);
214
        }
215
        return (File) obj;
216
    }
217

    
218
    @Override
219
    public URL getURL(String name) throws PersistenceException {
220
        Object obj = get(name);
221
        if (obj instanceof String) {
222
            try {
223
                return new URL((String) obj);
224
            } catch (MalformedURLException e) {
225
                throw new PersistenceException("Can't create URL from '" + (String) obj + "'", e);
226
            }
227
        }
228
        return (URL) obj;
229
    }
230

    
231
    @Override
232
    public URI getURI(String name) throws PersistenceException {
233
        Object obj = get(name);
234
        if (obj instanceof String) {
235
            try {
236
                return new URI((String) obj);
237
            } catch (URISyntaxException e) {
238
                throw new PersistenceException("Can't create URI from '" + (String) obj + "'", e);
239
            }
240
        }
241
        return (URI) obj;
242
    }
243

    
244
    @Override
245
    public Date getDate(String name) throws PersistenceException {
246
        return (Date) get(name);
247
    }
248

    
249
    @Override
250
    public float getFloat(String name) throws PersistenceException {
251
        return ((Float) get(name));
252
    }
253

    
254
    @Override
255
    public int getInt(String name) throws PersistenceException {
256
        return ((Integer) get(name));
257
    }
258

    
259
    @Override
260
    public Iterator getIterator(String name) throws PersistenceException {
261
        Collection collection = (Collection) get(name);
262
        if (collection == null) {
263
            return null;
264
        }
265
        return collection.iterator();
266
    }
267

    
268
    @Override
269
    public long getLong(String name) throws PersistenceException {
270
        return ((Long) get(name));
271
    }
272

    
273
    @Override
274
    public Object[] getArray(String name, Class valueClass)
275
            throws PersistenceException {
276
        List valueList = getList(name);
277
        if (valueList == null) {
278
            return null;
279
        }
280
        Object array = Array.newInstance(valueClass, valueList.size());
281
        return valueList.toArray((Object[]) array);
282
    }
283

    
284
    @Override
285
    public boolean[] getBooleanArray(String name) throws PersistenceException {
286
        List valueList = getList(name);
287
        if (valueList == null) {
288
            return null;
289
        }
290
        boolean[] values = new boolean[valueList.size()];
291
        for (int i = 0; i < values.length; i++) {
292
            values[i] = ((Boolean) valueList.get(i));
293
        }
294
        return values;
295
    }
296

    
297
    @Override
298
    public int[] getIntArray(String name) throws PersistenceException {
299
        List valueList = getList(name);
300
        if (valueList == null) {
301
            return null;
302
        }
303
        int[] values = new int[valueList.size()];
304
        for (int i = 0; i < values.length; i++) {
305
            values[i] = ((Number) valueList.get(i)).intValue();
306
        }
307
        return values;
308
    }
309

    
310
    @Override
311
    public long[] getLongArray(String name) throws PersistenceException {
312
        List valueList = getList(name);
313
        if (valueList == null) {
314
            return null;
315
        }
316
        long[] values = new long[valueList.size()];
317
        for (int i = 0; i < values.length; i++) {
318
            values[i] = ((Number) valueList.get(i)).longValue();
319
        }
320
        return values;
321
    }
322

    
323
    @Override
324
    public float[] getFloatArray(String name) throws PersistenceException {
325
        List valueList = getList(name);
326
        if (valueList == null) {
327
            return null;
328
        }
329
        float[] values = new float[valueList.size()];
330
        for (int i = 0; i < values.length; i++) {
331
            values[i] = ((Number) valueList.get(i)).floatValue();
332
        }
333
        return values;
334
    }
335

    
336
    @Override
337
    public double[] getDoubleArray(String name) throws PersistenceException {
338
        List valueList = getList(name);
339
        if (valueList == null) {
340
            return null;
341
        }
342
        double[] values = new double[valueList.size()];
343
        for (int i = 0; i < values.length; i++) {
344
            values[i] = ((Number) valueList.get(i)).doubleValue();
345
        }
346
        return values;
347
    }
348

    
349
    @Override
350
    public Date[] getDateArray(String name) throws PersistenceException {
351
        return (Date[]) this.getArray(name, Date.class);
352
    }
353

    
354
    @Override
355
    public String[] getStringArray(String name) throws PersistenceException {
356
        return (String[]) this.getArray(name, String.class);
357
    }
358

    
359
    @Override
360
    public Iterator getNames() {
361
        return values.keySet().iterator();
362
    }
363

    
364
    @Override
365
    public String getString(String name) throws PersistenceException {
366
        return ((String) get(name));
367
    }
368

    
369
    @Override
370
    public void setNull(String name) throws PersistenceException {
371
        setValue(name, null);
372
    }
373

    
374
    @Override
375
    public void set(String name, String value) throws PersistenceException {
376
        setValue(name, value);
377
    }
378

    
379
    @Override
380
    public void set(String name, File value) throws PersistenceException {
381
        setValue(name, value);
382
    }
383

    
384
    @Override
385
    public void set(String name, URL value) throws PersistenceException {
386
        setValue(name, value);
387
    }
388

    
389
    @Override
390
    public void set(String name, URI value) throws PersistenceException {
391
        setValue(name, value);
392
    }
393

    
394
    @Override
395
    public void set(String name, int value) throws PersistenceException {
396
        setValue(name, value);
397
    }
398

    
399
    @Override
400
    public void set(String name, long value) throws PersistenceException {
401
        setValue(name, value);
402
    }
403

    
404
    @Override
405
    public void set(String name, double value) throws PersistenceException {
406
        setValue(name, value);
407

    
408
    }
409

    
410
    @Override
411
    public void set(String name, float value) throws PersistenceException {
412
        setValue(name, value);
413

    
414
    }
415

    
416
    @Override
417
    public void set(String name, boolean value) throws PersistenceException {
418
        setValue(name, value);
419
    }
420

    
421
    @Override
422
    public void set(String name, Persistent obj) throws PersistenceException {
423
        if (obj == null) {
424
            setNull(name);
425
        } else {
426
            setValue(name, getObjectToPersist(obj, name));
427
        }
428
    }
429

    
430
    @Override
431
    public void set(String name, Object obj) throws PersistenceException {
432
        if (obj == null) {
433
            setNull(name);
434
        } else {
435
            setValue(name, getObjectToPersist(obj, name));
436
        }
437
    }
438

    
439
    @Override
440
    public void set(String name, Map obj) throws PersistenceException {
441
        if (obj == null) {
442
            setNull(name);
443
        } else {
444
            setValue(name, getObjectToPersist(obj, name));
445
        }
446
    }
447

    
448
    @Override
449
    public void set(String name, List obj) throws PersistenceException {
450
        if (obj == null) {
451
            setNull(name);
452
        } else {
453
            setValue(name, getObjectToPersist(obj, name));
454
        }
455
    }
456

    
457
    @Override
458
    public void set(String name, Iterator obj) throws PersistenceException {
459
        if (obj == null) {
460
            setNull(name);
461
        } else {
462
            setValue(name, getObjectToPersist(obj, name));
463
        }
464
    }
465

    
466
    @Override
467
    public void set(String name, Object[] values) throws PersistenceException {
468
        set(name, values == null ? null : Arrays.asList(values));
469
    }
470

    
471
    @Override
472
    public void set(String name, Date[] values) throws PersistenceException {
473
        set(name, values == null ? null : Arrays.asList(values));
474
    }
475

    
476
    @Override
477
    public void set(String name, String[] values) throws PersistenceException {
478
        set(name, values == null ? null : Arrays.asList(values));
479
    }
480

    
481
    @Override
482
    public void set(String name, boolean[] value) throws PersistenceException {
483
        if (value == null) {
484
            setValue(name, null);
485
        } else {
486
            List valueList = new ArrayList(value.length);
487
            for (int i = 0; i < value.length; i++) {
488
                valueList.add(value[i] ? Boolean.TRUE : Boolean.FALSE);
489
            }
490
            set(name, valueList);
491
        }
492
    }
493

    
494
    @Override
495
    public void set(String name, int[] value) throws PersistenceException {
496
        if (value == null) {
497
            setValue(name, null);
498
        } else {
499
            List valueList = new ArrayList(value.length);
500
            for (int i = 0; i < value.length; i++) {
501
                valueList.add(value[i]);
502
            }
503
            set(name, valueList);
504
        }
505
    }
506

    
507
    @Override
508
    public void set(String name, long[] value) throws PersistenceException {
509
        if (value == null) {
510
            setValue(name, null);
511
        } else {
512
            List valueList = new ArrayList(value.length);
513
            for (int i = 0; i < value.length; i++) {
514
                valueList.add(value[i]);
515
            }
516
            set(name, valueList);
517
        }
518
    }
519

    
520
    @Override
521
    public void set(String name, float[] value) throws PersistenceException {
522
        if (value == null) {
523
            setValue(name, null);
524
        } else {
525
            List valueList = new ArrayList(value.length);
526
            for (int i = 0; i < value.length; i++) {
527
                valueList.add(value[i]);
528
            }
529
            set(name, valueList);
530
        }
531
    }
532

    
533
    @Override
534
    public void set(String name, double[] value) throws PersistenceException {
535
        if (value == null) {
536
            setValue(name, null);
537
        } else {
538
            List valueList = new ArrayList(value.length);
539
            for (int i = 0; i < value.length; i++) {
540
                valueList.add(value[i]);
541
            }
542
            set(name, valueList);
543
        }
544
    }
545

    
546
    @Override
547
    public void set(String name, Set obj) throws PersistenceException {
548
        if (obj == null) {
549
            setNull(name);
550
        } else {
551
            setValue(name, getObjectToPersist(obj, name));
552
        }
553
    }
554

    
555
    @Override
556
    public void set(String name, Boolean obj) throws PersistenceException {
557
        if (obj == null) {
558
            setNull(name);
559
        } else {
560
            setValue(name, getObjectToPersist(obj, name));
561
        }
562
    }
563

    
564
    @Override
565
    public void set(String name, Integer obj) throws PersistenceException {
566
        if (obj == null) {
567
            setNull(name);
568
        } else {
569
            setValue(name, getObjectToPersist(obj, name));
570
        }
571
    }
572

    
573
    @Override
574
    public void set(String name, Long obj) throws PersistenceException {
575
        if (obj == null) {
576
            setNull(name);
577
        } else {
578
            setValue(name, getObjectToPersist(obj, name));
579
        }
580
    }
581

    
582
    @Override
583
    public void set(String name, Float obj) throws PersistenceException {
584
        if (obj == null) {
585
            setNull(name);
586
        } else {
587
            setValue(name, getObjectToPersist(obj, name));
588
        }
589
    }
590

    
591
    @Override
592
    public void set(String name, Double obj) throws PersistenceException {
593
        if (obj == null) {
594
            setNull(name);
595
        } else {
596
            setValue(name, getObjectToPersist(obj, name));
597
        }
598
    }
599

    
600
    @Override
601
    public void set(String name, Date obj) throws PersistenceException {
602
        if (obj == null) {
603
            setNull(name);
604
        } else {
605
            setValue(name, getObjectToPersist(obj, name));
606
        }
607
    }
608

    
609
    protected Object getObjectToPersist(Object theOriginal)
610
            throws PersistenceException {
611
        return getObjectToPersist(theOriginal, null);
612
    }
613

    
614
    /**
615
     * Checks class of <code>theOriginal</code> and transforms it if is
616
     * necessary.<br>
617
     *
618
     * @param theOriginal
619
     * @return
620
     * @throws PersistenceException
621
     */
622
    private Object getObjectToPersist(Object theOriginal, String propName)
623
            throws PersistenceException {
624
        DynStruct definition;
625
        DynField field = null;
626
        try {
627
            if (theOriginal == null) {
628
                return null;
629
            } else if (validStdTypeClasses.contains(theOriginal.getClass())) {
630
                // FIXME: No esta comprobando que el tipo sea el correcto
631
                return theOriginal;
632
            }
633
            if (theOriginal instanceof File) {
634
                // File no es una clase final, asi que convertimos
635
                // a File para curarnos en salud.
636
                // FIXME: No esta comprobando que el tipo sea el correcto
637
                return new File(((File) theOriginal).toURI());
638
            }
639
            definition = this.getDefinitionCheckNull();
640
            if (propName != null) {
641
                field = definition.getDynField(propName);
642
            }
643
            if (theOriginal instanceof Persistent) {
644
                if (field != null) {
645
                    Class classOfValue = field.getClassOfValue();
646
                    if (classOfValue == null) {
647
                        throw new NullPointerException(
648
                                "Class of value for field '"
649
                                + definition.getFullName() + "' of '"
650
                                + field.getName() + "' can't be null.");
651
                    }
652
                    if (!classOfValue.isAssignableFrom(theOriginal.getClass())) {
653
                        throw new PersistenceInvalidTypeForPropertyException(
654
                                propName, definition, field, theOriginal);
655
                    }
656
                }
657
                ObjectReference ref = context.get(theOriginal);
658
                if (ref == null) {
659
                    PersistentStateServices state = manager.createState(
660
                            theOriginal, context);
661
                    ref = context.get(state);
662
                }
663
                return ref;
664

    
665
            } else if ((manager.getFactories().get(theOriginal)) != null) {
666
                if (field != null) {
667
                    Class classOfValue = field.getClassOfValue();
668
                    if (classOfValue == null) {
669
                        throw new NullPointerException(
670
                                "Class of value for field '"
671
                                + definition.getFullName() + "' of '"
672
                                + field.getName() + "' can't be null.");
673
                    }
674
                    if (!classOfValue.isAssignableFrom(theOriginal.getClass())) {
675
                        throw new PersistenceInvalidTypeForPropertyException(
676
                                propName, definition, field, theOriginal);
677
                    }
678
                }
679
                ObjectReference ref = context.get(theOriginal);
680
                if (ref == null) {
681
                    PersistentStateServices state = manager.createState(
682
                            theOriginal, context);
683
                    ref = context.get(state);
684
                }
685
                return ref;
686

    
687
            } else if (theOriginal instanceof Map) {
688
                if (field != null && field.getType() != DataTypes.MAP) {
689
                    throw new PersistenceInvalidTypeForPropertyException(
690
                            propName, definition, field, theOriginal);
691
                }
692
                Map result = new LinkedHashMap(((Map) theOriginal).size());
693
                storeValues(result, (Map) theOriginal);
694
                return result;
695

    
696
            } else if (theOriginal instanceof Set) {
697
                if (field != null && field.getType() != DataTypes.SET) {
698
                    throw new PersistenceInvalidTypeForPropertyException(
699
                            propName, definition, field, theOriginal);
700
                }
701
                Set result = new LinkedHashSet(((Set) theOriginal).size());
702
                storeValues(result, ((Set) theOriginal).iterator());
703
                return result;
704

    
705
            } else if (theOriginal instanceof List) {
706
                if (field != null
707
                        && !(field.getType() == DataTypes.LIST || field
708
                        .getType() == DataTypes.ARRAY)) {
709
                    throw new PersistenceInvalidTypeForPropertyException(
710
                            propName, definition, field, theOriginal);
711
                }
712
                List result = new ArrayList(((List) theOriginal).size());
713
                storeValues(result, (((List) theOriginal).iterator()));
714
                return result;
715

    
716
            } else if (theOriginal instanceof Iterator) {
717
                if (field != null
718
                        && !(field.getType() == DataTypes.LIST || field
719
                        .getType() == DataTypes.ARRAY)) {
720
                    throw new PersistenceInvalidTypeForPropertyException(
721
                            propName, definition, field, theOriginal);
722
                }
723
                List result = new ArrayList();
724

    
725
                storeValues(result, (Iterator) theOriginal);
726
                return result;
727

    
728
            } else {
729
                if (this.manager.getAutoValidation() == PersistenceManager.MANDATORY) {
730
                    throw new PersistenceTypeNotSupportedException(
731
                            theOriginal.getClass(), propName);
732
                } else {
733
                    logger.error("Persistence type '"
734
                            + theOriginal.getClass().getName()
735
                            + "' not supported.");
736
                    return null;
737
                }
738
            }
739
        } catch (PersistenceException ex) {
740
            PersistentContextServices context = (PersistentContextServices) this
741
                    .getContext();
742
            if (!context.getCollectErrors()) {
743
                throw ex;
744
            }
745
            context.addError(ex);
746
            return null;
747
        } catch (Exception ex) {
748
            PersistentContextServices context = (PersistentContextServices) this
749
                    .getContext();
750
            if (!context.getCollectErrors()) {
751
                throw new PersistenceException(ex);
752
            }
753
            context.addError(ex);
754
            return null;
755
        }
756
    }
757

    
758
    @Override
759
    public PersistentIdentifier getId() {
760
        return id;
761
    }
762

    
763
    @Override
764
    public void setValue(String name, Object value) throws PersistenceException {
765
        try {
766
            if (this.theClassName == null) {
767
                throw new PersistenceIllegalStateTheClassNameNotSetException();
768
            }
769
            if (!VALID_NAME_PATTERN.matcher(name).matches()) {
770
                throw new PersistenceInvalidPropertyNameException(name);
771
            }
772
            this.values.put(name, value);
773

    
774
        } catch (PersistenceException ex) {
775
            PersistentContextServices context = (PersistentContextServices) this
776
                    .getContext();
777
            if (!context.getCollectErrors()) {
778
                throw ex;
779
            }
780
            context.addError(ex);
781
        } catch (Exception ex) {
782
            PersistentContextServices context = (PersistentContextServices) this
783
                    .getContext();
784
            if (!context.getCollectErrors()) {
785
                throw new PersistenceException(ex);
786
            }
787
            context.addError(ex);
788
        }
789
    }
790

    
791
    @Override
792
    public String getTheClassName() {
793
        return theClassName;
794
    }
795

    
796
    /*
797
         * (non-Javadoc)
798
         *
799
         * @see org.gvsig.tools.persistence.impl.ImplementationPersistentState#
800
         * setTheClassName(java.lang.String)
801
     */
802
    @Override
803
    public void setTheClassName(String className) {
804
        theClassName = className;
805
    }
806

    
807
    private void storeValues(Collection storage, Iterator iter)
808
            throws PersistenceException {
809
        while (iter.hasNext()) {
810
            storage.add(getObjectToPersist(iter.next()));
811
        }
812

    
813
    }
814

    
815
    private void storeValues(Map storage, Map originalStorage)
816
            throws PersistenceException {
817
        Iterator iter = originalStorage.entrySet().iterator();
818
        Entry orgEntry;
819
        Object key;
820
        Object value;
821

    
822
        while (iter.hasNext()) {
823
            orgEntry = (Entry) iter.next();
824
            key = orgEntry.getKey();
825

    
826
            if (key == null) {
827
                // Nothing to do
828
            } else if (key instanceof String) {
829
                // Nothing to do
830
            } else if (key instanceof Number) {
831
                // Nothing to do
832
            } else if (key instanceof Boolean) {
833
                // Nothing to do
834
            } else if (key instanceof Persistent) {
835
                key = getObjectToPersist(key);
836
            } else {
837
                throw new PersistenceUnsuportedMapKeyTypeException(orgEntry
838
                        .getKey().getClass());
839
            }
840

    
841
            value = getObjectToPersist(orgEntry.getValue());
842

    
843
            storage.put(key, value);
844
        }
845

    
846
    }
847

    
848
    @Override
849
    public PersistentContext getContext() {
850
        return context;
851
    }
852

    
853
    @Override
854
    public boolean hasValue(String name) {
855
        return this.values.containsKey(name);
856
    }
857

    
858
    @Override
859
    public Object getValue(String name) {
860
        return values.get(name);
861
    }
862

    
863
    /**
864
     * Returns if the definition related to this state has a defined field
865
     */
866
    private boolean definitionHasField(String name) {
867
        DynStruct definition = manager.getDefinition(getTheClassName());
868
        return definition != null && definition.getDynField(name) != null;
869
    }
870

    
871
    private Object getDefaultValue(String name) {
872
        DynStruct definition = manager.getDefinition(getTheClassName());
873
        if (definition == null) {
874
            return null;
875
        }
876
        if (definition.getDynField(name) == null) {
877
            return null;
878
        }
879
        return definition.getDynField(name).getDefaultValue();
880
    }
881

    
882
    @Override
883
    public void relativizeFiles(File rootFolder) {
884
        PersistentContext context = this.getContext();
885

    
886
        URI cwd = new File(System.getProperty("user.dir")).toURI();
887
        Iterator statesIterator = context.iterator();
888
        while (statesIterator.hasNext()) {
889
            PersistentState aState = (PersistentState) statesIterator.next();
890
            DynStruct definition = aState.getDefinition();
891
            DynField[] fields = definition.getDynFields();
892
            for (int i = 0; i < fields.length; i++) {
893
                DynField field = fields[i];
894
                if (field.getType() == DataTypes.FILE
895
                        || field.getType() == DataTypes.FOLDER) {
896
                    try {
897
                        File value = aState.getFile(field.getName());
898
                        value = FileTools.relativizeFile(rootFolder, value);
899
                        aState.set(field.getName(), value);
900
                    } catch (PersistenceException e) {
901
                        logger.warn(
902
                                "Can't relativice field '" + field.getName()
903
                                + "' for class '"
904
                                + definition.getName() + "'.", e);
905
                    }
906
                } else if (field.getType() == DataTypes.URL) {
907
                    try {
908
                        URL value = aState.getURL(field.getName());
909
                        if (value != null && "FILE".equalsIgnoreCase(value.getProtocol())) {
910
                            File file = FileUtils.toFile(value);
911
                            if (FileTools.isInDifferentDrive(rootFolder, file)) {
912
                                /*
913
                                 * Different drives
914
                                 * (should happen only in Windows)
915
                                 */
916
                                value = file.toURI().toURL();
917
                            } else {
918
                                /*
919
                                * Both in the Same drive (C: D: etc) or Unix-style
920
                                 */
921
                                file = FileTools.relativizeFile(rootFolder, file);
922
                                value = new URL("file", "", file.toURI().toString().substring(cwd.toString().length()));
923
                            }
924
                            aState.set(field.getName(), value);
925
                        }
926
                    } catch (PersistenceException | MalformedURLException e) {
927
                        // do nothind
928
                    }
929

    
930
                } else if (field.getType() == DataTypes.URI) {
931
                    try {
932
                        URI value = aState.getURI(field.getName());
933
                        if (value != null
934
                                && (value.getScheme() == null || "FILE".equalsIgnoreCase(value.getScheme()))) {
935
                            File file = new File(value.getPath());
936
                            if (FileTools.isInDifferentDrive(rootFolder, file)) {
937
                                /*
938
                                 * Different drives
939
                                 * (should happen only in Windows)
940
                                 */
941
                                value = file.toURI();
942
                            } else {
943
                                /*
944
                                * Both in the Same drive (C: D: etc) or Unix-style
945
                                 */
946
                                file = FileTools.relativizeFile(rootFolder, file);
947
                                value = new URI(file.getPath());
948
                            }
949
                            aState.set(field.getName(), value);
950
                        }
951
                    } catch (PersistenceException | URISyntaxException e) {
952
                        // do nothind
953
                    }
954

    
955
                }
956
            }
957
        }
958
    }
959

    
960
    @Override
961
    public void derelativizeFiles(File rootFolder) {
962
        PersistentContext context = this.getContext();
963
        //URI cwd = new File(System.getProperty("user.dir")).toURI();
964

    
965
        Iterator statesIterator = context.iterator();
966
        String className;
967

    
968
        while (statesIterator.hasNext()) {
969
            PersistentState aState = (PersistentState) statesIterator.next();
970
            if (aState == null) {
971
                continue;
972
            }
973
            try {
974
                className = aState.getTheClassName();
975
            } catch (Throwable e) {
976
                className = "Unknown";
977
            }
978
            try {
979
                DynStruct definition = aState.getDefinition();
980
                if (definition == null) {
981
                    continue;
982
                }
983
                DynField[] fields = definition.getDynFields();
984
                for (int i = 0; i < fields.length; i++) {
985
                    DynField field = fields[i];
986
                    if (field.getType() == DataTypes.FILE
987
                            || field.getType() == DataTypes.FOLDER) {
988
                        try {
989
                            File value = aState.getFile(field.getName());
990
                            value = FileTools.derelativizeFile(rootFolder, value);
991
                            aState.set(field.getName(), value);
992
                        } catch (PersistenceException e) {
993
                            logger.warn(
994
                                    "Can't fix field '" + field.getName()
995
                                    + "' for class '"
996
                                    + definition.getName() + "'.", e);
997
                        }
998
                    } else if (field.getType() == DataTypes.URL) {
999
                        try {
1000
                            URL value = aState.getURL(field.getName());
1001
                            if (value != null && "FILE".equalsIgnoreCase(value.getProtocol())) {
1002
                                if (!value.getFile().startsWith("/")) {
1003
                                    File file = FileUtils.toFile(value);
1004
                                    file = FileTools.derelativizeFile(rootFolder, file);
1005
                                    value = file.toURI().toURL();
1006
                                    aState.set(field.getName(), value);
1007
                                }
1008
                            }
1009
                        } catch (PersistenceException | MalformedURLException e) {
1010
                            // do nothing
1011
                        }
1012

    
1013
                    } else if (field.getType() == DataTypes.URI) {
1014
                        try {
1015
                            URI value = aState.getURI(field.getName());
1016
                            if ((value != null) && (value.getScheme() == null || "FILE".equalsIgnoreCase(value.getScheme()))) {
1017
                                if (!value.isAbsolute() || !value.getPath().startsWith("/")) {
1018
                                    File file;
1019
                                    file = new File(value.getPath());
1020
                                    file = FileTools.derelativizeFile(rootFolder, file);
1021
                                    aState.set(field.getName(), file.toURI());
1022
                                }
1023
                            }
1024
                        } catch (PersistenceException e) {
1025
                            // do nothing
1026
                        }
1027
                    }
1028

    
1029
                }
1030
            } catch (RuntimeException e) {
1031
                String msg = "Can't fix relative paths in '" + className + "'";
1032
                if (context.getCollectErrors()) {
1033
                    context.addError(new RuntimeException(msg));
1034
                }
1035
                logger.info(msg, e);
1036
            }
1037
        }
1038
    }
1039

    
1040
    @Override
1041
    public int getInt(String name, int defaultValue)
1042
            throws PersistenceException {
1043
        try {
1044
            return getInt(name);
1045
        } catch (Exception ex) {
1046
            return defaultValue;
1047
        }
1048
    }
1049

    
1050
    @Override
1051
    public long getLong(String name, long defaultValue)
1052
            throws PersistenceException {
1053
        try {
1054
            return getLong(name);
1055
        } catch (Exception ex) {
1056
            return defaultValue;
1057
        }
1058
    }
1059

    
1060
    @Override
1061
    public double getDouble(String name, double defaultValue)
1062
            throws PersistenceException {
1063
        try {
1064
            return getDouble(name);
1065
        } catch (Exception ex) {
1066
            return defaultValue;
1067
        }
1068
    }
1069

    
1070
    @Override
1071
    public float getFloat(String name, float defaultValue)
1072
            throws PersistenceException {
1073
        try {
1074
            return getFloat(name);
1075
        } catch (Exception ex) {
1076
            return defaultValue;
1077
        }
1078
    }
1079

    
1080
    @Override
1081
    public boolean getBoolean(String name, boolean defaultValue)
1082
            throws PersistenceException {
1083
        try {
1084
            return getBoolean(name);
1085
        } catch (Exception ex) {
1086
            return defaultValue;
1087
        }
1088
    }
1089
}