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

History | View | Annotate | Download (8.64 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.text.MessageFormat;
28
import java.util.ArrayList;
29
import java.util.Arrays;
30
import java.util.Iterator;
31
import java.util.List;
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

    
46
public class DefaultFeatureReference implements
47
                FeatureReferenceProviderServices, Persistent {
48

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

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

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

    
93
        }
94

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

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

    
113
        private DefaultFeatureStore getStore() {
114
                return (DefaultFeatureStore) this.storeRef.get();
115
        }
116

    
117
        private void calculatePK(FeatureProvider fdata) {
118
                ArrayList keys = new ArrayList();
119
                ArrayList keyNames = new ArrayList();
120
                FeatureType type = fdata.getType();
121
                Iterator it = type.iterator();
122
                while (it.hasNext()) {
123
                        FeatureAttributeDescriptor attr = (FeatureAttributeDescriptor) it
124
                                        .next();
125
                        if (attr.isPrimaryKey()) {
126
                                keys.add(fdata.get(attr.getIndex()));
127
                                keyNames.add(attr.getName());
128
                        }
129
                }
130
                if (keys.size() < 1) {
131
                        pk = null;
132
                        pkNames = null;
133
                } else {
134
                        pk = keys.toArray();
135
            pkNames = (String[]) keyNames.toArray(new String[keyNames.size()]);
136
                }
137
        }
138

    
139
        public Feature getFeature() throws DataException {
140
                return this.getStore().getFeatureByReference(this);
141
        }
142

    
143
        public Feature getFeature(FeatureType featureType) throws DataException {
144
                return this.getStore().getFeatureByReference(this, featureType);
145
        }
146

    
147
        public Object getOID() {
148
                return this.oid;
149
        }
150

    
151
        public boolean isNewFeature() {
152
                return this.isNewFeature;
153
        }
154

    
155

    
156
        public boolean equals(Object obj) {
157
                if (!(obj instanceof DefaultFeatureReference)) {
158
                        return false;
159
                }
160
                DefaultFeatureReference other = (DefaultFeatureReference) obj;
161

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

    
189
        public int hashCode() {
190
                if (this.oid != null) {
191
                        return this.oid.hashCode();
192
                }
193
                if (myHashCode == null) {
194
                        StringBuffer buff = new StringBuffer();
195

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

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

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

    
219
        public String getFeatureTypeId() {
220
                return featureTypeId;
221
        }
222

    
223
        // *** Persistence ***
224

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

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

    
261
        }
262

    
263
        public static void registerPersistent() {
264
                DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
265
                                DefaultFeatureReference.class, 
266
                                "Reference", 
267
                                "DefaultFeatureReference Persistent definition", 
268
                                null, 
269
                                null
270
                        );
271

    
272
                definition.addDynFieldObject("oid")
273
                        .setClassOfValue(Object.class)
274
                        .setMandatory(false)
275
                        .setPersistent(true);
276
                        
277
                definition.addDynFieldBoolean("isNewFeature")
278
                        .setMandatory(true)
279
                        .setPersistent(true);
280
        
281
                definition.addDynFieldObject("store")
282
                        .setClassOfValue(FeatureStore.class)
283
                        .setMandatory(true)
284
                        .setPersistent(true);
285

    
286
                definition.addDynFieldInt("myHashCode")
287
                        .setMandatory(false)
288
                        .setPersistent(true);
289
        
290
                definition.addDynFieldString("featureTypeId")
291
                        .setMandatory(true)
292
                        .setPersistent(true);
293

    
294
                definition.addDynFieldArray("pk")
295
                        .setClassOfItems(Object.class)
296
                        .setMandatory(false)
297
                        .setPersistent(true);
298

    
299
        definition.addDynFieldArray("pkNames")
300
                        .setClassOfItems(String.class)
301
                        .setMandatory(false)
302
                        .setPersistent(true);
303

    
304
        }
305

    
306
        public String toString() {
307
                return MessageFormat.format(
308
                                "FeatureReference: oid = {0}, myHashCode = {1}, "
309
                                + "pks = {2}, pkNames = {3}, "
310
                                + "isNewFeature = {4}, featureTypeId = {5}", new Object[] {
311
                                oid, myHashCode, (pk == null ? null : Arrays.asList(pk)),
312
                                (pkNames == null ? null : Arrays.asList(pkNames)),
313
                                new Boolean(isNewFeature),
314
                                featureTypeId });
315
        }
316

    
317
}