Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.lib / org.gvsig.scripting.lib.impl / src / main / java / org / gvsig / scripting / impl / DefaultScriptingFolder.java @ 981

History | View | Annotate | Download (14 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import java.io.File;
4
import java.io.FilenameFilter;
5
import java.io.IOException;
6
import java.net.URL;
7
import java.util.ArrayList;
8
import java.util.List;
9
import java.util.Arrays;
10
import java.util.Collections;
11
import java.util.Comparator;
12
import java.util.HashSet;
13
import java.util.Set;
14

    
15
import org.apache.commons.io.FileUtils;
16
import org.apache.commons.io.FilenameUtils;
17
import org.apache.commons.lang3.StringUtils;
18
import org.gvsig.scripting.ScriptingFolder;
19
import org.gvsig.scripting.ScriptingManager;
20
import org.gvsig.scripting.ScriptingUnit;
21
import org.gvsig.tools.exception.BaseException;
22
import org.gvsig.tools.visitor.Visitor;
23
import org.ini4j.Ini;
24
import org.slf4j.Logger;
25
import org.slf4j.LoggerFactory;
26

    
27
public class DefaultScriptingFolder extends AbstractUnit implements ScriptingFolder {
28

    
29
    private static final Logger logger = LoggerFactory.getLogger(DefaultScriptingFolder.class);
30
    protected File folder;
31
    private boolean islink;
32

    
33
    public DefaultScriptingFolder(ScriptingFolder parent, ScriptingManager manager) {
34
        this(parent, manager, (File) null);
35
    }
36

    
37
    public DefaultScriptingFolder(ScriptingFolder parent, ScriptingManager manager, File folder) {
38
        super(parent, ScriptingManager.UNIT_FOLDER, manager, null);
39
        this.folder = folder;
40
        if (folder != null) {
41
            this.setId(folder.getName());
42
        }
43
        this.islink = false;
44
   }
45

    
46
    public DefaultScriptingFolder(ScriptingFolder parent, ScriptingManager manager, URL folder) {
47
        super(parent, ScriptingManager.UNIT_FOLDER, manager, null);
48
        if (!folder.getProtocol().equalsIgnoreCase("file")) {
49
            throw new RuntimeException("Protocol URL not supported");
50
        }
51
        File f = new File(folder.getPath());
52
        this.setId(f.getName());
53
        this.folder = f;
54
        this.islink = false;
55
    }
56

    
57
    @Override
58
    public void create(ScriptingFolder folder, String id) {
59
        this.getFile().mkdir();
60
    }
61

    
62
    @Override
63
    public File getFile() {
64
        return this.folder;
65
    }
66

    
67
    @Override
68
    public List<File> getFiles() {
69
        List<File> l = new ArrayList<>();
70
        l.add(this.getFile());
71
        return l;
72
    }
73

    
74
    @Override
75
    public ScriptingFolder getParent() {
76
        ScriptingFolder parent = super.getParent();
77
        if (parent != null) {
78
            return parent;
79
        }
80
        return new DefaultScriptingFolder(null, manager, this.folder.getParentFile());
81
    }
82

    
83
    private String getTypenameFromInf(File file) {
84
        if (file == null) {
85
            logger.warn("Can't load 'inf' file, file is null.");
86
            return null;
87
        }
88
        try {
89
            Ini inf = new Ini(file);
90
            String typename = inf.get("Unit", "type");
91
            if (typename == null) {
92
                return ScriptingManager.UNIT_SCRIPT;
93
            }
94
            return typename;
95
        } catch (Exception e) {
96
            logger.warn("Can't load 'inf' file '" + file.getAbsolutePath() + "'.", e);
97
            return null;
98
        }
99

    
100
    }
101

    
102
    @Override
103
    public Unit getUnit(File afile) {
104
        Unit unit = null;
105

    
106
        File file;
107
        if (afile.isAbsolute()) {
108
            file = afile.getAbsoluteFile();
109
        } else {
110
            file = new File(this.getFile(), afile.getPath());
111
        }
112

    
113
        String id = FilenameUtils.getBaseName(afile.getAbsolutePath());
114
        if( StringUtils.isBlank(id) ) {
115
            id = afile.getName();
116
        }
117
        ScriptingFolder parent;
118
        if (FilenameUtils.equalsNormalizedOnSystem(this.getFile().getAbsolutePath(), file.getParentFile().getAbsolutePath())) {
119
            parent = this;
120
        } else {
121
            parent = new DefaultScriptingFolder(null, manager, file.getParentFile());
122
        }
123

    
124
        if (file.isDirectory()) {
125
            unit = (Unit) this.manager.createUnit(ScriptingManager.UNIT_FOLDER, parent, id);
126

    
127
        } else if (file.isFile()) {
128
            if (!file.getName().endsWith(".inf")) {
129
                file = new File(file.getParentFile(),id + ".inf");
130
            }
131
            if (!file.exists()) {
132
                logger.warn("Can't get Unit, file '" + file.getAbsolutePath() + "' not exists.");
133
                return null;
134
            }
135
            unit = (Unit) this.manager.createUnit(getTypenameFromInf(file), parent, id);
136
        }
137
        return unit;
138
    }
139

    
140
    @Override
141
    public List<ScriptingUnit> getUnits() {
142
        List<ScriptingUnit> ol = new ArrayList<>();
143
        File[] files = this.folder.listFiles(new FilenameFilter() {
144
            @Override
145
            public boolean accept(File arg0, String arg1) {
146
                File f = new File(arg0, arg1);
147
                if (!f.canRead() || f.isHidden()) {
148
                    return false;
149
                }
150
                if (f.isDirectory()) {
151
                    return true;
152
                }
153
                String ext = FilenameUtils.getExtension(f.getName());
154
                return "inf".equalsIgnoreCase(ext);
155
            }
156
        });
157
        Set<File> filesAdded = new HashSet<>();
158
        if (files != null) {
159
//            Arrays.sort(files, new Comparator<File>() {
160
//                @Override
161
//                public int compare(File f1, File f2) {
162
//                    if (f1.isDirectory() && !f2.isDirectory()) {
163
//                        return -1;
164
//                    } else if (!f1.isDirectory() && f2.isDirectory()) {
165
//                        return 1;
166
//                    } else {
167
//                        return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase());
168
//                    }
169
//                }
170
//            });
171
            for (File f : files) {
172
                try {
173
                    ScriptingUnit unit = this.getUnit(f);
174
                    filesAdded.addAll(unit.getFiles());
175
                    ol.add(unit);
176
                } catch (Exception ex) {
177
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.",ex);
178
                }
179
            }
180
        }
181
        files = this.folder.listFiles(new FilenameFilter() {
182
            @Override
183
            public boolean accept(File arg0, String arg1) {
184
                File f = new File(arg0, arg1);
185
                if (!f.canRead() || f.isHidden()) {
186
                    return false;
187
                }
188
                if (f.isDirectory()) {
189
                    return true;
190
                }
191
                return true;
192
            }
193
        });
194
        if (files != null) {
195
            for (File f : files) {
196
                try {
197
                    String extension = FilenameUtils.getExtension(f.getName());
198
                    if( "inf".equalsIgnoreCase(extension) || "class".equalsIgnoreCase(extension) ) {
199
                        continue;
200
                    }
201
                    if( !filesAdded.contains(f) ) {
202
                        ScriptingUnit unit = this.manager.createExternalFile(this, f.getName());
203
                        filesAdded.addAll(unit.getFiles());
204
                        ol.add(unit);
205
                    } 
206
                } catch (Exception ex) {
207
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.",ex);
208
                }
209
            }
210
        }
211
        Collections.sort(ol, new Comparator<ScriptingUnit>() {
212

    
213
            @Override
214
            public int compare(ScriptingUnit o1, ScriptingUnit o2) {
215
                if( o1 instanceof ScriptingFolder ) {
216
                    if( ! (o2 instanceof ScriptingFolder) ) {
217
                        return -1;
218
                    }
219
                } else if( o2 instanceof ScriptingFolder ) { 
220
                    return 1;
221
                }
222
                return o1.getId().compareToIgnoreCase(o2.getId());
223
            }
224
        });
225
        return ol;
226
    }
227

    
228
    @Override
229
    public List<ScriptingFolder> getUnitFolders() {
230
        List<ScriptingFolder> ol = new ArrayList<>();
231
        File[] files = this.folder.listFiles(new FilenameFilter() {
232
            @Override
233
            public boolean accept(File arg0, String arg1) {
234
                File f = new File(arg0, arg1);
235
                if (!f.canRead() || f.isHidden()) {
236
                    return false;
237
                }
238
                if (f.isDirectory()) {
239
                    return true;
240
                }
241
                String ext = FilenameUtils.getExtension(f.getName());
242
                return "inf".equalsIgnoreCase(ext);
243
            }
244
        });
245
        if (files != null) {
246
            Arrays.sort(files, new Comparator<File>() {
247
                @Override
248
                public int compare(File f1, File f2) {
249
                    if (f1.isDirectory() && !f2.isDirectory()) {
250
                        return -1;
251
                    } else if (!f1.isDirectory() && f2.isDirectory()) {
252
                        return 1;
253
                    } else {
254
                        return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase());
255
                    }
256
                }
257
            });
258
            for (File f : files) {
259
                try {
260
                    ScriptingUnit unit = this.getUnit(f);
261
                    if( unit instanceof ScriptingFolder ) {
262
                        ol.add((ScriptingFolder) unit);
263
                    }
264
                } catch (Exception ex) {
265
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.");
266
                }
267
            }
268
        }
269
        return ol;
270
    }
271

    
272
    @Override
273
    public void add(ScriptingUnit unit) {
274
        unit.move(this);
275
    }
276

    
277
    @Override
278
    public void remove(ScriptingUnit unit) {
279
        unit.remove();
280
    }
281

    
282
    @Override
283
    public void load(ScriptingFolder folder, String id) {
284
        DefaultScriptingFolder parent = (DefaultScriptingFolder) folder;
285
        this.setParent(folder);
286
        this.setId(id);
287
        this.folder = new File(parent.getFile(), id);
288
        File f = getFileResource(".inf");
289
        if (f.isFile()) {
290
            Ini prefs;
291
            try {
292
                prefs = new Ini(f);
293
                loadInf(prefs);
294
                String spath = getInfString(
295
                        prefs, 
296
                        ScriptingManager.UNIT_FOLDER, 
297
                        "path",
298
                        null
299
                );
300
                if( StringUtils.isEmpty(spath) ) {
301
                    this.folder = this.folder.getAbsoluteFile();
302
                    this.islink = false;
303
                } else {
304
                    File path = new File(spath);
305
                    if( path.isAbsolute() ) {
306
                        this.folder = path;
307
                    } else {
308
                        this.folder = new File(parent.getFile(), spath);
309
                    }
310
                    this.islink = true;
311
                }
312
            } catch (Exception e) {
313
                logger.warn("Can't load 'inf' file '" + f.getAbsolutePath() + "'.", e);
314
            }
315
        }        
316
    }
317

    
318
    @Override
319
    public String[] getIconNames() {
320
        return new String[]{"folder", "folder-drag-accept"};
321
    }
322

    
323
    @Override
324
    public boolean remove() {
325
        File f = this.getFile();
326
        try {
327
            File infofile = getFileResource(".inf");
328
            if( infofile.exists() ) {
329
                FileUtils.forceDelete(infofile);
330
            }            
331
            if( !this.islink ) {
332
                if( f!=null ) {
333
                    FileUtils.forceDelete(this.getFile());
334
                }
335
            }
336
            return true;
337
        } catch (Throwable e) {
338
            logger.warn("Can't remove folder '" + ((f==null)?"unknown":f.getAbsolutePath()) + "'.", e);
339
            return false;
340
        }
341
    }
342

    
343
    @Override
344
    public void create(ScriptingFolder folder, String id, String language) {
345
        File f = new File(folder.getFile(), id);
346
        f.mkdir();
347
        this.load(folder, id);
348
    }
349

    
350
    @Override
351
    public boolean move(ScriptingFolder target) {
352
        if (! manager.validateUnitId(target, this.getId()) ) {
353
            logger.info("Can't move folder '"+this.getId()+"' to '"+target.getFile().getAbsolutePath()+"', is not valid.");
354
            return false;
355
        }
356
        try {
357
            File infofile = getFileResource(".inf");
358
            if( infofile.exists() ) {
359
                FileUtils.moveFileToDirectory(infofile, target.getFile(), true);
360
            }
361
            if( !this.islink ) {
362
                FileUtils.moveDirectoryToDirectory(this.getFile(), target.getFile(),true);
363
            }
364
            this.parent = target;
365
            this.load(target, id);
366
        } catch (IOException ex) {
367
            logger.info("Can't move folder '"+this.getId()+"' to '"+target.getFile().getAbsolutePath()+"', "+ex.getMessage(),ex);
368
            return false;
369
        }
370
        return true;
371
    }
372

    
373
    @Override
374
    public boolean rename(String newId) {
375
        if (! manager.validateUnitId(this.getParent(), newId) ) {
376
            logger.info("Can't rename folder '"+this.getId()+"', target id '"+newId+"' is not valid.");
377
            return false;
378
        }
379
        try {
380
            File target = this.getParent().getFile();
381
            File infofile = getFileResource(".inf");
382
            if( this.islink ) {
383
                FileUtils.moveFile(infofile, new File(target,newId));
384
            } else {
385
                FileUtils.moveDirectory(this.getFile(), new File(target,newId));
386
                if( infofile.exists() ) {
387
                    FileUtils.moveFile(infofile, new File(target,newId));
388
                }
389
            }
390
            this.setId(newId);
391
            this.load(this.getParent(), id);
392
        } catch (IOException ex) {
393
            logger.info("Can't rename folder '"+this.getId()+"' to '"+newId+"', "+ex.getMessage(),ex);
394
            return false;
395
        }        
396
        return true;
397
    }
398

    
399
    @Override
400
    public void accept(Visitor visitor) throws BaseException {
401
        List<ScriptingUnit> units = this.getUnits();
402
        for( ScriptingUnit unit : units ) {
403
            if( unit instanceof ScriptingFolder ) {
404
                ScriptingFolder folder = (ScriptingFolder) unit;
405
                folder.accept(visitor);
406
            } else {
407
                visitor.visit(unit);
408
            }
409
        }
410
    }
411
    
412
    
413
    
414
}