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

History | View | Annotate | Download (15.8 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.util.ArrayList;
7
import java.util.List;
8
import java.util.Arrays;
9
import java.util.Collections;
10
import java.util.Comparator;
11
import java.util.HashSet;
12
import java.util.Set;
13
import java.util.function.Predicate;
14

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

    
26
public class DefaultScriptingFolder extends AbstractUnit implements ScriptingFolder {
27

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

    
32
    protected DefaultScriptingFolder(ScriptingManager manager) {
33
        super(null, ScriptingManager.UNIT_FOLDER, manager, null);
34
    }
35

    
36
    public DefaultScriptingFolder(ScriptingFolder parent, ScriptingManager manager, File folder) {
37
        super(parent, ScriptingManager.UNIT_FOLDER, manager, null);
38
        this.folder = new File(FilenameUtils.normalizeNoEndSeparator(folder.getAbsolutePath(),true));
39
        this.infFile = null;
40
        if( folder.isFile() ) {
41
            if( !folder.getName().toLowerCase().endsWith(".inf") ) {
42
                throw new IllegalArgumentException("folder argument can be a folder.");
43
            }
44
            if( !folder.exists() ) {
45
                throw new IllegalArgumentException("Can't access to folder inf file ("+folder.getAbsolutePath()+").");
46
            }
47
            this.loadInf(folder);
48
        } else {
49
            this.setId(folder.getName());
50
            File f = new File(folder.getParentFile(),this.getId() + ".inf");
51
            if (f.isFile()) {
52
                this.loadInf(f);
53
            }
54
        }
55
   }
56
    
57
    @Override
58
    public void create(ScriptingFolder folder, String id) {
59
        File f = new File(folder.getFile(), id);
60
        f.mkdir();
61
        this.load(folder, id);    }
62

    
63
    @Override
64
    public void create(ScriptingFolder folder, String id, String language) {
65
        this.create(folder, id);
66
    }
67
    
68
    @Override
69
    public File getFile() {
70
        return this.folder;
71
    }
72

    
73
    @Override
74
    public List<File> getFiles() {
75
        List<File> l = new ArrayList<>();
76
        l.add(this.getFile());
77
        return l;
78
    }
79

    
80
    @Override
81
    public ScriptingFolder getParent() {
82
        ScriptingFolder parent = super.getParent();
83
        if( parent != null ) {
84
            return parent;
85
        }
86
        File f = this.infFile;
87
        if( f==null ) {
88
            // Is a link
89
            f = this.folder;
90
        } 
91
        if( FileUtils.isSameFile(this.manager.getRootUserFolder(), f) ) {
92
            return null;
93
        }
94
        if( FileUtils.isRootFile(f) ) {
95
            return null;
96
        }
97
//        if( !DefaultScriptingManager.isSubfolder(this.manager.getRootUserFolder(), f) ) {
98
//            return null;
99
//        }        
100

    
101
        return manager.getFolder(f.getParentFile());
102
    }
103

    
104
    private String getTypenameFromInf(File file) {
105
        if (file == null) {
106
            logger.warn("Can't load 'inf' file, file is null.");
107
            return null;
108
        }
109
        try {
110
            Ini inf = new Ini(file);
111
            String typename = inf.get("Unit", "type");
112
            if (typename == null) {
113
                return ScriptingManager.UNIT_SCRIPT;
114
            }
115
            return typename;
116
        } catch (Exception e) {
117
            logger.warn("Can't load 'inf' file '" + file.getAbsolutePath() + "'.", e);
118
            return null;
119
        }
120

    
121
    }
122

    
123
    @Override
124
    public Unit getUnit(File afile) {
125
        Unit unit = null;
126

    
127
        File file;
128
        if (afile.isAbsolute()) {
129
            file = afile.getAbsoluteFile();
130
        } else {
131
            file = new File(this.getFile(), afile.getPath());
132
        }
133

    
134
        String id = FilenameUtils.getBaseName(afile.getAbsolutePath());
135
        if( StringUtils.isBlank(id) ) {
136
            id = afile.getName();
137
        }
138
        ScriptingFolder parent;
139
        if (FilenameUtils.equalsNormalizedOnSystem(this.getFile().getAbsolutePath(), file.getParentFile().getAbsolutePath())) {
140
            parent = this;
141
        } else {
142
            parent = new DefaultScriptingFolder(null, manager, file.getParentFile());
143
        }
144

    
145
        if (file.isDirectory()) {
146
            unit = (Unit) this.manager.createUnit(ScriptingManager.UNIT_FOLDER, parent, id);
147

    
148
        } else if (file.isFile()) {
149
            if (!file.getName().endsWith(".inf")) {
150
                file = new File(file.getParentFile(),id + ".inf");
151
            }
152
            if (!file.exists()) {
153
                logger.warn("Can't get Unit, file '" + file.getAbsolutePath() + "' not exists.");
154
                return null;
155
            }
156
            unit = (Unit) this.manager.createUnit(getTypenameFromInf(file), parent, id);
157
        }
158
        return unit;
159
    }
160

    
161
    @Override
162
    public List<ScriptingUnit> getUnits() {
163
        List<ScriptingUnit> ol = new ArrayList<>();
164
        File[] files = this.folder.listFiles(new FilenameFilter() {
165
            @Override
166
            public boolean accept(File arg0, String arg1) {
167
                File f = new File(arg0, arg1);
168
                if (!f.canRead() || f.isHidden()) {
169
                    return false;
170
                }
171
                if (f.isDirectory()) {
172
                    return true;
173
                }
174
                String ext = FilenameUtils.getExtension(f.getName());
175
                return "inf".equalsIgnoreCase(ext);
176
            }
177
        });
178
        Set<File> filesAdded = new HashSet<>();
179
        if (files != null) {
180
//            Arrays.sort(files, new Comparator<File>() {
181
//                @Override
182
//                public int compare(File f1, File f2) {
183
//                    if (f1.isDirectory() && !f2.isDirectory()) {
184
//                        return -1;
185
//                    } else if (!f1.isDirectory() && f2.isDirectory()) {
186
//                        return 1;
187
//                    } else {
188
//                        return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase());
189
//                    }
190
//                }
191
//            });
192
            for (File f : files) {
193
                try {
194
                    ScriptingUnit unit = this.getUnit(f);
195
                    filesAdded.addAll(unit.getFiles());
196
                    ol.add(unit);
197
                } catch (Exception ex) {
198
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.",ex);
199
                }
200
            }
201
        }
202
        files = this.folder.listFiles(new FilenameFilter() {
203
            @Override
204
            public boolean accept(File arg0, String arg1) {
205
                File f = new File(arg0, arg1);
206
                if (!f.canRead() || f.isHidden()) {
207
                    return false;
208
                }
209
                if (f.isDirectory()) {
210
                    return true;
211
                }
212
                return true;
213
            }
214
        });
215
        if (files != null) {
216
            for (File f : files) {
217
                try {
218
                    String extension = FilenameUtils.getExtension(f.getName());
219
                    if( "inf".equalsIgnoreCase(extension) || "class".equalsIgnoreCase(extension) ) {
220
                        continue;
221
                    }
222
                    if( !filesAdded.contains(f) ) {
223
                        ScriptingUnit unit = this.manager.createExternalFile(this, f.getName());
224
                        filesAdded.addAll(unit.getFiles());
225
                        ol.add(unit);
226
                    } 
227
                } catch (Exception ex) {
228
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.",ex);
229
                }
230
            }
231
        }
232
        Collections.sort(ol, new Comparator<ScriptingUnit>() {
233

    
234
            @Override
235
            public int compare(ScriptingUnit o1, ScriptingUnit o2) {
236
                if( o1 instanceof ScriptingFolder ) {
237
                    if( ! (o2 instanceof ScriptingFolder) ) {
238
                        return -1;
239
                    }
240
                } else if( o2 instanceof ScriptingFolder ) { 
241
                    return 1;
242
                }
243
                return o1.getId().compareToIgnoreCase(o2.getId());
244
            }
245
        });
246
        return ol;
247
    }
248

    
249
    @Override
250
    public List<ScriptingFolder> getUnitFolders() {
251
        List<ScriptingFolder> ol = new ArrayList<>();
252
        File[] files = this.folder.listFiles(new FilenameFilter() {
253
            @Override
254
            public boolean accept(File arg0, String arg1) {
255
                File f = new File(arg0, arg1);
256
                if (!f.canRead() || f.isHidden()) {
257
                    return false;
258
                }
259
                if (f.isDirectory()) {
260
                    return true;
261
                }
262
                String ext = FilenameUtils.getExtension(f.getName());
263
                return "inf".equalsIgnoreCase(ext);
264
            }
265
        });
266
        if (files != null) {
267
            Arrays.sort(files, new Comparator<File>() {
268
                @Override
269
                public int compare(File f1, File f2) {
270
                    if (f1.isDirectory() && !f2.isDirectory()) {
271
                        return -1;
272
                    } else if (!f1.isDirectory() && f2.isDirectory()) {
273
                        return 1;
274
                    } else {
275
                        return f1.getName().toLowerCase().compareTo(f2.getName().toLowerCase());
276
                    }
277
                }
278
            });
279
            for (File f : files) {
280
                try {
281
                    ScriptingUnit unit = this.getUnit(f);
282
                    if( unit instanceof ScriptingFolder ) {
283
                        ol.add((ScriptingFolder) unit);
284
                    }
285
                } catch (Exception ex) {
286
                    logger.warn("Can't create unit from file '" + f.getAbsolutePath() + "'.");
287
                }
288
            }
289
        }
290
        return ol;
291
    }
292

    
293
    @Override
294
    public void add(ScriptingUnit unit) {
295
        unit.move(this);
296
    }
297

    
298
    @Override
299
    public void remove(ScriptingUnit unit) {
300
        unit.remove();
301
    }
302

    
303
    @Override
304
    public void load(ScriptingFolder parent, String id) {
305
        File f = new File(parent.getFile(), id+".inf");
306
        if (f.isFile()) {
307
            this.loadInf(f);
308
        } else {
309
            this.setParent(parent);
310
            this.setId(id);
311
        }
312
    }
313
        
314
    private void loadInf(File f) {   
315
        Ini prefs;
316
        try {
317
            prefs = new Ini(f);
318
            loadInf(prefs);
319
            String spath = getInfString(
320
                    prefs, 
321
                    ScriptingManager.UNIT_FOLDER, 
322
                    "path",
323
                    null
324
            );
325
            if( StringUtils.isEmpty(spath) ) {
326
                this.folder = FileUtils.removeExtension(f);
327
                this.infFile = null;
328
            } else {
329
                File path = new File(spath);
330
                if( path.isAbsolute() ) {
331
                    this.folder = path;
332
                } else {
333
                    this.folder = new File(FilenameUtils.concat(f.getParent(), spath));
334
                }
335
                this.infFile = FileUtils.getAbsoluteFile(f);
336
                this.manager.addLink(this.infFile, this.folder);
337
            }
338
            this.folder = FileUtils.getAbsoluteFile(this.folder);
339
            this.setId(FileUtils.getBaseName(f));
340
            this.setParent(manager.getFolder(f.getParentFile()));
341
        } catch (Exception e) {
342
            logger.warn("Can't load 'inf' file '" + f.getAbsolutePath() + "'.", e);
343
        }
344
    }
345

    
346
    @Override
347
    public String[] getIconNames() {
348
        return new String[]{"folder", "folder-drag-accept"};
349
    }
350

    
351
    @Override
352
    public boolean remove() {
353
        File f = this.getFile();
354
        try {
355
            File infofile = getFileResource(".inf");
356
            if( infofile.exists() ) {
357
                FileUtils.forceDelete(infofile);
358
            }            
359
            if( !this.isLink() ) {
360
                if( f!=null ) {
361
                    FileUtils.forceDelete(this.getFile());
362
                }
363
            }
364
            return true;
365
        } catch (Throwable e) {
366
            logger.warn("Can't remove folder '" + ((f==null)?"unknown":f.getAbsolutePath()) + "'.", e);
367
            return false;
368
        }
369
    }
370

    
371
    @Override
372
    public boolean move(ScriptingFolder target) {
373
        if (! manager.validateUnitId(target, this.getId()) ) {
374
            logger.info("Can't move folder '"+this.getId()+"' to '"+target.getFile().getAbsolutePath()+"', is not valid.");
375
            return false;
376
        }
377
        try {
378
            File infofile = getFileResource(".inf");
379
            if( infofile.exists() ) {
380
                FileUtils.moveFileToDirectory(infofile, target.getFile(), true);
381
            }
382
            if( !this.isLink() ) {
383
                FileUtils.moveDirectoryToDirectory(this.getFile(), target.getFile(),true);
384
            }
385
            this.parent = target;
386
            this.load(target, id);
387
        } catch (IOException ex) {
388
            logger.info("Can't move folder '"+this.getId()+"' to '"+target.getFile().getAbsolutePath()+"', "+ex.getMessage(),ex);
389
            return false;
390
        }
391
        return true;
392
    }
393

    
394
    @Override
395
    public boolean rename(String newId) {
396
        if (! manager.validateUnitId(this.getParent(), newId) ) {
397
            logger.info("Can't rename folder '"+this.getId()+"', target id '"+newId+"' is not valid.");
398
            return false;
399
        }
400
        try {
401
            File target = this.getParent().getFile();
402
            File infofile = getFileResource(".inf");
403
            if( this.isLink() ) {
404
                FileUtils.moveFile(infofile, new File(target,newId));
405
            } else {
406
                FileUtils.moveDirectory(this.getFile(), new File(target,newId));
407
                if( infofile.exists() ) {
408
                    FileUtils.moveFile(infofile, new File(target,newId));
409
                }
410
            }
411
            this.setId(newId);
412
            this.load(this.getParent(), id);
413
        } catch (IOException ex) {
414
            logger.info("Can't rename folder '"+this.getId()+"' to '"+newId+"', "+ex.getMessage(),ex);
415
            return false;
416
        }        
417
        return true;
418
    }
419

    
420
    @Override
421
    public void accept(Visitor visitor) throws BaseException {
422
        List<ScriptingUnit> units = this.getUnits();
423
        for( ScriptingUnit unit : units ) {
424
            if( unit instanceof ScriptingFolder ) {
425
                ScriptingFolder folder = (ScriptingFolder) unit;
426
                folder.accept(visitor);
427
            } else {
428
                visitor.visit(unit);
429
            }
430
        }
431
    }
432
    
433
    @Override
434
    public boolean isLink() {
435
        return this.infFile!=null;
436
    }
437
    
438
    @Override
439
    public void accept(Visitor visitor, Predicate<ScriptingUnit> includeFilter) throws BaseException {
440
        List<ScriptingUnit> units = this.getUnits();
441
        for( ScriptingUnit unit : units ) {
442
            if( includeFilter.test(unit) ) {
443
                if( unit instanceof ScriptingFolder ) {
444
                    ScriptingFolder folder = (ScriptingFolder) unit;
445
                    folder.accept(visitor);
446
                } else {
447
                    visitor.visit(unit);
448
                }
449
            }
450
        }
451
    }
452

    
453
    @Override
454
    public void save() {
455
        File f = this.infFile;
456
        if( f==null ) {
457
            f = new File(folder.getParentFile(),this.getId() + ".inf");
458
        }
459
        try {        
460
            Ini prefs = new Ini(f);
461
            this.save(prefs);
462
        } catch (Throwable e) {
463
            String msg = "Can't save 'inf' file '" + f.getAbsolutePath() + "'.";
464
            logger.warn(msg, e);
465
            throw new RuntimeException(msg, e);
466
        }
467
    }
468
}