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

History | View | Annotate | Download (12 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.DataServerExplorer.DataResource;
22
import org.gvsig.fmap.dal.DataStoreParameters;
23
import org.gvsig.fmap.dal.complements.RelatedFeatures;
24
import org.gvsig.fmap.dal.exception.DataException;
25
import org.gvsig.fmap.dal.feature.AbstractFeatureTypeDefinitionsManager;
26
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
27
import org.gvsig.fmap.dal.feature.FeatureStore;
28
import org.gvsig.fmap.dal.feature.FeatureType;
29
import org.gvsig.fmap.dal.feature.FeatureTypeDefinitionsManager;
30
import org.gvsig.tools.ToolsLocator;
31
import org.gvsig.tools.dataTypes.DataTypes;
32
import org.gvsig.tools.dispose.DisposeUtils;
33
import org.gvsig.tools.dynform.JDynForm;
34
import static org.gvsig.tools.dynform.JDynForm.USE_PLAIN;
35
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
36
import static org.gvsig.tools.dynform.spi.DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE;
37
import static org.gvsig.tools.dynform.spi.DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE_VALUE_PLAIN;
38
import org.gvsig.tools.dynobject.DynClass;
39
import org.gvsig.tools.dynobject.DynClass_v2;
40
import org.gvsig.tools.dynobject.DynField_v2;
41
import org.gvsig.tools.dynobject.DynObjectManager;
42
import org.gvsig.tools.dynobject.Tags;
43
import org.gvsig.tools.util.HasAFile;
44
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
46

    
47
@SuppressWarnings("UseSpecificCatch")
48
public class DefaultFeatureTypeDefinitionsManager extends AbstractFeatureTypeDefinitionsManager implements FeatureTypeDefinitionsManager {
49

    
50
    private static final Logger logger = LoggerFactory.getLogger(DefaultFeatureTypeDefinitionsManager.class);
51

    
52
    private static final String FILE_EXTENSION = "form";
53
    
54
    private File definitionsFolder = null;
55
    private final Map<String, DynClass> dynClasses;
56

    
57
    public DefaultFeatureTypeDefinitionsManager() {
58
        this.dynClasses = new HashMap<>();
59
    }
60

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

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

    
95
    protected String getKey(FeatureStore store, FeatureType featureType) {
96
        return store.getName() + "_" + Long.toHexString(getCRC(featureType));
97
    }
98

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

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

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

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

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

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

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

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

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

    
260
          } catch (Exception ex) {
261
              logger.warn("Can't parse xml definition.", ex);
262
          }
263
    }
264

    
265
    private DynClass getDynClass(FeatureStore store, FeatureType featureType) {
266
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
267
        DynClass_v2 definition = (DynClass_v2) manager.createCopy(featureType);
268

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