Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / DefaultFeatureTypeDefinitionsManager.java @ 44370

History | View | Annotate | Download (12.3 KB)

1
package org.gvsig.app.extension;
2

    
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.FileOutputStream;
6
import java.io.IOException;
7
import java.io.InputStream;
8
import java.nio.charset.Charset;
9
import java.util.HashMap;
10
import java.util.Map;
11
import java.util.Properties;
12
import java.util.zip.CRC32;
13

    
14
import org.apache.commons.io.FileUtils;
15
import org.apache.commons.io.IOUtils;
16
import org.apache.commons.lang3.StringUtils;
17
import org.gvsig.andami.PluginServices;
18
import org.gvsig.andami.PluginsLocator;
19
import org.gvsig.andami.PluginsManager;
20
import org.gvsig.fmap.dal.DataServerExplorer;
21
import org.gvsig.fmap.dal.DataStoreParameters;
22
import org.gvsig.fmap.dal.complements.RelatedFeatures;
23
import org.gvsig.fmap.dal.feature.AbstractFeatureTypeDefinitionsManager;
24
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.feature.FeatureType;
27
import org.gvsig.fmap.dal.feature.FeatureTypeDefinitionsManager;
28
import org.gvsig.tools.ToolsLocator;
29
import org.gvsig.tools.dataTypes.DataTypes;
30
import org.gvsig.tools.dispose.DisposeUtils;
31
import org.gvsig.tools.dynform.JDynForm;
32
import static org.gvsig.tools.dynform.spi.DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE;
33
import org.gvsig.tools.dynobject.DynClass;
34
import org.gvsig.tools.dynobject.DynClass_v2;
35
import org.gvsig.tools.dynobject.DynField_v2;
36
import org.gvsig.tools.dynobject.DynObjectManager;
37
import org.gvsig.tools.dynobject.Tags;
38
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
39
import org.gvsig.tools.util.HasAFile;
40
import org.gvsig.tools.resourcesstorage.ResourcesStorage.Resource;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
@SuppressWarnings("UseSpecificCatch")
45
public class DefaultFeatureTypeDefinitionsManager extends AbstractFeatureTypeDefinitionsManager implements FeatureTypeDefinitionsManager {
46

    
47
    private static final Logger logger = LoggerFactory.getLogger(DefaultFeatureTypeDefinitionsManager.class);
48

    
49
    private static final String FILE_EXTENSION = "form";
50
    
51
    private File definitionsFolder = null;
52
    private final Map<String, DynClass> dynClasses;
53

    
54
    public DefaultFeatureTypeDefinitionsManager() {
55
        this.dynClasses = new HashMap<>();
56
    }
57

    
58
    protected Map<String, DynClass> getDynClasses() {
59
        return this.dynClasses;
60
    }
61
    
62
    protected File getDefinitionsFolder() throws IOException {
63
        if (this.definitionsFolder == null) {
64
            PluginsManager pluginManager = PluginsLocator.getManager();
65
            PluginServices plugin = pluginManager.getPlugin(CreateDefaultFormDefinitionExtension.class);
66
            File homeFolder = plugin.getPluginHomeFolder();
67
            File definitionsFolder = new File(homeFolder, "schemas");
68
            if (!definitionsFolder.exists()) {
69
                FileUtils.forceMkdir(definitionsFolder);
70
            }
71
            this.definitionsFolder = definitionsFolder;
72
        }
73
        return this.definitionsFolder;
74
    }
75

    
76
    protected long getCRC(FeatureType type) {
77
        StringBuilder buffer = new StringBuilder();
78
        for (int i = 0; i < type.size(); i++) {
79
            FeatureAttributeDescriptor x = type.getAttributeDescriptor(i);
80
            if( !x.isComputed() ) {
81
                buffer.append(x.getName());
82
                buffer.append(x.getDataTypeName());
83
                buffer.append(x.getSize());
84
            }
85
        }
86
        CRC32 crc = new CRC32();
87
        byte[] data = buffer.toString().getBytes();
88
        crc.update(data);
89
        return crc.getValue();
90
    }
91

    
92
    protected String getKey(FeatureStore store, FeatureType featureType) {
93
        return store.getName() + "_" + Long.toHexString(getCRC(featureType));
94
    }
95

    
96
    protected String getKey(FeatureStore store, FeatureType featureType, String name) {
97
        CRC32 crc = new CRC32();
98
        crc.update(name.getBytes());
99
        crc.getValue();
100
        if( !StringUtils.isAlphanumeric(name) ) {
101
            name = StringUtils.removeAll(name, "[^a-zA-Z0-9_]");
102
        }
103
        return store.getName() + name + "_" + Long.toHexString(getCRC(featureType))+Long.toHexString(crc.getValue()) ;
104
    }
105

    
106
    protected File getDefinitionFile(String key) {
107
        File folder;
108
        try {
109
            folder = getDefinitionsFolder();
110
        } catch (IOException ex) {
111
            return null;
112
        }
113
        File f = new File(folder, key + "."+FILE_EXTENSION);
114
        if (f.exists()) {
115
            return f;
116
        }
117
        Properties prop = new Properties();
118
        FileInputStream fin = null;
119
        try {
120
            fin = new FileInputStream(new File(folder, "index.properties"));
121
            prop.load(fin);
122
        } catch (IOException ex) {
123
            return null;
124
        } finally {
125
            IOUtils.closeQuietly(fin);
126
        }
127
        String s = prop.getProperty(key, null);
128
        if (s == null) {
129
            return null;
130
        }
131
        f = new File(folder, s);
132
        if (f.exists()) {
133
            return f;
134
        }
135
        f = new File(s);
136
        if (f.exists()) {
137
            return f;
138
        }
139
        return null;
140
    }
141

    
142
    @Override
143
    public DynClass get(FeatureStore store, FeatureType featureType) {
144
        String key = this.getKey(store, featureType);
145
        DynClass dynClass = this.getDynClasses().get(key);
146
        if (dynClass != null) {
147
            return dynClass;
148
        }
149
        String xml = null;
150
        File definitionFile = getDefinitionFile(key);
151
        if (definitionFile == null) {
152
            DataServerExplorer explorer = null;
153
            Resource resource = null;
154
            try {
155
                ResourcesStorage resourcesStorage = store.getResourcesStorage();
156
                if( resourcesStorage==null ) {
157
                    return this.getDynClass(store, featureType);                    
158
                } else {
159
                    resource = resourcesStorage.getResource(FILE_EXTENSION);
160
                    if( resource !=null && resource.exists() ) {
161
                        xml = IOUtils.toString(resource.asInputStream());
162
                    } else {
163
                        DynClass aDynClass = this.getDynClass(store, featureType);
164
                        this.getDynClasses().put(aDynClass.getName(), aDynClass);
165
                        return aDynClass;
166
                    }
167
                }
168
            } catch(Exception ex) {
169
                // Do nothing, leave xml to null
170
            } finally {
171
                IOUtils.closeQuietly(resource);
172
                DisposeUtils.disposeQuietly(explorer);
173
            }
174
        }
175
        DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
176
        try {
177
            if( xml!=null ) {
178
                xml = FileUtils.readFileToString(definitionFile);
179
                xml = xml.replaceAll("[$][{]CWD[}]",definitionFile.getParentFile().getAbsolutePath());
180
            }
181
            InputStream is = IOUtils.toInputStream(xml, Charset.forName("UTF-8"));
182
            Map<String, DynClass> dynClasses = dynObjectManager.importDynClassDefinitions(is, this.getClass().getClassLoader());
183
            for (DynClass aDynClass : dynClasses.values()) {
184
                this.getDynClasses().put(aDynClass.getName(), aDynClass);
185
            }
186
        } catch (Exception ex) {
187
            logger.warn("Can't parse xml definition.", ex);
188
            return null;
189
        }
190

    
191
        dynClass = this.getDynClasses().get(key);
192
        if (dynClass != null) {
193
            return dynClass;
194
        }
195
        return this.getDynClass(store, featureType);
196
    }
197

    
198
    @Override
199
    public boolean contains(FeatureStore store, FeatureType featureType) {
200
        String key = this.getKey(store, featureType);
201
        return this.getDynClasses().containsKey(key);
202
    }
203

    
204
    @Override
205
    public void add(FeatureStore store, FeatureType featureType, DynClass dynClass) {
206
        try {
207
            if( dynClass instanceof FeatureType ) {
208
                dynClass = this.getDynClass(store, (FeatureType) dynClass);
209
            }
210
            String key = this.getKey(store, featureType);
211
            File f = new File(getDefinitionsFolder(), key + "."+FILE_EXTENSION);
212
            DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
213
            String xml = dynObjectManager.exportSimpleDynClassDefinitions(dynClass);
214
            FileUtils.write(f, xml);
215
            this.getDynClasses().put(key, dynClass);
216
        } catch (IOException ex) {
217
            throw new RuntimeException(ex);
218
        }
219
    }
220

    
221
    @Override
222
    public void remove(FeatureStore store, FeatureType featureType) {
223
        String key = this.getKey(store, featureType);
224
        this.getDynClasses().remove(key);
225
    }
226

    
227
    @Override
228
    public void addModel(File model) {
229
              DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
230
          try {
231
              String xml = FileUtils.readFileToString(model);
232
              InputStream is = IOUtils.toInputStream(xml, Charset.forName("UTF-8"));
233
              Map<String, DynClass> dynClasses = dynObjectManager.importDynClassDefinitions(is, this.getClass().getClassLoader());
234

    
235
              File folder;
236
              try {
237
                  folder = getDefinitionsFolder();
238
              } catch (IOException ex) {
239
                  return ;
240
              }
241
              Properties prop = new Properties();
242
              FileInputStream fin = null;
243
              try {
244
                  fin = new FileInputStream(new File(folder, "index.properties"));
245
                  prop.load(fin);
246
              } catch (IOException ex) {
247
              } finally {
248
                  IOUtils.closeQuietly(fin);
249
              }
250
              for (DynClass aDynClass : dynClasses.values()) {
251
                      String className = aDynClass.getName();
252
                      prop.setProperty(className, model.getAbsolutePath());
253
              }
254
              FileOutputStream fout = null;
255
              try {
256
                      fout = new FileOutputStream(new File(folder, "index.properties"));
257
                  prop.store(fout, "");
258
              } catch (IOException ex) {
259
              } finally {
260
                  IOUtils.closeQuietly(fout);
261
              }
262

    
263
          } catch (Exception ex) {
264
              logger.warn("Can't parse xml definition.", ex);
265
          }
266
    }
267

    
268
    private DynClass getDynClass(FeatureStore store, FeatureType featureType) {
269
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
270
        DynClass_v2 definition = (DynClass_v2) manager.createCopy(featureType);
271

    
272
        File path = null;
273
        if( store!=null ) {
274
            try {
275
                String label = featureType.getLabel();
276
                if( StringUtils.isEmpty(label) ) {
277
                    definition.setLabel(store.getName());
278
                } else {
279
                    definition.setLabel(label);
280
                }
281
                DataStoreParameters params = store.getParameters();
282
                if( params instanceof HasAFile ) {
283
                    File f = ((HasAFile)params).getFile();
284
                    if( f!=null ) {
285
                        path = f.getParentFile();
286
                    }
287
                }
288
            } catch (Exception ex) {
289
            }
290
        }
291
        boolean calculateLayout = true;
292
        if( featureType.getTags().has(TAG_DYNFORM_LAYOUTMODE) ) {
293
            calculateLayout = false;
294
        }
295
        for (FeatureAttributeDescriptor descriptor : featureType) {
296
            DynField_v2 definitionField = (DynField_v2) definition.getDynField(descriptor.getName());
297
            if( descriptor.isComputed() ) {
298
                definitionField.setReadOnly(true);
299
            }
300
            String profileName = descriptor.getDataProfileName();
301
            if( !StringUtils.isBlank(profileName) ) {
302
                definitionField.setSubtype(profileName);
303
            }
304
            if( path!=null && definitionField.getType()==DataTypes.FILE ) {
305
                Tags tags = definitionField.getTags();
306
                if (!tags.has("path")) {    
307
                    tags.set("path", path);
308
                }
309
            }
310
            if( calculateLayout ) {
311
                RelatedFeatures complement = (RelatedFeatures) ToolsLocator.getComplementsManager().get(
312
                        RelatedFeatures.COMPLEMENT_MANE, descriptor
313
                );
314
                if( complement.isRelatedFeatures() ) {
315
                    definition.getTags().set(TAG_DYNFORM_LAYOUTMODE, JDynForm.USE_TABS);
316
                    definitionField.setGroup(descriptor.getLabel());
317
                }
318
            }
319
        }
320
        return definition;
321
    }
322
}