Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / featurereference / DefaultFeatureReference.java @ 45647

History | View | Annotate | Download (14.1 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.impl.featurereference;
25

    
26
import java.lang.ref.WeakReference;
27
import java.util.Arrays;
28
import java.util.Base64;
29
import java.util.List;
30
import java.util.Objects;
31
import org.apache.commons.lang3.ArrayUtils;
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.dal.feature.FeatureType;
37
import org.gvsig.fmap.dal.feature.impl.DefaultFeature;
38
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
39
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
40
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
41
import org.gvsig.tools.ToolsLocator;
42
import org.gvsig.tools.dynobject.DynStruct;
43
import org.gvsig.tools.persistence.Persistent;
44
import org.gvsig.tools.persistence.PersistentState;
45
import org.gvsig.tools.persistence.exception.PersistenceException;
46
import org.json.JSONArray;
47
import org.json.JSONObject;
48

    
49
@SuppressWarnings("UseSpecificCatch")
50
public class DefaultFeatureReference implements
51
                FeatureReferenceProviderServices, Persistent {
52

    
53
        private Object oid;
54
        private Integer myHashCode = null;
55
        private Object[] pk;
56
        private String[] pkNames;
57
        private WeakReference storeRef;
58
        private boolean isNewFeature;
59
        private String featureTypeId;
60
         
61
        
62
        private static final int OID_INDEX = 0;
63
        private static final int MYHASHCODE_INDEX = 1;
64
        private static final int ISNEWFEATURE_INDEX = 2;
65
        private static final int FEATURETYPEID_INDEX = 3;
66
        private static final int PKNAMES_SIZE_INDEX = 4;
67
        private static final int PKNAMES_INDEX = 5;
68
        private static final int PK_INDEX = 6;
69
        
70
        /**
71
     * Constructor used by the persistence manager. Don't use directly.
72
     * After to invoke this method, the persistence manager calls 
73
     * the the method {@link #loadFromState(PersistentState)} to set 
74
     * the values of the internal attributes that this class needs to work.
75
     */
76
        public DefaultFeatureReference() {
77
                super();                
78
        }
79
        
80
        public DefaultFeatureReference(DefaultFeature feature) {
81
                this(feature.getStore(), feature.getData());
82
        }
83

    
84
        public DefaultFeatureReference(FeatureStore store,
85
                        FeatureProvider fdata) {
86
                this.isNewFeature = fdata.isNew();
87
                this.oid = null;
88
                this.pk = null;
89
                this.storeRef = new WeakReference(store);
90
                this.featureTypeId = fdata.getType().getId();
91

    
92
                if (fdata.getType().hasOID() || isNewFeature) {
93
                        this.oid = fdata.getOID();
94
                        if (this.oid == null) {
95
                                // FIXME Exception
96
                                throw new RuntimeException("Missing OID");
97
                        }
98
                } else {
99
                        this.calculatePK(fdata);
100
                        if (this.pk == null) {
101
                                // FIXME Exception
102
                                throw new RuntimeException("Missing pk attributes");
103
                        }
104
                }
105

    
106
        }
107

    
108
        /*
109
         * Use only for Persistent.setState
110
         */
111
//        public DefaultFeatureReference(FeatureStore store) {
112
//                this.isNewFeature = false;
113
//                this.oid = null;
114
//                this.pk = null;
115
//                this.storeRef = new WeakReference(store);
116
//        }
117

    
118
        public DefaultFeatureReference(FeatureStore store, Object oid) {
119
                // FIXME featureTypeId is needed !!!
120
                this.isNewFeature = false;
121
                this.oid = oid;
122
                this.pk = null;
123
                this.storeRef = new WeakReference(store);
124
        }
125

    
126
        public DefaultFeatureReference(FeatureStore store, String code) {
127
            this.storeRef = new WeakReference(store);
128
            
129
            String json = new String(Base64.getDecoder().decode(code.getBytes()));
130
            
131
            JSONArray x = new JSONArray(json);
132
            this.oid = x.get(OID_INDEX);
133
            if( x.get(MYHASHCODE_INDEX)==JSONObject.NULL ) {
134
                this.myHashCode = null;
135
            } else {
136
                this.myHashCode = x.getInt(MYHASHCODE_INDEX);
137
            }
138
            this.isNewFeature = x.getBoolean(ISNEWFEATURE_INDEX);
139
            this.featureTypeId = x.getString(FEATURETYPEID_INDEX);
140
            int pkNames_size = x.getInt(PKNAMES_SIZE_INDEX);
141
            if( pkNames_size<0 ) {
142
                this.pk = null;
143
                this.pkNames = null;
144
            } else {
145
                this.pk = new Object[pkNames_size];
146
                this.pkNames = new String[pkNames_size];
147
                JSONArray xx = x.getJSONArray(PKNAMES_INDEX);
148
                for( int i=0; i<xx.length(); i++ ) {
149
                    this.pkNames[i] = xx.getString(i);
150
                }
151
                xx = x.getJSONArray(PKNAMES_INDEX);
152
                for( int i=0; i<xx.length(); i++ ) {
153
                    this.pk[i] = xx.get(i);
154
                }
155
            }
156
            
157
//            JSONObject x = new JSONObject(json);
158
//            this.oid = x.get("oid");
159
//            this.myHashCode = x.getInt("myHashCode");
160
//            this.isNewFeature = x.getBoolean("isNewFeature");
161
//            this.featureTypeId = x.getString("featureTypeId");
162
//            int pkNames_size = x.getInt("pkNames_size");
163
//            if( pkNames_size<0 ) {
164
//                this.pk = null;
165
//                this.pkNames = null;
166
//            } else {
167
//                this.pk = new Object[pkNames_size];
168
//                this.pkNames = new String[pkNames_size];
169
//                JSONArray xx = x.getJSONArray("pkNames");
170
//                for( int i=0; i<xx.length(); i++ ) {
171
//                    this.pkNames[i] = xx.getString(i);
172
//                }
173
//                xx = x.getJSONArray("pk");
174
//                for( int i=0; i<xx.length(); i++ ) {
175
//                    this.pk[i] = xx.get(i);
176
//                }
177
//            }
178
        }
179
        
180
        private DefaultFeatureStore getStore() {
181
                return (DefaultFeatureStore) this.storeRef.get();
182
        }
183

    
184
        public void calculatePK(FeatureProvider fdata) { // Usado en los test de BBDD
185
            FeatureAttributeDescriptor[] pkattrs = fdata.getType().getPrimaryKey();
186
            if( ArrayUtils.isEmpty(pkattrs) ) {
187
                this.pk = null;
188
                this.pkNames = null;
189
                return ;
190
            }
191
            this.pk = new Object[pkattrs.length];
192
            this.pkNames = new String[pkattrs.length];
193
            int n = 0;
194
            for (FeatureAttributeDescriptor pkattr : pkattrs) {
195
//                if( pkattr.isAutomatic() ) {
196
//                    this.pk = null;
197
//                    this.pkNames = null;
198
//                    return ;
199
//                }
200
                this.pk[n] = fdata.get(pkattr.getIndex());
201
                this.pkNames[n] = pkattr.getName();
202
                n++;
203
            }
204
    }
205

    
206
    @Override
207
    public Feature getFeature() throws DataException {
208
        return this.getStore().getFeatureByReference(this);
209
    }
210

    
211
    @Override
212
    public Feature getFeatureQuietly() {
213
        try {
214
            return this.getFeature();
215
        } catch(Exception ex) {
216
            return null;
217
        }
218
    }
219

    
220
    @Override
221
        public Feature getFeature(FeatureType featureType) throws DataException {
222
                return this.getStore().getFeatureByReference(this, featureType);
223
        }
224

    
225
    @Override
226
        public Object getOID() {
227
                return this.oid;
228
        }
229

    
230
    @Override
231
        public boolean isNewFeature() {
232
                return this.isNewFeature;
233
        }
234

    
235

    
236
    @Override
237
        public boolean equals(Object obj) {
238
                if (!(obj instanceof DefaultFeatureReference)) {
239
                        return false;
240
                }
241
                DefaultFeatureReference other = (DefaultFeatureReference) obj;
242

    
243
                FeatureStore otherStore = (FeatureStore) other.storeRef.get();
244
                FeatureStore myrStore = (FeatureStore) this.storeRef.get();
245
                if (otherStore == null || myrStore == null) {
246
                        return false;
247
                }
248
                if (!myrStore.equals(otherStore)) {
249
                        return false;
250
                }
251
                if (myHashCode != null && other.myHashCode != null) {
252
                        return myHashCode.equals(other.myHashCode);
253
                }
254
                if (this.oid != null) {
255
                        return this.oid.equals(other.oid);
256
                }
257
                if(pk != null) {
258
                        if(other.pk == null) {
259
                                return false;
260
                        }
261
                    for (int i = 0; i < this.pk.length; i++) {
262
                            if (!this.pk[i].equals(other.pk[i])) {
263
                                    return false;
264
                            }
265
                    }
266
                }
267
                return true;
268
        }
269

    
270
    @Override
271
        public int hashCode() {
272
                if (this.oid != null) {
273
                        return this.oid.hashCode();
274
                }
275
                if (myHashCode == null) {
276
                        StringBuilder buff = new StringBuilder();
277

    
278
                        for (int i = 0; i < this.pk.length; i++) {
279
                                buff.append(Objects.hashCode(this.pk[i]));
280
                                buff.append("##");
281
                        }
282
                        myHashCode = buff.toString().hashCode();
283
                }
284
                return myHashCode;
285
        }
286

    
287
    @Override
288
        public String[] getKeyNames() {
289
                return pkNames;
290
        }
291

    
292
    @Override
293
        public Object getKeyValue(String name) {
294
                for (int i = 0; i < pkNames.length; i++) {
295
                        if (pkNames[i].equalsIgnoreCase(name)) {
296
                                return pk[i];
297
                        }
298
                }
299
                // FIXME exception????
300
                return null;
301
        }
302

    
303
    @Override
304
        public String getFeatureTypeId() {
305
                return featureTypeId;
306
        }
307

    
308
        // *** Persistence ***
309

    
310
    @Override
311
        public void loadFromState(PersistentState state)
312
                        throws PersistenceException {
313
                this.oid = state.get("oid");
314
                this.myHashCode = (Integer) state.get("myHashCode");
315
                this.storeRef = new WeakReference(state.get("store"));
316
                this.isNewFeature = state.getBoolean("isNewFeature");
317
                this.featureTypeId = state.getString("featureTypeId");
318
                List pkList = (List) state.get("pk");
319
                if (pkList != null) {
320
                        List pkNamesList = (List) state.get("pkNames");
321
                        if (pkNamesList == null || pkList.size() != pkNamesList.size()) {
322
                                throw new PersistenceException("bad pkNames value");
323
                        }
324
                        this.pk = pkList.toArray();
325
            this.pkNames =
326
                (String[]) pkNamesList.toArray(new String[pkList.size()]);
327
                } else {
328
                        this.pk = null;
329
                        this.pkNames = null;
330
                }
331
        }
332

    
333
    @Override
334
        public void saveToState(PersistentState state) throws PersistenceException {
335
                state.set("oid", oid);
336
                state.set("myHashCode", myHashCode);
337
                state.set("isNewFeature", isNewFeature);
338
                state.set("store", (Persistent) storeRef.get());
339
                state.set("featureTypeId", featureTypeId);
340
                if (pk == null) {
341
                        state.setNull("pk");
342
                        state.setNull("pkNames");
343
                } else {
344
                        state.set("pk", pk);
345
                        state.set("pkNames", pkNames);
346
                }
347

    
348
        }
349
        
350
        @Override
351
        public String getCode() {
352
//            JSONObject x = new JSONObject();
353
////            x.put("store", (Persistent) storeRef.get());
354
//            x.put("oid", oid);
355
//            x.put("myHashCode", myHashCode);
356
//            x.put("isNewFeature", isNewFeature);
357
//            x.put("featureTypeId", featureTypeId);
358
//            if( this.pk == null ) {
359
//                x.put("pkNames_size", -1);
360
//                x.put("pkNames", JSONObject.NULL);
361
//                x.put("pk", JSONObject.NULL);
362
//            } else {
363
//                x.put("pkNames_size", pkNames.length);
364
//                x.put("pkNames", new JSONArray(this.pkNames));
365
//                x.put("pk", new JSONArray(this.pk));
366
//            }
367
//
368
            Object[] data = new Object[7];
369
            data[OID_INDEX] = this.oid;
370
            data[MYHASHCODE_INDEX] = this.myHashCode;
371
            data[ISNEWFEATURE_INDEX] = this.isNewFeature;
372
            data[FEATURETYPEID_INDEX] = this.featureTypeId;
373
            if( this.pk == null ) {
374
                data[PKNAMES_SIZE_INDEX] = -1;
375
                data[PKNAMES_INDEX] = JSONObject.NULL;
376
                data[PK_INDEX] = JSONObject.NULL;
377
            } else {
378
                data[PKNAMES_SIZE_INDEX] = pkNames.length;
379
                data[PKNAMES_INDEX] = new JSONArray(this.pkNames);
380
                data[PK_INDEX] = new JSONArray(this.pk);            
381
            }            
382
            String s = new JSONArray(data).toString();
383
            String r = Base64.getEncoder().encodeToString(s.getBytes());
384
            
385
            return r;
386
        }
387

    
388
        public static void registerPersistent() {
389
                DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
390
                                DefaultFeatureReference.class, 
391
                                "Reference", 
392
                                "DefaultFeatureReference Persistent definition", 
393
                                null, 
394
                                null
395
                        );
396

    
397
                definition.addDynFieldObject("oid")
398
                        .setClassOfValue(Object.class)
399
                        .setMandatory(false)
400
                        .setPersistent(true);
401
                        
402
                definition.addDynFieldBoolean("isNewFeature")
403
                        .setMandatory(true)
404
                        .setPersistent(true);
405
        
406
                definition.addDynFieldObject("store")
407
                        .setClassOfValue(FeatureStore.class)
408
                        .setMandatory(true)
409
                        .setPersistent(true);
410

    
411
                definition.addDynFieldInt("myHashCode")
412
                        .setMandatory(false)
413
                        .setPersistent(true);
414
        
415
                definition.addDynFieldString("featureTypeId")
416
                        .setMandatory(true)
417
                        .setPersistent(true);
418

    
419
                definition.addDynFieldArray("pk")
420
                        .setClassOfItems(Object.class)
421
                        .setMandatory(false)
422
                        .setPersistent(true);
423

    
424
        definition.addDynFieldArray("pkNames")
425
                        .setClassOfItems(String.class)
426
                        .setMandatory(false)
427
                        .setPersistent(true);
428

    
429
        }
430

    
431
    @Override
432
        public String toString() {
433
        StringBuilder builder = new StringBuilder();
434
        builder.append("FeatureReference: oid = ");
435
        builder.append(oid);
436
        if( myHashCode!=null ) {
437
            builder.append(", myHashCode = ");
438
            builder.append(myHashCode);
439
        } 
440
        if( pk!=null ) {
441
            builder.append(", pks = ");
442
            builder.append(Arrays.asList(pk));
443
        }
444
        if( pkNames!=null ) {
445
            builder.append(", pkNames = ");
446
            builder.append(Arrays.asList(pkNames));
447
        }
448
        if( isNewFeature ) {
449
            builder.append(", isNew = ");
450
            builder.append(isNewFeature);
451
        }
452
        if( featureTypeId!=null ) {
453
            builder.append(", featureTypeId = ");
454
            builder.append(featureTypeId);
455
        }
456
        return builder.toString();
457
        }
458

    
459
}