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

History | View | Annotate | Download (13.5 KB)

1 40559 jjdelcerro
/**
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 40435 jjdelcerro
package org.gvsig.fmap.dal.feature.impl;
25
26
import java.lang.ref.WeakReference;
27
import java.util.Arrays;
28 43824 jjdelcerro
import java.util.Base64;
29 40435 jjdelcerro
import java.util.List;
30 43358 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
31 40435 jjdelcerro
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.spi.FeatureProvider;
38
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.dynobject.DynStruct;
41
import org.gvsig.tools.persistence.Persistent;
42
import org.gvsig.tools.persistence.PersistentState;
43
import org.gvsig.tools.persistence.exception.PersistenceException;
44 43824 jjdelcerro
import org.json.JSONArray;
45
import org.json.JSONObject;
46 40435 jjdelcerro
47
public class DefaultFeatureReference implements
48
                FeatureReferenceProviderServices, Persistent {
49
50
        private Object oid;
51
        private Integer myHashCode = null;
52
        private Object[] pk;
53
        private String[] pkNames;
54
        private WeakReference storeRef;
55
        private boolean isNewFeature;
56
        private String featureTypeId;
57
58 43824 jjdelcerro
59
        private final int OID_INDEX = 0;
60
        private final int MYHASHCODE_INDEX = 1;
61
        private final int ISNEWFEATURE_INDEX = 2;
62
        private final int FEATURETYPEID_INDEX = 3;
63
        private final int PKNAMES_SIZE_INDEX = 4;
64
        private final int PKNAMES_INDEX = 5;
65
        private final int PK_INDEX = 6;
66
67 40435 jjdelcerro
        /**
68
     * Constructor used by the persistence manager. Don't use directly.
69
     * After to invoke this method, the persistence manager calls
70
     * the the method {@link #loadFromState(PersistentState)} to set
71
     * the values of the internal attributes that this class needs to work.
72
     */
73
        public DefaultFeatureReference() {
74
                super();
75
        }
76
77
        public DefaultFeatureReference(DefaultFeature feature) {
78
                this(feature.getStore(), feature.getData());
79
        }
80
81
        public DefaultFeatureReference(FeatureStore store,
82
                        FeatureProvider fdata) {
83
                this.isNewFeature = fdata.isNew();
84
                this.oid = null;
85
                this.pk = null;
86
                this.storeRef = new WeakReference(store);
87
                this.featureTypeId = fdata.getType().getId();
88
89
                if (fdata.getType().hasOID() || isNewFeature) {
90
                        this.oid = fdata.getOID();
91
                        if (this.oid == null) {
92
                                // FIXME Exception
93
                                throw new RuntimeException("Missing OID");
94
                        }
95
                } else {
96
                        this.calculatePK(fdata);
97
                        if (this.pk == null) {
98
                                // FIXME Exception
99
                                throw new RuntimeException("Missing pk attributes");
100
                        }
101
                }
102
103
        }
104
105
        /*
106
         * Use only for Persistent.setState
107
         */
108
        public DefaultFeatureReference(FeatureStore store) {
109
                this.isNewFeature = false;
110
                this.oid = null;
111
                this.pk = null;
112
                this.storeRef = new WeakReference(store);
113
        }
114
115
        public DefaultFeatureReference(FeatureStore store, Object oid) {
116
                // FIXME featureTypeId is needed !!!
117
                this.isNewFeature = false;
118
                this.oid = oid;
119
                this.pk = null;
120
                this.storeRef = new WeakReference(store);
121
        }
