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

History | View | Annotate | Download (11.8 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.util.HasAFile;
39
import org.gvsig.tools.util.ResourcesStorage.Resource;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

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

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

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

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

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

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

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

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

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

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

    
184
        dynClass = this.getDynClasses().get(key);
185
        if (dynClass != null) {
186
            return dynClass;
187
        }
188
        return this.getDynClass(store, featureType);
189
    }
190

    
191
    @Override
192
    public boolean contains(FeatureStore store, FeatureType featureType) {
193
        String key = this.getKey(store, featureType);
194
        return this.getDynClasses().containsKey(key);
195
    }
196

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

    
214
    @Override
215
    public void remove(FeatureStore store, FeatureType featureType) {
216
        String key = this.getKey(store, featureType);
217
        this.getDynClasses().remove(key);
218
    }
219

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

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

    
256
          } catch (Exception ex) {
257
              logger.warn("Can't parse xml definition.", ex);
258
          }
259
    }
260

    
261
    private DynClass getDynClass(FeatureStore store, FeatureType featureType) {
262
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
263
        DynClass_v2 definition = (DynClass_v2) manager.createCopy(featureType);
264

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