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 / DefaultFeatureReference.java @ 45639

History | View | Annotate | Download (14 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;
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

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
39
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
40
import org.gvsig.tools.ToolsLocator;
41
import org.gvsig.tools.dynobject.DynStruct;
42
import org.gvsig.tools.persistence.Persistent;
43
import org.gvsig.tools.persistence.PersistentState;
44
import org.gvsig.tools.persistence.exception.PersistenceException;
45
import org.json.JSONArray;
46
import org.json.JSONObject;
47

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

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

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

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

    
105
        }
106

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

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

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

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

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

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

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

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

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

    
234

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

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

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

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

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

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

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

    
307
        // *** Persistence ***
308

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

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

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

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

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

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

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

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

    
428
        }
429

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

    
458
}