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 @ 44488

History | View | Annotate | Download (13.5 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
public class DefaultFeatureReference implements
49
                FeatureReferenceProviderServices, Persistent {
50

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

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

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

    
104
        }
105

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

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

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

    
182
        private void calculatePK(FeatureProvider fdata) {
183
            FeatureAttributeDescriptor[] pkattrs = fdata.getType().getPrimaryKey();
184
            if( ArrayUtils.isEmpty(pkattrs) ) {
185
                this.pk = null;
186
                this.pkNames = null;
187
                return ;
188
            }
189
            this.pk = new Object[pkattrs.length];
190
            this.pkNames = new String[pkattrs.length];
191
            int n = 0;
192
            for (FeatureAttributeDescriptor pkattr : pkattrs) {
193
                this.pk[n] = fdata.get(pkattr.getIndex());
194
                this.pkNames[n] = pkattr.getName();
195
                n++;
196
            }
197
    }
198

    
199
    @Override
200
        public Feature getFeature() throws DataException {
201
                return this.getStore().getFeatureByReference(this);
202
        }
203

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

    
209
    @Override
210
        public Object getOID() {
211
                return this.oid;
212
        }
213

    
214
    @Override
215
        public boolean isNewFeature() {
216
                return this.isNewFeature;
217
        }
218

    
219

    
220
    @Override
221
        public boolean equals(Object obj) {
222
                if (!(obj instanceof DefaultFeatureReference)) {
223
                        return false;
224
                }
225
                DefaultFeatureReference other = (DefaultFeatureReference) obj;
226

    
227
                FeatureStore otherStore = (FeatureStore) other.storeRef.get();
228
                FeatureStore myrStore = (FeatureStore) this.storeRef.get();
229
                if (otherStore == null || myrStore == null) {
230
                        return false;
231
                }
232
                if (!myrStore.equals(otherStore)) {
233
                        return false;
234
                }
235
                if (myHashCode != null && other.myHashCode != null) {
236
                        return myHashCode.equals(other.myHashCode);
237
                }
238
                if (this.oid != null) {
239
                        return this.oid.equals(other.oid);
240
                }
241
                if(pk != null) {
242
                        if(other.pk == null) {
243
                                return false;
244
                        }
245
                    for (int i = 0; i < this.pk.length; i++) {
246
                            if (!this.pk[i].equals(other.pk[i])) {
247
                                    return false;
248
                            }
249
                    }
250
                }
251
                return true;
252
        }
253

    
254
    @Override
255
        public int hashCode() {
256
                if (this.oid != null) {
257
                        return this.oid.hashCode();
258
                }
259
                if (myHashCode == null) {
260
                        StringBuilder buff = new StringBuilder();
261

    
262
                        for (int i = 0; i < this.pk.length; i++) {
263
                                buff.append(Objects.hashCode(this.pk[i]));
264
                                buff.append("##");
265
                        }
266
                        myHashCode = buff.toString().hashCode();
267
                }
268
                return myHashCode;
269
        }
270

    
271
    @Override
272
        public String[] getKeyNames() {
273
                return pkNames;
274
        }
275

    
276
    @Override
277
        public Object getKeyValue(String name) {
278
                for (int i = 0; i < pkNames.length; i++) {
279
                        if (pkNames[i].equalsIgnoreCase(name)) {
280
                                return pk[i];
281
                        }
282
                }
283
                // FIXME exception????
284
                return null;
285
        }
286

    
287
    @Override
288
        public String getFeatureTypeId() {
289
                return featureTypeId;
290
        }
291

    
292
        // *** Persistence ***
293

    
294
    @Override
295
        public void loadFromState(PersistentState state)
296
                        throws PersistenceException {
297
                this.oid = state.get("oid");
298
                this.myHashCode = (Integer) state.get("myHashCode");
299
                this.storeRef = new WeakReference(state.get("store"));
300
                this.isNewFeature = state.getBoolean("isNewFeature");
301
                this.featureTypeId = state.getString("featureTypeId");
302
                List pkList = (List) state.get("pk");
303
                if (pkList != null) {
304
                        List pkNamesList = (List) state.get("pkNames");
305
                        if (pkNamesList == null || pkList.size() != pkNamesList.size()) {
306
                                throw new PersistenceException("bad pkNames value");
307
                        }
308
                        this.pk = pkList.toArray();
309
            this.pkNames =
310
                (String[]) pkNamesList.toArray(new String[pkList.size()]);
311
                } else {
312
                        this.pk = null;
313
                        this.pkNames = null;
314
                }
315
        }
316

    
317
    @Override
318
        public void saveToState(PersistentState state) throws PersistenceException {
319
                state.set("oid", oid);
320
                state.set("myHashCode", myHashCode);
321
                state.set("isNewFeature", isNewFeature);
322
                state.set("store", (Persistent) storeRef.get());
323
                state.set("featureTypeId", featureTypeId);
324
                if (pk == null) {
325
                        state.setNull("pk");
326
                        state.setNull("pkNames");
327
                } else {
328
                        state.set("pk", pk);
329
                        state.set("pkNames", pkNames);
330
                }
331

    
332
        }
333
        
334
        @Override
335
        public String getCode() {
336
//            JSONObject x = new JSONObject();
337
////            x.put("store", (Persistent) storeRef.get());
338
//            x.put("oid", oid);
339
//            x.put("myHashCode", myHashCode);
340
//            x.put("isNewFeature", isNewFeature);
341
//            x.put("featureTypeId", featureTypeId);
342
//            if( this.pk == null ) {
343
//                x.put("pkNames_size", -1);
344
//                x.put("pkNames", JSONObject.NULL);
345
//                x.put("pk", JSONObject.NULL);
346
//            } else {
347
//                x.put("pkNames_size", pkNames.length);
348
//                x.put("pkNames", new JSONArray(this.pkNames));
349
//                x.put("pk", new JSONArray(this.pk));
350
//            }
351
//
352
            Object[] data = new Object[7];
353
            data[OID_INDEX] = this.oid;
354
            data[MYHASHCODE_INDEX] = this.myHashCode;
355
            data[ISNEWFEATURE_INDEX] = this.isNewFeature;
356
            data[FEATURETYPEID_INDEX] = this.featureTypeId;
357
            if( this.pk == null ) {
358
                data[PKNAMES_SIZE_INDEX] = -1;
359
                data[PKNAMES_INDEX] = JSONObject.NULL;
360
                data[PK_INDEX] = JSONObject.NULL;
361
            } else {
362
                data[PKNAMES_SIZE_INDEX] = pkNames.length;
363
                data[PKNAMES_INDEX] = new JSONArray(this.pkNames);
364
                data[PK_INDEX] = new JSONArray(this.pk);            
365
            }            
366
            String s = new JSONArray(data).toString();
367
            String r = Base64.getEncoder().encodeToString(s.getBytes());
368
            
369
            return r;
370
        }
371

    
372
        public static void registerPersistent() {
373
                DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
374
                                DefaultFeatureReference.class, 
375
                                "Reference", 
376
                                "DefaultFeatureReference Persistent definition", 
377
                                null, 
378
                                null
379
                        );
380

    
381
                definition.addDynFieldObject("oid")
382
                        .setClassOfValue(Object.class)
383
                        .setMandatory(false)
384
                        .setPersistent(true);
385
                        
386
                definition.addDynFieldBoolean("isNewFeature")
387
                        .setMandatory(true)
388
                        .setPersistent(true);
389
        
390
                definition.addDynFieldObject("store")
391
                        .setClassOfValue(FeatureStore.class)
392
                        .setMandatory(true)
393
                        .setPersistent(true);
394

    
395
                definition.addDynFieldInt("myHashCode")
396
                        .setMandatory(false)
397
                        .setPersistent(true);
398
        
399
                definition.addDynFieldString("featureTypeId")
400
                        .setMandatory(true)
401
                        .setPersistent(true);
402

    
403
                definition.addDynFieldArray("pk")
404
                        .setClassOfItems(Object.class)
405
                        .setMandatory(false)
406
                        .setPersistent(true);
407

    
408
        definition.addDynFieldArray("pkNames")
409
                        .setClassOfItems(String.class)
410
                        .setMandatory(false)
411
                        .setPersistent(true);
412

    
413
        }
414

    
415
    @Override
416
        public String toString() {
417
        StringBuilder builder = new StringBuilder();
418
        builder.append("FeatureReference: oid = ");
419
        builder.append(oid);
420
        if( myHashCode!=null ) {
421
            builder.append(", myHashCode = ");
422
            builder.append(myHashCode);
423
        } 
424
        if( pk!=null ) {
425
            builder.append(", pks = ");
426
            builder.append(Arrays.asList(pk));
427
        }
428
        if( pkNames!=null ) {
429
            builder.append(", pkNames = ");
430
            builder.append(Arrays.asList(pkNames));
431
        }
432
        if( isNewFeature ) {
433
            builder.append(", isNew = ");
434
            builder.append(isNewFeature);
435
        }
436
        if( featureTypeId!=null ) {
437
            builder.append(", featureTypeId = ");
438
            builder.append(featureTypeId);
439
        }
440
        return builder.toString();
441
        }
442

    
443
}