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 / DefaultScriptingHelpManager.java @ 478

History | View | Annotate | Download (20.2 KB)

1
package org.gvsig.scripting.impl;
2

    
3
import org.gvsig.scripting.HelpConfig;
4
import java.io.BufferedReader;
5
import java.io.File;
6
import java.io.FileNotFoundException;
7
import java.io.FileReader;
8
import java.io.IOException;
9
import java.io.Reader;
10
import java.io.Writer;
11
import java.net.MalformedURLException;
12
import java.net.URISyntaxException;
13
import java.net.URL;
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.logging.Level;
23
import javax.help.HelpSet;
24
import javax.help.HelpSetException;
25
import org.apache.commons.io.FileUtils;
26
import org.apache.commons.io.FilenameUtils;
27
import org.apache.commons.io.IOUtils;
28
import org.gvsig.scripting.ScriptingHelpManager;
29
import org.gvsig.scripting.ScriptingManager;
30
import org.gvsig.tools.task.SimpleTaskStatus;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
public class DefaultScriptingHelpManager implements ScriptingHelpManager {
35

    
36
    protected static final Logger logger = LoggerFactory.getLogger(DefaultScriptingHelpManager.class);
37

    
38
    private ScriptingManager manager;
39

    
40
    protected HelpSet helpSet = null;
41
    protected IndexerHelper indexer;
42
    protected MethodList methodsList;
43
    protected List<File> helpRoots = null;
44

    
45
    public DefaultScriptingHelpManager(ScriptingManager manager) {
46
        this.manager = manager;
47
        this.methodsList = new MethodList();
48
    }
49

    
50
    private void initializeHelpSet() {
51
        HelpSet helpSet = null;
52
        File f = new File(this.manager.getHomeFolder(), "help");
53
        if (!f.exists()) {
54
            try {
55
                FileUtils.forceMkdir(f);
56
            } catch (IOException ex) {
57
                logger.warn("Can't create help folder in '" + f.getAbsolutePath() + "'.", ex);
58
            }
59
        }
60
        ClassLoader loader = this.getClass().getClassLoader();
61
        URL resource = loader.getResource("org/gvsig/scripting/apihelp/api.hs");
62
        if (resource == null) {
63
            logger.info("Can't initialize help framework. Can't find 'api.hs'.");
64
        } else {
65
            try {
66
                helpSet = new HelpSet(loader, resource);
67
            } catch (HelpSetException e) {
68
                logger.info("Can't initialize help framework, can't create HelpSet from '" + resource.toString() + "'.", e);
69
            }
70
        }
71
        this.helpSet = helpSet;
72
        loadHelps();
73
    }
74

    
75
    public void loadHelps() {
76
//        HelpConfig helpConfig = new DefaultHelpConfig();
77
        List<File> folders = this.getHelpRoots();
78
        for (File folder : folders) {
79
            File[] helpFolders = folder.listFiles();
80
            for (File helpFolder : helpFolders) {
81
                HelpSet helpset = loadHelp(helpFolder);
82
                if (helpset != null) {
83
                    this.getHelpSet().add(helpset);
84
                }
85
            }
86
        }
87
    }
88

    
89
    public URL makeURL(File helpsetfolder, URL sourceurl) {
90
        if( sourceurl==null ) {
91
            return null;
92
        }
93
        URL url ;
94
        HelpConfig helpConfig = new DefaultHelpConfig();
95
        if (helpsetfolder == null) {
96
            List<File> folders = this.getHelpRoots();
97
            for (File folder : folders) {
98
                File[] helpFolders = folder.listFiles();
99
                for (File helpFolder : helpFolders) {
100
                    if( helpConfig.exists(helpFolder) ) {
101
                        if( helpConfig.load(helpFolder) ) {
102
                            ClassLoader loader = helpConfig.getLoader();
103
                            url = loader.getResource(sourceurl.getPath().substring(1));
104
                            if( url != null ) {
105
                                return url;
106
                            }
107
                        }
108
                    }
109
                }
110
            }
111
        } else {
112
            if( helpConfig.load(helpsetfolder) ) {
113
                ClassLoader loader = helpConfig.getLoader();
114
                url = loader.getResource(sourceurl.getPath());
115
                if( url != null ) {
116
                    return url;
117
                }
118
                if( sourceurl.getPath().startsWith(helpsetfolder.getPath()) ) {
119
                    int n = helpsetfolder.getPath().length()+1;
120
                    url = loader.getResource(sourceurl.getPath().substring(n));
121
                    if( url != null ) {
122
                        return url;
123
                    }
124
                }
125
            }
126
        }
127
        return sourceurl;
128
    }    
129
    
130
    private HelpSet loadHelp(File folder) {
131
        HelpConfig helpConfig = new DefaultHelpConfig();
132

    
133
        if (!helpConfig.exists(folder)) {
134
            return null;
135
        }
136
        if (!helpConfig.load(folder)) {
137
            logger.warn("Can't load help from folder '"+folder.getAbsolutePath()+"'.");
138
            return null;
139
        }
140

    
141
        File helpindex = helpConfig.getHelpIndex();
142
        if (helpindex != null) {
143
            this.methodsList.addMethods(helpindex);
144
        }
145
        HelpSet helpset = helpConfig.createHelpSet();
146
        return helpset;
147
    }
148

    
149
    public void reloadHelp() {
150
        this.helpSet = null;
151
        this.initializeHelpSet();
152
    }
153

    
154
    @Override
155
    public boolean existsHelp(String name) {
156
        HelpConfig helpConfig = new DefaultHelpConfig();
157
        List<File> folders = this.getHelpRoots();
158
        for (File folder : folders) {
159
            if (helpConfig.exists(FileUtils.getFile(folder,name))) {
160
                return true;
161
            }
162
        }
163
        return false;
164
    }
165

    
166
    @Override
167
    public boolean removeHelp(String name) {
168
        HelpConfig helpConfig = new DefaultHelpConfig();
169
        List<File> folders = this.getHelpRoots();
170
        for (File folder : folders) {
171
            if (helpConfig.exists(folder)) {
172
                try {
173
                    FileUtils.forceDelete(folder);
174
                    return true;
175
                } catch (IOException ex) {
176
                    return true;
177
                }
178
            }
179
        }
180
        return false;
181
    }
182

    
183
    @Override
184
    public void addMethods(URL methodsfile) {
185
        this.methodsList.addMethods(methodsfile);
186
    }
187

    
188
    @Override
189
    public List<ScriptingHelpMethod> getMethods() {
190
        return this.methodsList;
191
    }
192

    
193
    @Override
194
    public ScriptingHelpClass getHelpClass(String name) {
195
        return this.methodsList.getHelpClass(name);
196
    }
197

    
198
    @Override
199
    public List<ScriptingHelpClass> getHelpClasses() {
200
        return this.methodsList.getHelpClasses();
201
    }
202

    
203
    @Override
204
    public Map<String, ScriptingHelpMethod> findMethods(String text) {
205
        return this.methodsList.findMethods(text);
206
    }
207

    
208
    @Override
209
    public List<File> getHelpRoots() {
210
        if (this.helpRoots == null) {
211
            List<File> helpRoots = new ArrayList();
212
            helpRoots.add(new File(this.manager.getHomeFolder(), "help"));
213
            this.helpRoots = helpRoots;
214
        }
215
        return this.helpRoots;
216
    }
217

    
218
    @Override
219
    public HelpSet getHelpSet() {
220
        if (this.helpSet == null) {
221
            this.initializeHelpSet();
222
        }
223
        return this.helpSet;
224
    }
225

    
226
    private BufferedReader createFileReader(File f) {
227
        if (f == null) {
228
            logger.warn("Can't create reader file is null.");
229
            return null;
230
        }
231
        Reader fileReader;
232
        try {
233
            fileReader = new FileReader(f);
234
        } catch (FileNotFoundException ex) {
235
            logger.warn("Can't create reader from '" + f.getAbsolutePath() + "'.", ex);
236
            return null;
237
        }
238
        return new BufferedReader(fileReader);
239
    }
240

    
241
    private int countLines(File textfile) {
242
        try {
243
            BufferedReader reader = createFileReader(textfile);
244
            int nlines = 0;
245
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
246
                nlines++;
247
            }
248
            return nlines;
249
        } catch (IOException ex) {
250
            return -1;
251
        }
252
    }