122
123 43824 jjdelcerro
        public DefaultFeatureReference(FeatureStore store, String code) {
124
            this.storeRef = new WeakReference(store);
125
126
            String json = new String(Base64.getDecoder().decode(code.getBytes()));
127
128
            JSONArray x = new JSONArray(json);
129
            this.oid = x.get(OID_INDEX);
130
            if( x.get(MYHASHCODE_INDEX)==JSONObject.NULL ) {
131
                this.myHashCode = null;
132
            } else {
133
                this.myHashCode = x.getInt(MYHASHCODE_INDEX);
134
            }
135
            this.isNewFeature = x.getBoolean(ISNEWFEATURE_INDEX);
136
            this.featureTypeId = x.getString(FEATURETYPEID_INDEX);
137
            int pkNames_size = x.getInt(PKNAMES_SIZE_INDEX);
138
            if( pkNames_size<0 ) {
139
                this.pk = null;
140
                this.pkNames = null;
141
            } else {
142
                this.pk = new Object[pkNames_size];
143
                this.pkNames = new String[pkNames_size];
144
                JSONArray xx = x.getJSONArray(PKNAMES_INDEX);
145
                for( int i=0; i<xx.length(); i++ ) {
146
                    this.pkNames[i] = xx.getString(i);
147
                }
148
                xx = x.getJSONArray(PKNAMES_INDEX);
149
                for( int i=0; i<xx.length(); i++ ) {
150
                    this.pk[i] = xx.get(i);
151
                }
152
            }
153
154
//            JSONObject x = new JSONObject(json);
155
//            this.oid = x.get("oid");
156
//            this.myHashCode = x.getInt("myHashCode");
157
//            this.isNewFeature = x.getBoolean("isNewFeature");
158
//            this.featureTypeId = x.getString("featureTypeId");
159
//            int pkNames_size = x.getInt("pkNames_size");
160
//            if( pkNames_size<0 ) {
161
//                this.pk = null;
162
//                this.pkNames = null;
163
//            } else {
164
//                this.pk = new Object[pkNames_size];
165
//                this.pkNames = new String[pkNames_size];
166
//                JSONArray xx = x.getJSONArray("pkNames");
167
//                for( int i=0; i<xx.length(); i++ ) {
168
//                    this.pkNames[i] = xx.getString(i);
169
//                }
170
//                xx = x.getJSONArray("pk");
171
//                for( int i=0; i<xx.length(); i++ ) {
172
//                    this.pk[i] = xx.get(i);
173
//                }
174
//            }
175
        }
176
177
        private DefaultFeatureStore getStore() {
178 40435 jjdelcerro
                return (DefaultFeatureStore) this.storeRef.get();
179
        }
180
181
        private void calculatePK(FeatureProvider fdata) {
182 43358 jjdelcerro
            FeatureAttributeDescriptor[] pkattrs = fdata.getType().getPrimaryKey();
183
            if( ArrayUtils.isEmpty(pkattrs) ) {
184
                this.pk = null;
185
                this.pkNames = null;
186
                return ;
187
            }
188
            this.pk = new Object[pkattrs.length];
189
            this.pkNames = new String[pkattrs.length];
190
            int n = 0;
191
            for (FeatureAttributeDescriptor pkattr : pkattrs) {
192
                this.pk[n] = fdata.get(pkattr.getIndex());
193
                this.pkNames[n] = pkattr.getName();
194
                n++;
195
            }
196
    }
197 40435 jjdelcerro
198 43358 jjdelcerro
    @Override
199 40435 jjdelcerro
        public Feature getFeature() throws DataException {
200
                return this.getStore().getFeatureByReference(this);
201
        }
202
203 43358 jjdelcerro
    @Override
204 40435 jjdelcerro
        public Feature getFeature(FeatureType featureType) throws DataException {
205
                return this.getStore().getFeatureByReference(this, featureType);
206
        }
207
208 43358 jjdelcerro
    @Override
209 40435 jjdelcerro
        public Object getOID() {
210
                return this.oid;
211
        }
212
213 43358 jjdelcerro
    @Override
214 40435 jjdelcerro
        public boolean isNewFeature() {
215
                return this.isNewFeature;
216
        }
217
218
219 43358 jjdelcerro
    @Override
