Java tutorial
package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.help; //import static org.apache.commons.lang.StringEscapeUtils.escapeHtml; import java.awt.Desktop; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiReader; import org.apache.lucene.queryparser.classic.MultiFieldQueryParser; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.NoSuchRascalFunction; import org.rascalmpl.library.experiments.tutor3.Concept; import org.rascalmpl.library.experiments.tutor3.Onthology; import org.rascalmpl.value.ISourceLocation; public class HelpManager { private URI coursesDir; private final int maxSearch = 25; private final PrintWriter stdout; private final PrintWriter stderr; private IndexSearcher indexSearcher; private final int port = 8000; private HelpServer helpServer; public HelpManager(ISourceLocation binDir, PrintWriter stdout, PrintWriter stderr) { this.stdout = stdout; this.stderr = stderr; //URL c = this.getClass().getResource("/courses"); coursesDir = binDir.getURI(); try { helpServer = new HelpServer(getPort(), this, Paths.get(coursesDir)); indexSearcher = makeIndexSearcher(); } catch (IOException e) { System.err.println("HelpManager: " + e.getMessage()); } } private ArrayList<IndexReader> getReaders() throws IOException { if (coursesDir.getScheme().equals("file")) { Path destDir = Paths.get(coursesDir); ArrayList<IndexReader> readers = new ArrayList<>(); for (Path p : Files.newDirectoryStream(destDir)) { if (Files.isDirectory(p) && p.getFileName().toString().matches("^[A-Z].*")) { Directory directory = FSDirectory.open(p); try { DirectoryReader ireader = DirectoryReader.open(directory); readers.add(ireader); } catch (IOException e) { stderr.println("Skipping index " + directory); } } } return readers; } throw new IOException("Cannot yet handle non-file coursesDir"); } IndexSearcher makeIndexSearcher() throws IOException { ArrayList<IndexReader> readers = getReaders(); IndexReader[] ireaders = new IndexReader[readers.size()]; for (int i = 0; i < readers.size(); i++) { ireaders[i] = readers.get(i); } IndexReader ireader = new MultiReader(ireaders); return new IndexSearcher(ireader); } private boolean indexAvailable() { if (indexSearcher != null) { return true; } stderr.println("No deployed courses found; they are needed for 'help' or 'apropos'"); return false; } public void openInBrowser(URI uri) { Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { try { desktop.browse(uri); } catch (IOException e) { System.err.println(e.getMessage()); } } else { System.err.println("Desktop not supported, cannout open browser"); } } void appendURL(StringWriter w, String conceptName) { String[] parts = conceptName.split("/"); int n = parts.length; String course = parts[0]; w.append("/").append(course).append("#").append(parts[n - (n > 1 ? 2 : 1)]).append("-") .append(parts[n - 1]); } String makeURL(String conceptName) { StringWriter w = new StringWriter(); appendURL(w, conceptName); return w.toString(); } void appendHyperlink(StringWriter w, String conceptName) { w.append("<a href=\"http://localhost:"); w.append(String.valueOf(getPort())); appendURL(w, conceptName); w.append("\">").append(conceptName).append("</a>"); } private String escapeForQuery(String s) { return s.toLowerCase().replaceAll("([+\\-!(){}\\[\\]\\^\"~*?:\\\\/]|(&&)|(\\|\\|))", "\\\\$1"); } private String escapeHtml(String s) { // TODO: switch to StringEscapeUtils when compiled inside Eclipse return s; } private URI makeSearchURI(String[] words) throws URISyntaxException, UnsupportedEncodingException { StringWriter w = new StringWriter(); for (int i = 1; i < words.length; i++) { w.append(words[i]); if (i < words.length - 1) w.append(" "); } String encoded = URLEncoder.encode(w.toString(), "UTF-8"); return new URI("http", "localhost:" + getPort() + "/Search?searchFor=" + encoded, null); } public void handleHelp(String[] words) { if (words[0].equals("help")) { try { openInBrowser(makeSearchURI(words)); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { stdout.println(giveHelp(words)); } } public String giveHelp(String[] words) { //TODO Add here for example credits, copyright, license if (words.length <= 1) { IntroHelp.print(stdout); return ""; } if (!indexAvailable()) { return ""; } Analyzer multiFieldAnalyzer = Onthology.multiFieldAnalyzer(); try { String searchFields[] = { "index", "synopsis", "doc" }; QueryParser parser = new MultiFieldQueryParser(searchFields, multiFieldAnalyzer); StringBuilder sb = new StringBuilder(); for (int i = 1; i < words.length; i++) { sb.append(" ").append(escapeForQuery(words[i])); } Query query; try { query = parser.parse(sb.toString()); } catch (ParseException e) { stderr.println("Cannot parse query: " + sb + ", " + e.getMessage()); return ""; } if (words[0].equals("help")) { return reportHelp(words, indexSearcher.search(query, maxSearch).scoreDocs); } else { return reportApropos(words, indexSearcher.search(query, maxSearch).scoreDocs); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ""; } String getField(Document hitDoc, String field) { String s = hitDoc.get(field); return (s == null || s.isEmpty()) ? "" : s; } void genPrelude(StringWriter w) { w.append("<head>\n"); w.append("<title>Rascal Help</title>"); w.append("<link rel=\"stylesheet\" href=\"css/style.css\"/>"); w.append("<link rel=\"stylesheet\" href=\"css/font-awesome.min.css\"/>"); w.append("<link rel=\"icon\" href=\"/favicon.ico\" type=\"image/x-icon\"/>"); w.append("</head>\n"); w.append("<body class=\"book toc2 toc-left\">"); w.append(Concept.getHomeLink()); w.append(Concept.getSearchForm()); w.append("<div id=\"toc\" class=\"toc2\">"); w.append("</div>"); } void genSearchTerms(String[] words, StringWriter w) { w.append("<i>"); for (int i = 1; i < words.length; i++) { w.append(words[i]).append(" "); } w.append("</i>\n"); } String reportHelp(String[] words, ScoreDoc[] hits) throws IOException { int nhits = hits.length; StringWriter w = new StringWriter(); if (nhits == 0) { stdout.println("No info found"); genPrelude(w); w.append("<h1 class=\"search-sect0\">No help found for: "); genSearchTerms(words, w); w.append("</h1>\n"); w.append("<div class=\"search-ulist\">\n"); w.append( "<ul><li>Perhaps try <i>help</i>, <i>further reading</i> or <i>introduction</i> as search terms</li>"); w.append("</ul>\n"); w.append("</div>"); w.append("</body>\n"); return w.toString(); } else { genPrelude(w); w.append("<h1 class=\"search-sect0\">Help for: "); genSearchTerms(words, w); w.append("</h1>\n"); w.append("<ul>\n"); for (int i = 0; i < Math.min(hits.length, maxSearch); i++) { Document hitDoc = indexSearcher.doc(hits[i].doc); w.append("<div class=\"search-ulist\">\n"); w.append("<li> "); String name = hitDoc.get("name"); appendHyperlink(w, name); w.append(": <em>").append(escapeHtml(getField(hitDoc, "synopsis"))).append("</em>"); String signature = getField(hitDoc, "signature"); if (!signature.isEmpty()) { w.append("<br>").append("<code>").append(escapeHtml(signature)).append("</code>"); } } w.append("</ul>\n"); w.append("</div>"); w.append("</body>\n"); return w.toString(); } } String reportApropos(String[] words, ScoreDoc[] hits) throws IOException { StringWriter w = new StringWriter(); for (int i = 0; i < Math.min(hits.length, maxSearch); i++) { Document hitDoc = indexSearcher.doc(hits[i].doc); String name = hitDoc.get("name"); String signature = getField(hitDoc, "signature"); String synopsis = getField(hitDoc, "synopsis"); w.append(name).append(":\n\t").append(synopsis); if (!signature.isEmpty()) { w.append("\n\t").append(signature); } w.append("\n"); } return w.toString(); } public int getPort() { return port; } }