PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/help/HelpIndex.java

#
Java | 395 lines | 280 code | 44 blank | 71 comment | 43 complexity | b98b895efa214844b80547c0ccfaeb63 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * HelpIndex.java - Index for help searching feature
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2002 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.help;
  23. //{{{ Imports
  24. import java.io.*;
  25. import java.net.*;
  26. import java.util.zip.*;
  27. import java.util.*;
  28. import org.gjt.sp.jedit.io.*;
  29. import org.gjt.sp.jedit.*;
  30. import org.gjt.sp.util.Log;
  31. //}}}
  32. class HelpIndex
  33. {
  34. //{{{ HelpIndex constructor
  35. public HelpIndex()
  36. {
  37. words = new HashMap();
  38. files = new ArrayList();
  39. ignoreWord("a");
  40. ignoreWord("an");
  41. ignoreWord("and");
  42. ignoreWord("are");
  43. ignoreWord("as");
  44. ignoreWord("be");
  45. ignoreWord("by");
  46. ignoreWord("can");
  47. ignoreWord("do");
  48. ignoreWord("for");
  49. ignoreWord("from");
  50. ignoreWord("how");
  51. ignoreWord("i");
  52. ignoreWord("if");
  53. ignoreWord("in");
  54. ignoreWord("is");
  55. ignoreWord("it");
  56. ignoreWord("not");
  57. ignoreWord("of");
  58. ignoreWord("on");
  59. ignoreWord("or");
  60. ignoreWord("s");
  61. ignoreWord("that");
  62. ignoreWord("the");
  63. ignoreWord("this");
  64. ignoreWord("to");
  65. ignoreWord("will");
  66. ignoreWord("with");
  67. ignoreWord("you");
  68. } //}}}
  69. /* //{{{ HelpIndex constructor
  70. public HelpIndex(String fileListPath, String wordIndexPath)
  71. {
  72. this();
  73. } //}}} */
  74. //{{{ indexEditorHelp() method
  75. /**
  76. * Indexes all available help, including the jEdit user's guide, FAQ,]
  77. * and plugin documentation.
  78. */
  79. public void indexEditorHelp()
  80. {
  81. try
  82. {
  83. String jEditHome = jEdit.getJEditHome();
  84. if(jEditHome != null)
  85. {
  86. indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","users-guide"));
  87. indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","FAQ"));
  88. indexDirectory(MiscUtilities.constructPath(jEditHome,"doc","news42"));
  89. }
  90. }
  91. catch(Throwable e)
  92. {
  93. Log.log(Log.ERROR,this,"Error indexing editor help");
  94. Log.log(Log.ERROR,this,e);
  95. }
  96. PluginJAR[] jars = jEdit.getPluginJARs();
  97. for(int i = 0; i < jars.length; i++)
  98. {
  99. try
  100. {
  101. indexJAR(jars[i].getZipFile());
  102. }
  103. catch(Throwable e)
  104. {
  105. Log.log(Log.ERROR,this,"Error indexing JAR: "
  106. + jars[i].getPath());
  107. Log.log(Log.ERROR,this,e);
  108. }
  109. }
  110. Log.log(Log.DEBUG,this,"Indexed " + words.size() + " words");
  111. } //}}}
  112. //{{{ indexDirectory() method
  113. /**
  114. * Indexes all HTML and text files in the specified directory.
  115. * @param dir The directory
  116. */
  117. public void indexDirectory(String dir) throws Exception
  118. {
  119. String[] files = VFSManager.getFileVFS()
  120. ._listDirectory(null,dir,"*.{html,txt}",true,null);
  121. for(int i = 0; i < files.length; i++)
  122. {
  123. indexURL(files[i]);
  124. }
  125. } //}}}
  126. //{{{ indexJAR() method
  127. /**
  128. * Indexes all HTML and text files in the specified JAR file.
  129. * @param jar The JAR file
  130. */
  131. public void indexJAR(ZipFile jar) throws Exception
  132. {
  133. Enumeration enum = jar.entries();
  134. while(enum.hasMoreElements())
  135. {
  136. ZipEntry entry = (ZipEntry)enum.nextElement();
  137. String name = entry.getName();
  138. String lname = name.toLowerCase();
  139. if(lname.endsWith(".html")/* || lname.endsWith(".txt") */)
  140. {
  141. // only works for jEdit plugins
  142. String url = "jeditresource:/" +
  143. MiscUtilities.getFileName(jar.getName())
  144. + "!/" + name;
  145. Log.log(Log.DEBUG,this,url);
  146. indexStream(jar.getInputStream(entry),url);
  147. }
  148. }
  149. } //}}}
  150. //{{{ indexURL() method
  151. /**
  152. * Reads the specified HTML file and adds all words defined therein to the
  153. * index.
  154. * @param url The HTML file's URL
  155. */
  156. public void indexURL(String url) throws Exception
  157. {
  158. InputStream _in;
  159. if(MiscUtilities.isURL(url))
  160. _in = new URL(url).openStream();
  161. else
  162. {
  163. _in = new FileInputStream(url);
  164. // hack since HelpViewer needs a URL...
  165. url = "file:" + url;
  166. }
  167. indexStream(_in,url);
  168. } //}}}
  169. //{{{ lookupWord() method
  170. public Word lookupWord(String word)
  171. {
  172. Object o = words.get(word);
  173. if(o == IGNORE)
  174. return null;
  175. else
  176. return (Word)o;
  177. } //}}}
  178. //{{{ getFile() method
  179. public HelpFile getFile(int index)
  180. {
  181. return (HelpFile)files.get(index);
  182. } //}}}
  183. //{{{ Private members
  184. private static Word.Occurrence[] EMPTY_ARRAY = new Word.Occurrence[0];
  185. // used to mark words to ignore (see constructor for the list)
  186. private static Object IGNORE = new Object();
  187. private HashMap words;
  188. private ArrayList files;
  189. //{{{ ignoreWord() method
  190. private void ignoreWord(String word)
  191. {
  192. words.put(word,IGNORE);
  193. } //}}}
  194. //{{{ indexStream() method
  195. /**
  196. * Reads the specified HTML file and adds all words defined therein to the
  197. * index.
  198. * @param _in The input stream
  199. * @param file The file
  200. */
  201. private void indexStream(InputStream _in, String fileName) throws Exception
  202. {
  203. HelpFile file = new HelpFile(fileName);
  204. files.add(file);
  205. int index = files.size() - 1;
  206. BufferedReader in = new BufferedReader(new InputStreamReader(_in));
  207. StringBuffer titleText = new StringBuffer();
  208. try
  209. {
  210. StringBuffer word = new StringBuffer();
  211. boolean insideTag = false;
  212. boolean insideEntity = false;
  213. boolean title = false;
  214. int c;
  215. while((c = in.read()) != -1)
  216. {
  217. char ch = (char)c;
  218. if(insideTag)
  219. {
  220. if(ch == '>')
  221. {
  222. if(word.toString().equals("title"))
  223. title = true;
  224. insideTag = false;
  225. word.setLength(0);
  226. }
  227. else
  228. word.append(ch);
  229. }
  230. else if(insideEntity)
  231. {
  232. if(ch == ';')
  233. insideEntity = false;
  234. }
  235. else if(ch == '<')
  236. {
  237. if(title)
  238. title = false;
  239. if(word.length() != 0)
  240. {
  241. addWord(word.toString(),index,title);
  242. word.setLength(0);
  243. }
  244. insideTag = true;
  245. }
  246. else if(ch == '&')
  247. insideEntity = true;
  248. else if(title)
  249. titleText.append(ch);
  250. else if(!Character.isLetterOrDigit(ch))
  251. {
  252. if(word.length() != 0)
  253. {
  254. addWord(word.toString(),index,title);
  255. word.setLength(0);
  256. }
  257. }
  258. else
  259. word.append(ch);
  260. }
  261. }
  262. finally
  263. {
  264. in.close();
  265. }
  266. if(titleText.length() == 0)
  267. file.title = fileName;
  268. else
  269. file.title = titleText.toString();
  270. } //}}}
  271. //{{{ addWord() method
  272. private void addWord(String word, int file, boolean title)
  273. {
  274. word = word.toLowerCase();
  275. Object o = words.get(word);
  276. if(o == IGNORE)
  277. return;
  278. if(o == null)
  279. words.put(word,new Word(word,file,title));
  280. else
  281. ((Word)o).addOccurrence(file,title);
  282. } //}}}
  283. //}}}
  284. //{{{ Word class
  285. static class Word
  286. {
  287. // how much an occurrence in the title is worth
  288. static final int TITLE_OCCUR = 10;
  289. // the word
  290. String word;
  291. // files it occurs in
  292. int occurCount = 0;
  293. Occurrence[] occurrences;
  294. Word(String word, int file, boolean title)
  295. {
  296. this.word = word;
  297. occurrences = new Occurrence[5];
  298. addOccurrence(file,title);
  299. }
  300. void addOccurrence(int file, boolean title)
  301. {
  302. for(int i = 0; i < occurCount; i++)
  303. {
  304. if(occurrences[i].file == file)
  305. {
  306. occurrences[i].count += (title ? TITLE_OCCUR : 1);
  307. return;
  308. }
  309. }
  310. if(occurCount >= occurrences.length)
  311. {
  312. Occurrence[] newOccur = new Occurrence[occurrences.length * 2];
  313. System.arraycopy(occurrences,0,newOccur,0,occurCount);
  314. occurrences = newOccur;
  315. }
  316. occurrences[occurCount++] = new Occurrence(file,title);
  317. }
  318. static class Occurrence
  319. {
  320. int file;
  321. int count;
  322. Occurrence(int file, boolean title)
  323. {
  324. this.file = file;
  325. this.count = (title ? TITLE_OCCUR : 1);
  326. }
  327. }
  328. } //}}}
  329. //{{{ HelpFile class
  330. static class HelpFile
  331. {
  332. String file;
  333. String title;
  334. HelpFile(String file)
  335. {
  336. this.file = file;
  337. this.title = title;
  338. }
  339. public String toString()
  340. {
  341. return title;
  342. }
  343. public boolean equals(Object o)
  344. {
  345. if(o instanceof HelpFile)
  346. return ((HelpFile)o).file.equals(file);
  347. else
  348. return false;
  349. }
  350. } //}}}
  351. }