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

History | View | Annotate | Download (12.2 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
                        return this.getDynClass(store, featureType);
164
                    }
165
                }
166
            } catch(Exception ex) {
167
                // Do nothing, leave xml to null
168
            } finally {
169
                IOUtils.closeQuietly(resource);
170
                DisposeUtils.disposeQuietly(explorer);
171
            }
172
        }
173
        DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
174
        try {
175
            if( xml!=null ) {
176
                xml = FileUtils.readFileToString(definitionFile);
177
                xml = xml.replaceAll("[$][{]CWD[}]",definitionFile.getParentFile().getAbsolutePath());
178
            }
179
            InputStream is = IOUtils.toInputStream(xml, Charset.forName("UTF-8"));
180
            Map<String, DynClass> dynClasses = dynObjectManager.importDynClassDefinitions(is, this.getClass().getClassLoader());
181
            for (DynClass aDynClass : dynClasses.values()) {
182
                this.getDynClasses().put(aDynClass.getName(), aDynClass);
183
            }
184
        } catch (Exception ex) {
185
            logger.warn("Can't parse xml definition.", ex);
186
            return null;
187
        }
188

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

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

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

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

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

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

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

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

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