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

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.DataStoreParameters;
21
import org.gvsig.fmap.dal.complements.RelatedFeatures;
22
import org.gvsig.fmap.dal.feature.AbstractFeatureTypeDefinitionsManager;
23
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
24
import org.gvsig.fmap.dal.feature.FeatureStore;
25
import org.gvsig.fmap.dal.feature.FeatureType;
26
import org.gvsig.fmap.dal.feature.FeatureTypeDefinitionsManager;
27
import org.gvsig.tools.ToolsLocator;
28
import org.gvsig.tools.dataTypes.DataTypes;
29
import org.gvsig.tools.dynform.JDynForm;
30
import static org.gvsig.tools.dynform.spi.DynFormSPIManager.TAG_DYNFORM_LAYOUTMODE;
31
import org.gvsig.tools.dynobject.DynClass;
32
import org.gvsig.tools.dynobject.DynClass_v2;
33
import org.gvsig.tools.dynobject.DynField_v2;
34
import org.gvsig.tools.dynobject.DynObjectManager;
35
import org.gvsig.tools.dynobject.Tags;
36
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
37
import org.gvsig.tools.util.HasAFile;
38
import org.gvsig.tools.resourcesstorage.ResourcesStorage.Resource;
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

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

    
45
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureTypeDefinitionsManager.class);
46

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

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

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

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

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

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

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

    
140
    @Override
141
    public DynClass get(FeatureStore store, FeatureType featureType) {
142
        String key = this.getKey(store, featureType);
143
        DynClass dynClass = this.getDynClasses().get(key);
144
        if (dynClass != null) {
145
            return dynClass;
146
        }
147
        String xml = null;
148
        Resource resource = null;
149
        DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
150
        File definitionFile = getDefinitionFile(key);
151
        try {
152
            if (definitionFile == null) {
153
                ResourcesStorage resourcesStorage = store.getResourcesStorage();
154
                if( resourcesStorage!=null ) {
155
                    resource = resourcesStorage.getResource(FILE_EXTENSION);
156
                    if( resource !=null && resource.exists() ) {
157
                        xml = IOUtils.toString(resource.asInputStream());
158
                    }
159
                }
160
            } else {
161
                xml = FileUtils.readFileToString(definitionFile);
162
                xml = xml.replaceAll("[$][{]CWD[}]",definitionFile.getParentFile().getAbsolutePath());
163
            }
164
            if( !StringUtils.isEmpty(xml) ) {
165
                InputStream is = IOUtils.toInputStream(xml, Charset.forName("UTF-8"));
166
                Map<String, DynClass> theDynClasses = dynObjectManager.importDynClassDefinitions(is, this.getClass().getClassLoader());
167
                for (DynClass aDynClass : theDynClasses.values()) {
168
                    this.getDynClasses().put(aDynClass.getName(), aDynClass);
169
                }
170
            }
171
            dynClass = this.getDynClasses().get(key);
172
            if (dynClass != null) {
173
                return dynClass;
174
            }
175
            return this.getDynClass(store, featureType);
176

    
177
        } catch(Exception ex) {
178
            LOGGER.warn("Can't retrieve definition of '"+key+"'.", ex);
179
            return null;
180
        } finally {
181
            IOUtils.closeQuietly(resource);
182
        }
183
    }
184

    
185
    @Override
186
    public boolean contains(FeatureStore store, FeatureType featureType) {
187
        String key = this.getKey(store, featureType);
188
        return this.getDynClasses().containsKey(key);
189
    }
190

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

    
208
    @Override
209
    public void remove(FeatureStore store, FeatureType featureType) {
210
        String key = this.getKey(store, featureType);
211
        this.getDynClasses().remove(key);
212
    }
213

    
214
    @Override
215
    public void addModel(File model) {
216
              DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
217
          try {
218
              String xml = FileUtils.readFileToString(model);
219
              InputStream is = IOUtils.toInputStream(xml, Charset.forName("UTF-8"));
220
              Map<String, DynClass> dynClasses = dynObjectManager.importDynClassDefinitions(is, this.getClass().getClassLoader());
221

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

    
250
          } catch (Exception ex) {
251
              LOGGER.warn("Can't parse xml definition.", ex);
252
          }
253
    }
254

    
255
    private DynClass getDynClass(FeatureStore store, FeatureType featureType) {
256
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
257
        DynClass_v2 definition = (DynClass_v2) manager.createCopy(featureType);
258

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