220 40435 jjdelcerro
        public boolean equals(Object obj) {
221
                if (!(obj instanceof DefaultFeatureReference)) {
222
                        return false;
223
                }
224
                DefaultFeatureReference other = (DefaultFeatureReference) obj;
225
226
                FeatureStore otherStore = (FeatureStore) other.storeRef.get();
227
                FeatureStore myrStore = (FeatureStore) this.storeRef.get();
228
                if (otherStore == null || myrStore == null) {
229
                        return false;
230
                }
231
                if (!myrStore.equals(otherStore)) {
232
                        return false;
233
                }
234
                if (myHashCode != null && other.myHashCode != null) {
235
                        return myHashCode.equals(other.myHashCode);
236
                }
237
                if (this.oid != null) {
238
                        return this.oid.equals(other.oid);
239
                }
240
                if(pk != null) {
241
                        if(other.pk == null) {
242
                                return false;
243
                        }
244
                    for (int i = 0; i < this.pk.length; i++) {
245
                            if (!this.pk[i].equals(other.pk[i])) {
246
                                    return false;
247
                            }
248
                    }
249
                }
250
                return true;
251
        }
252
253 43358 jjdelcerro
    @Override
254 40435 jjdelcerro
        public int hashCode() {
255
                if (this.oid != null) {
256
                        return this.oid.hashCode();
257
                }
258
                if (myHashCode == null) {
259 43358 jjdelcerro
                        StringBuilder buff = new StringBuilder();
260 40435 jjdelcerro
261
                        for (int i = 0; i < this.pk.length; i++) {
262
                                buff.append(this.pk[i].hashCode());
263
                                buff.append("##");
264
                        }
265 43358 jjdelcerro
                        myHashCode = buff.toString().hashCode();
266 40435 jjdelcerro
                }
267 43358 jjdelcerro
                return myHashCode;
268 40435 jjdelcerro
        }
269
270 43358 jjdelcerro
    @Override
271 40435 jjdelcerro
        public String[] getKeyNames() {
272
                return pkNames;
273
        }
274
275 43358 jjdelcerro
    @Override
276 40435 jjdelcerro
        public Object getKeyValue(String name) {
277
                for (int i = 0; i < pkNames.length; i++) {
278
                        if (pkNames[i].equalsIgnoreCase(name)) {
279
                                return pk[i];
280
                        }
281
                }
282
                // FIXME exception????
283
                return null;
284
        }
285
286 43358 jjdelcerro
    @Override
287 40435 jjdelcerro
        public String getFeatureTypeId() {
288
                return featureTypeId;
289
        }
290
291
        // *** Persistence ***
292
293 43358 jjdelcerro
    @Override
294 40435 jjdelcerro
        public void loadFromState(PersistentState state)
295
                        throws PersistenceException {
296
                this.oid = state.get("oid");
297
                this.myHashCode = (Integer) state.get("myHashCode");
298
                this.storeRef = new WeakReference(state.get("store"));
299
                this.isNewFeature = state.getBoolean("isNewFeature");
300
                this.featureTypeId = state.getString("featureTypeId");
301
                List pkList = (List) state.get("pk");
302
                if (pkList != null) {
303
                        List pkNamesList = (List) state.get("pkNames");
304
                        if (pkNamesList == null || pkList.size() != pkNamesList.size()) {
305
                                throw new PersistenceException("bad pkNames value");
306
                        }
307
                        this.pk = pkList.toArray();
308
            this.pkNames =
309
                (String[]) pkNamesList.toArray(new String[pkList.size()]);
310
                } else {
311
                        this.pk = null;
312
                        this.pkNames = null;
313
                }
314
        }
315
316 43358 jjdelcerro
    @Override
317 40435 jjdelcerro
        public void saveToState(PersistentState state) throws PersistenceException {
318
                state.set("oid", oid);
319
                state.set("myHashCode", myHashCode);
320
                state.set("isNewFeature", isNewFeature);
321
                state.set("store", (Persistent) storeRef.get());
322
                state.set("featureTypeId", featureTypeId);
323
                if (pk == null) {
324
                        state.setNull("pk");
325
                        state.setNull("pkNames");
326
                } else {
327
                        state.set("pk", pk);
328
                        state.set("pkNames", pkNames);
329
                }
330
331
        }
332 43824 jjdelcerro
333
        @Override
