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

History | View | Annotate | Download (9.23 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.List;
29
import org.apache.commons.lang3.ArrayUtils;
30

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

    
44
public class DefaultFeatureReference implements
45
                FeatureReferenceProviderServices, Persistent {
46

    
47
        private Object oid;
48
        private Integer myHashCode = null;
49
        private Object[] pk;
50
        private String[] pkNames;
51
        private WeakReference storeRef;
52
        private boolean isNewFeature;
53
        private String featureTypeId;
54
         
55
        /**
56
     * Constructor used by the persistence manager. Don't use directly.
57
     * After to invoke this method, the persistence manager calls 
58
     * the the method {@link #loadFromState(PersistentState)} to set 
59
     * the values of the internal attributes that this class needs to work.
60
     */
61
        public DefaultFeatureReference() {
62
                super();                
63
        }
64
        
65
        public DefaultFeatureReference(DefaultFeature feature) {
66
                this(feature.getStore(), feature.getData());
67
        }
68

    
69
        public DefaultFeatureReference(FeatureStore store,
70
                        FeatureProvider fdata) {
71
                this.isNewFeature = fdata.isNew();
72
                this.oid = null;
73
                this.pk = null;
74
                this.storeRef = new WeakReference(store);
75
                this.featureTypeId = fdata.getType().getId();
76

    
77
                if (fdata.getType().hasOID() || isNewFeature) {
78
                        this.oid = fdata.getOID();
79
                        if (this.oid == null) {
80
                                // FIXME Exception
81
                                throw new RuntimeException("Missing OID");
82
                        }
83
                } else {
84
                        this.calculatePK(fdata);
85
                        if (this.pk == null) {
86
                                // FIXME Exception
87
                                throw new RuntimeException("Missing pk attributes");
88
                        }
89
                }
90

    
91
        }
92

    
93
        /*
94
         * Use only for Persistent.setState
95
         */
96
        public DefaultFeatureReference(FeatureStore store) {
97
                this.isNewFeature = false;
98
                this.oid = null;
99
                this.pk = null;
100
                this.storeRef = new WeakReference(store);
101
        }
102

    
103
        public DefaultFeatureReference(FeatureStore store, Object oid) {
104
                // FIXME featureTypeId is needed !!!
105
                this.isNewFeature = false;
106
                this.oid = oid;
107
                this.pk = null;
108
                this.storeRef = new WeakReference(store);
109
        }
110

    
111
        private DefaultFeatureStore getStore() {
112
                return (DefaultFeatureStore) this.storeRef.get();
113
        }
114

    
115
        private void calculatePK(FeatureProvider fdata) {
116
            FeatureAttributeDescriptor[] pkattrs = fdata.getType().getPrimaryKey();
117
            if( ArrayUtils.isEmpty(pkattrs) ) {
118
                this.pk = null;
119
                this.pkNames = null;
120
                return ;
121
            }
122
            this.pk = new Object[pkattrs.length];
123
            this.pkNames = new String[pkattrs.length];
124
            int n = 0;
125
            for (FeatureAttributeDescriptor pkattr : pkattrs) {
126
                this.pk[n] = fdata.get(pkattr.getIndex());
127
                this.pkNames[n] = pkattr.getName();
128
                n++;
129
            }
130
    }
131

    
132
    @Override
133
        public Feature getFeature() throws DataException {
134
                return this.getStore().getFeatureByReference(this);
135
        }
136

    
137
    @Override
138
        public Feature getFeature(FeatureType featureType) throws DataException {
139
                return this.getStore().getFeatureByReference(this, featureType);
140
        }
141

    
142
    @Override
143
        public Object getOID() {
144
                return this.oid;
145
        }
146

    
147
    @Override
148
        public boolean isNewFeature() {
149
                return this.isNewFeature;
150
        }
151

    
152

    
153
    @Override
154
        public boolean equals(Object obj) {
155
                if (!(obj instanceof DefaultFeatureReference)) {
156
                        return false;
157
                }
158
                DefaultFeatureReference other = (DefaultFeatureReference) obj;
159

    
160
                FeatureStore otherStore = (FeatureStore) other.storeRef.get();
161
                FeatureStore myrStore = (FeatureStore) this.storeRef.get();
162
                if (otherStore == null || myrStore == null) {
163
                        return false;
164
                }
165
                if (!myrStore.equals(otherStore)) {
166
                        return false;
167
                }
168
                if (myHashCode != null && other.myHashCode != null) {
169
                        return myHashCode.equals(other.myHashCode);
170
                }
171
                if (this.oid != null) {
172
                        return this.oid.equals(other.oid);
173
                }
174
                if(pk != null) {
175
                        if(other.pk == null) {
176
                                return false;
177
                        }
178
                    for (int i = 0; i < this.pk.length; i++) {
179
                            if (!this.pk[i].equals(other.pk[i])) {
180
                                    return false;
181
                            }
182
                    }
183
                }
184
                return true;
185
        }
186

    
187
    @Override
188
        public int hashCode() {
189
                if (this.oid != null) {
190
                        return this.oid.hashCode();
191
                }
192
                if (myHashCode == null) {
193
                        StringBuilder buff = new StringBuilder();
194

    
195
                        for (int i = 0; i < this.pk.length; i++) {
196
                                buff.append(this.pk[i].hashCode());
197
                                buff.append("##");
198
                        }
199
                        myHashCode = buff.toString().hashCode();
200
                }
201
                return myHashCode;
202
        }
203

    
204
    @Override
205
        public String[] getKeyNames() {
206
                return pkNames;
207
        }
208

    
209
    @Override
210
        public Object getKeyValue(String name) {
211
                for (int i = 0; i < pkNames.length; i++) {
212
                        if (pkNames[i].equalsIgnoreCase(name)) {
213
                                return pk[i];
214
                        }
215
                }
216
                // FIXME exception????
217
                return null;
218
        }
219

    
220
    @Override
221
        public String getFeatureTypeId() {
222
                return featureTypeId;
223
        }
224

    
225
        // *** Persistence ***
226

    
227
    @Override
228
        public void loadFromState(PersistentState state)
229
                        throws PersistenceException {
230
                this.oid = state.get("oid");
231
                this.myHashCode = (Integer) state.get("myHashCode");
232
                this.storeRef = new WeakReference(state.get("store"));
233
                this.isNewFeature = state.getBoolean("isNewFeature");
234
                this.featureTypeId = state.getString("featureTypeId");
235
                List pkList = (List) state.get("pk");
236
                if (pkList != null) {
237
                        List pkNamesList = (List) state.get("pkNames");
238
                        if (pkNamesList == null || pkList.size() != pkNamesList.size()) {
239
                                throw new PersistenceException("bad pkNames value");
240
                        }
241
                        this.pk = pkList.toArray();
242
            this.pkNames =
243
                (String[]) pkNamesList.toArray(new String[pkList.size()]);
244
                } else {
245
                        this.pk = null;
246
                        this.pkNames = null;
247
                }
248
        }
249

    
250
    @Override
251
        public void saveToState(PersistentState state) throws PersistenceException {
252
                state.set("oid", oid);
253
                state.set("myHashCode", myHashCode);
254
                state.set("isNewFeature", isNewFeature);
255
                state.set("store", (Persistent) storeRef.get());
256
                state.set("featureTypeId", featureTypeId);
257
                if (pk == null) {
258
                        state.setNull("pk");
259
                        state.setNull("pkNames");
260
                } else {
261
                        state.set("pk", pk);
262
                        state.set("pkNames", pkNames);
263
                }
264

    
265
        }
266

    
267
        public static void registerPersistent() {
268
                DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
269
                                DefaultFeatureReference.class, 
270
                                "Reference", 
271
                                "DefaultFeatureReference Persistent definition", 
272
                                null, 
273
                                null
274
                        );
275

    
276
                definition.addDynFieldObject("oid")
277
                        .setClassOfValue(Object.class)
278
                        .setMandatory(false)
279
                        .setPersistent(true);
280
                        
281
                definition.addDynFieldBoolean("isNewFeature")
282
                        .setMandatory(true)
283
                        .setPersistent(true);
284
        
285
                definition.addDynFieldObject("store")
286
                        .setClassOfValue(FeatureStore.class)
287
                        .setMandatory(true)
288
                        .setPersistent(true);
289

    
290
                definition.addDynFieldInt("myHashCode")
291
                        .setMandatory(false)
292
                        .setPersistent(true);
293
        
294
                definition.addDynFieldString("featureTypeId")
295
                        .setMandatory(true)
296
                        .setPersistent(true);
297

    
298
                definition.addDynFieldArray("pk")
299
                        .setClassOfItems(Object.class)
300
                        .setMandatory(false)
301
                        .setPersistent(true);
302

    
303
        definition.addDynFieldArray("pkNames")
304
                        .setClassOfItems(String.class)
305
                        .setMandatory(false)
306
                        .setPersistent(true);
307

    
308
        }
309

    
310
    @Override
311
        public String toString() {
312
        StringBuilder builder = new StringBuilder();
313
        builder.append("FeatureReference: oid = ");
314
        builder.append(oid);
315
        if( myHashCode!=null ) {
316
            builder.append(", myHashCode = ");
317
            builder.append(myHashCode);
318
        } 
319
        if( pk!=null ) {
320
            builder.append(", pks = ");
321
            builder.append(Arrays.asList(pk));
322
        }
323
        if( pkNames!=null ) {
324
            builder.append(", pkNames = ");
325
            builder.append(Arrays.asList(pkNames));
326
        }
327
        if( isNewFeature ) {
328
            builder.append(", isNew = ");
329
            builder.append(isNewFeature);
330
        }
331
        if( featureTypeId!=null ) {
332
            builder.append(", featureTypeId = ");
333
            builder.append(featureTypeId);
334
        }
335
        return builder.toString();
336
        }
337

    
338
}