253

    
254
    @Override
255
    public boolean importJavadoc(String name, File folder, SimpleTaskStatus status) {
256
        if (existsHelp(name)) {
257
            status.message("Help '" + name + "' already exists");
258
            status.abort();
259
            return false;
260
        }
261
        status.setIndeterminate();
262
        status.message(("Preparing import of javadoc..."));
263

    
264
        HelpConfig config = new DefaultHelpConfig();
265

    
266
        File rootFolder = this.getHelpRoots().get(0);
267
        config.create(rootFolder, name, folder);
268

    
269
        Writer helpsetWriter = null;
270
        Writer tocWriter = null;
271
        Writer mappingWriter = null;
272
        Writer indexWriter = null;
273
        BufferedReader packageListReader = null;
274

    
275
        try {
276

    
277
            helpsetWriter = config.getHelpSetWriter();
278
            helpsetWriter.write(
279
                    "<?xml version='1.0' encoding='ISO-8859-1' ?>\n"
280
                    + "<!DOCTYPE helpset\n"
281
                    + "  PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 1.0//EN\"\n"
282
                    + "                   \"http://java.sun.com/products/javahelp/helpset_1_0.dtd\">\n\n"
283
                    + "<?TestTarget this is data for the test target ?>\n\n"
284
                    + "<helpset version=\"1.0\">\n\n"
285
                    + "  <!-- title -->\n"
286
                    + "  <title>" + config.getName() + "</title>\n\n"
287
                    + "  <!-- maps -->\n"
288
                    + "  <maps>\n"
289
                    + "     <homeID>main</homeID>\n"
290
                    + "     <mapref location=\""+HelpConfig.FILENAME_HELPMAPPING+"\"/>\n"
291
                    + "  </maps>\n\n"
292
                    + "  <!-- views -->\n"
293
                    + "  <view>\n"
294
                    + "    <name>TOC</name>\n"
295
                    + "    <label>TOC</label>\n"
296
                    + "    <type>javax.help.TOCView</type>\n"
297
                    + "    <data>"+HelpConfig.FILENAME_HELPTOC+"</data>\n"
298
                    + "  </view>\n\n"
299
                    + "  <view>\n"
300
                    + "    <name>Index</name>\n"
301
                    + "    <label>Index</label>\n"
302
                    + "    <type>javax.help.IndexView</type>\n"
303
                    + "    <data>"+HelpConfig.FILENAME_HELPINDEX+"</data>\n"
304
                    + "  </view>\n"
305
                    + "  <view>\n"
306
                    + "    <name>Search</name>\n"
307
                    + "    <label>Search</label>\n"
308
                    + "    <type>javax.help.SearchView</type>\n"
309
                    + "    <data engine=\"com.sun.java.help.search.DefaultSearchEngine\">"+HelpConfig.FILENAME_SEARCHDB+"</data>\n"
310
                    + "  </view>\n\n"
311
                    + "  <view>\n"
312
                    + "    <name>Favorites</name>\n"
313
                    + "    <label>Favoritos</label>\n"
314
                    + "    <type>javax.help.FavoritesView</type>\n"
315
                    + "  </view>\n\n"
316
                    + "  <presentation default=\"true\" displayviewimages=\"false\">\n"
317
                    + "     <name>main window</name>\n"
318
                    + "     <size width=\"700\" height=\"400\" />\n"
319
                    + "     <location x=\"200\" y=\"200\" />\n"
320
                    + "     <title>gvSIG - Ayuda en linea</title>\n"
321
                    + "     <image>toplevelfolder</image>\n"
322
                    + "     <toolbar>\n"
323
                    + "       <helpaction image=\"action.back\">javax.help.BackAction</helpaction>\n"
324
                    + "       <helpaction image=\"action.forward\">javax.help.ForwardAction</helpaction>\n"
325
                    + "     </toolbar>\n"
326
                    + "  </presentation>\n"
327
                    + "</helpset>"
328
            );
329
            IOUtils.closeQuietly(helpsetWriter);
330

    
331
            tocWriter = config.getTOCWriter();
332
            mappingWriter = config.getHelpMappingWriter();
333
            packageListReader = createFileReader(new File(folder, "package-list"));
334

    
335
            status.message("Processing package-list");
336
            status.setRangeOfValues(0, countLines(new File(folder, "package-list")));
337

    
338
            mappingWriter.write(
339
                    "<?xml version='1.0' encoding='ISO-8859-1' ?>\n"
340
                    + "<!DOCTYPE map\n"
341
                    + "  PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp Map Version 1.0//EN\"\n"
342
                    + "         \"http://java.sun.com/products/javahelp/map_1_0.dtd\">\n\n"
343
                    + "<map version=\"1.0\">\n"
344
            );
345
            tocWriter.write(
346
                    "<!DOCTYPE toc\n"
347
                    + "  PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 1.0//EN\"\n    "
348
                    + "         \"http://java.sun.com/products/javahelp/toc_1_0.dtd\">\n\n"
349
                    + "<toc version=\"1.0\">\n"
350
            );
351
            int count = 0;
352
            tocWriter.write("<tocitem text=\"" + name + "\">\n");
353
            String line = packageListReader.readLine();
354
            while (line != null) {
355
                tocWriter.write("\t<tocitem text=\"" + line + "\">\n");
356
                File f = new File(folder, line.replace(".", File.separator));
357
                if (f.isDirectory() && f.canRead()) {
358
                    String[] fileNames = f.list();
359
                    Arrays.sort(fileNames, String.CASE_INSENSITIVE_ORDER);
360
                    for (int i = 0; i < fileNames.length; i++) {
361
                        if (fileNames[i].toLowerCase().endsWith(".html") &&
362
                            ! fileNames[i].contains("-")    ) {
363
                            String fileName = FilenameUtils.removeExtension(fileNames[i]);
364

    
365
                            tocWriter.write("\t\t<tocitem text=\"");
366
                            tocWriter.write(fileName);
367
                            tocWriter.write("\" target=\"");
368
                            tocWriter.write(line);
369
                            tocWriter.write(".");
370
                            tocWriter.write(fileName);
371
                            tocWriter.write(".html\"/>\n");
372

    
373
                            String targetid = line + "." + fileName;
374
                            String url = "/"+targetid.replace(".", "/");
375
                            mappingWriter.write("\t\t<mapID target=\"");
376
                            mappingWriter.write(targetid);
377
                            mappingWriter.write(".html\" url=\"");
378
                            mappingWriter.write(url);
379
                            mappingWriter.write(".html\" />\n");
380
                        }
381
                    }
382
                }
383
                tocWriter.write("\t</tocitem>\n");
384
                line = packageListReader.readLine();
385
                status.setCurValue(count);
386
            }
387
            tocWriter.write("</tocitem>\n");
388
            tocWriter.write("</toc>\n");
389
            mappingWriter.write("</map>\n");
390

    
391
            IOUtils.closeQuietly(tocWriter);
392
            IOUtils.closeQuietly(mappingWriter);
393

    
394
            indexWriter = config.getHelpIndexWriter();
395
            indexWriter.write(
396
                "<?xml version='1.0' encoding='ISO-8859-1' ?>\n" +
397
                "<!DOCTYPE index \n" +
398
                "        PUBLIC \"-//Sun Microsystems Inc.//DTD JavaHelp Index Version 1.0//EN\" \n" +
399
                "                \"http://java.sun.com/javase/technologies/desktop/javahelp/index_1_0.dtd\">\n" +
400
                "\n" +
401
                "<index version=\"1.0\">\n"
402
            );
403
            MethodList methodsIndex = loadJavadocMethodsIndex(new File(folder, "index-all.html"), status);
404
            Iterator<ScriptingHelpMethod> it = methodsIndex.iterator();
405
            while (it.hasNext()) {
406
                ScriptingHelpMethod mn = it.next();
407
                indexWriter.write("\t<indexitem text=\"" + mn.getName() + "\" expand=\"false\">\n");
408
                Iterator<ScriptingHelpClass> itcn = mn.iterator();
409
                while (itcn.hasNext()) {
410
                    ScriptingHelpClass cn = itcn.next();
411
                    indexWriter.write("\t\t<indexitem text=\"" + cn.getName() + "\" target=\"" + cn.getUrl() + "\" />\n");
412
                }
413
                indexWriter.write("\t</indexitem>\n");
414
            }
415
            indexWriter.write("</index>\n");
416
            IOUtils.closeQuietly(indexWriter);
417
        
418
            File docsFolder = config.getDocsFolder();
419
            if( docsFolder!=null ) {
420
                // Si no puede obtener el fichero donde estan los docs como un File,
421
                // probablemente sea por que los documentos esten zipeados,
422
                // Y en ese caso no se pueden indexar.
423
                status.message("Indexing files");
424
                status.setIndeterminate();
425
                IndexerHelper indexer = new IndexerHelper();
426
                indexer.index(
427
                        config.getIndexerConfig(),
428
                        config.getSearchdb(),
429
                        docsFolder
430
                );
431
            }
432
        
433
            status.message("Loading help");
434
            HelpSet helpset = loadHelp(config.getFolder());
435
            if (helpset != null) {
436
                this.getHelpSet().add(helpset);
437
            }
438

    
439
        } catch (IOException ex) {
440
            logger.warn("Can't import help '" + name + "' from '" + folder.getAbsolutePath() + "'.", ex);
441
            status.abort();
442
            return false;
443

    
444
        } finally {
445
            IOUtils.closeQuietly(tocWriter);
446
            IOUtils.closeQuietly(mappingWriter);
447
            IOUtils.closeQuietly(helpsetWriter);
448
            IOUtils.closeQuietly(indexWriter);
449
            IOUtils.closeQuietly(packageListReader);
450
        }
451

    
452
        return true;
453
    }