334
        public String getCode() {
335
//            JSONObject x = new JSONObject();
336
////            x.put("store", (Persistent) storeRef.get());
337
//            x.put("oid", oid);
338
//            x.put("myHashCode", myHashCode);
339
//            x.put("isNewFeature", isNewFeature);
340
//            x.put("featureTypeId", featureTypeId);
341
//            if( this.pk == null ) {
342
//                x.put("pkNames_size", -1);
343
//                x.put("pkNames", JSONObject.NULL);
344
//                x.put("pk", JSONObject.NULL);
345
//            } else {
346
//                x.put("pkNames_size", pkNames.length);
347
//                x.put("pkNames", new JSONArray(this.pkNames));
348
//                x.put("pk", new JSONArray(this.pk));
349
//            }
350
//
351
            Object[] data = new Object[7];
352
            data[OID_INDEX] = this.oid;
353
            data[MYHASHCODE_INDEX] = this.myHashCode;
354
            data[ISNEWFEATURE_INDEX] = this.isNewFeature;
355
            data[FEATURETYPEID_INDEX] = this.featureTypeId;
356
            if( this.pk == null ) {
357
                data[PKNAMES_SIZE_INDEX] = -1;
358
                data[PKNAMES_INDEX] = JSONObject.NULL;
359
                data[PK_INDEX] = JSONObject.NULL;
360
            } else {
361
                data[PKNAMES_SIZE_INDEX] = pkNames.length;
362
                data[PKNAMES_INDEX] = new JSONArray(this.pkNames);
363
                data[PK_INDEX] = new JSONArray(this.pk);
364
            }
365
            String s = new JSONArray(data).toString();
366
            String r = Base64.getEncoder().encodeToString(s.getBytes());
367
368
            return r;
369
        }
370 40435 jjdelcerro
371
        public static void registerPersistent() {
372
                DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
373
                                DefaultFeatureReference.class,
374
                                "Reference",
375
                                "DefaultFeatureReference Persistent definition",
376
                                null,
377
                                null
378
                        );
379
380
                definition.addDynFieldObject("oid")
381
                        .setClassOfValue(Object.class)
382
                        .setMandatory(false)
383
                        .setPersistent(true);
384
385
                definition.addDynFieldBoolean("isNewFeature")
386
                        .setMandatory(true)
387
                        .setPersistent(true);
388
389
                definition.addDynFieldObject("store")
390
                        .setClassOfValue(FeatureStore.class)
391
                        .setMandatory(true)
392
                        .setPersistent(true);
393
394
                definition.addDynFieldInt("myHashCode")
395
                        .setMandatory(false)
396
                        .setPersistent(true);
397
398
                definition.addDynFieldString("featureTypeId")
399
                        .setMandatory(true)
400
                        .setPersistent(true);
401
402
                definition.addDynFieldArray("pk")
403
                        .setClassOfItems(Object.class)
404
                        .setMandatory(false)
405
                        .setPersistent(true);
406
407
        definition.addDynFieldArray("pkNames")
408
                        .setClassOfItems(String.class)
409
                        .setMandatory(false)
410
                        .setPersistent(true);
411
412
        }
413
414 43243 jjdelcerro
    @Override
415 40435 jjdelcerro
        public String toString() {
416 43243 jjdelcerro
        StringBuilder builder = new StringBuilder();
417
        builder.append("FeatureReference: oid = ");
418
        builder.append(oid);
419
        if( myHashCode!=null ) {
420
            builder.append(", myHashCode = ");
421
            builder.append(myHashCode);
422
        }
423
        if( pk!=null ) {
424
            builder.append(", pks = ");
425
            builder.append(Arrays.asList(pk));
426
        }
427
        if( pkNames!=null ) {
428
            builder.append(", pkNames = ");
429
            builder.append(Arrays.asList(pkNames));
430
        }
431
        if( isNewFeature ) {
432
            builder.append(", isNew = ");
433
            builder.append(isNewFeature);
434
        }
435
        if( featureTypeId!=null ) {
436
            builder.append(", featureTypeId = ");
437
            builder.append(featureTypeId);
438
        }
439
        return builder.toString();
440 40435 jjdelcerro
        }
441
442
}