454

    
455
    private MethodList loadJavadocMethodsIndex(File indexallFile, SimpleTaskStatus status) throws IOException {
456
        try {
457
            Map<String, Set<String>> classes = new HashMap();
458
            
459
            BufferedReader indexallReader = createFileReader(indexallFile);
460
            status.message("Loading methods information...");
461
            status.setRangeOfValues(0, countLines(indexallFile));
462
            int count = 0;
463
            for (String line = indexallReader.readLine(); line != null; line = indexallReader.readLine()) {
464
                line = line.replaceAll("\\<.*?\\>", "");
465
                String parts[] = line.split(" ");
466
                int l = parts.length;
467
                if (l > 4 && "Method".equalsIgnoreCase(parts[l - 4])) {
468
                    String classname = parts[l - 1];
469
                    String methodname = parts[0];
470
                    int n = methodname.indexOf("(");
471
                    if (n > 0) {
472
                        methodname = methodname.substring(0, n);
473
                    }
474
                    Set<String> classmethods = classes.get(classname);
475
                    if (classmethods == null) {
476
                        classmethods = new HashSet<String>();
477
                        classes.put(classname, classmethods);
478
                    }
479
                    classmethods.add(methodname);
480
                }
481
                status.setCurValue(count++);
482
            }
483

    
484
            status.message("Processing methods information...");
485
            status.setRangeOfValues(0, classes.size());
486
            count = 0;
487
            
488
            MethodList methodsIndex = new MethodList();
489
            Iterator<Map.Entry<String, Set<String>>> it = classes.entrySet().iterator();
490
            while (it.hasNext()) {
491
                Map.Entry<String, Set<String>> entry = it.next();
492
                String[] ss = entry.getKey().split("[.]");
493
                String classname = ss[ss.length - 1];
494
                methodsIndex.add(classname, entry.getKey() + ".html", new ArrayList(entry.getValue()));
495
                status.setCurValue(count++);
496
            }
497
            return methodsIndex;
498
        } catch (IOException ex) {
499
            logger.warn("Can't load methods information from '"+indexallFile.getAbsolutePath()+"'.",ex);
500
            throw ex;
501
        }
502
    }
503

    
504
//    public List<ScriptingHelpAPI> getAPI() {
505
//        String[] files = this.getFolder().list();
506
//        List<ScriptingHelpAPI> apis = new ArrayList<ScriptingHelpAPI>();
507
//
508
//        for (int i = 0; i < files.length; i++) {
509
//            apis.add(new DefaultScriptingHelpAPI(files[i]));
510
//        }
511
//        return apis;
512
//    }
513
//
514
//    private static class DefaultScriptingHelpAPI implements ScriptingHelpAPI {
515
//
516
//        private final String name;
517
//
518
//        DefaultScriptingHelpAPI(String name) {
519
//            this.name = name;
520
//        }
521
//
522
//        public String getName() {
523
//            return this.name;
524
//        }
525
//
526
//    }
527

    
528
}