PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/help/HelpIndex.java

#
Java | 395 lines | 280 code | 44 blank | 71 comment | 43 complexity | f0ee9309210eab1e3d8b7e31944ff46a 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 e = jar.entries();
  134. while(e.hasMoreElements())
  135. {
  136. ZipEntry entry = (ZipEntry)e.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. // used to mark words to ignore (see constructor for the list)
  185. private static Object IGNORE = new Object();
  186. private HashMap words;
  187. private ArrayList files;
  188. //{{{ ignoreWord() method
  189. private void ignoreWord(String word)
  190. {
  191. words.put(word,IGNORE);
  192. } //}}}
  193. //{{{ indexStream() method
  194. /**
  195. * Reads the specified HTML file and adds all words defined therein to the
  196. * index.
  197. * @param _in The input stream
  198. * @param file The file
  199. */
  200. private void indexStream(InputStream _in, String fileName)
  201. throws Exception
  202. {
  203. HelpFile file = new HelpFile(fileName);
  204. files.add(file);
  205. int index = files.size() - 1;
  206. StringBuffer titleText = new StringBuffer();
  207. BufferedReader in = new BufferedReader(
  208. new InputStreamReader(_in));
  209. try
  210. {
  211. StringBuffer word = new StringBuffer();
  212. boolean insideTag = false;
  213. boolean insideEntity = false;
  214. boolean title = false;
  215. int c;
  216. while((c = in.read()) != -1)
  217. {
  218. char ch = (char)c;
  219. if(insideTag)
  220. {
  221. if(ch == '>')
  222. {
  223. if(word.toString().equals("title"))
  224. title = true;
  225. insideTag = false;
  226. word.setLength(0);
  227. }
  228. else
  229. word.append(ch);
  230. }
  231. else if(insideEntity)
  232. {
  233. if(ch == ';')
  234. insideEntity = false;
  235. }
  236. else if(ch == '<')
  237. {
  238. if(title)
  239. title = false;
  240. if(word.length() != 0)
  241. {
  242. addWord(word.toString(),index,title);
  243. word.setLength(0);
  244. }
  245. insideTag = true;
  246. }
  247. else if(ch == '&')
  248. insideEntity = true;
  249. else if(title)
  250. titleText.append(ch);
  251. else if(!Character.isLetterOrDigit(ch))
  252. {
  253. if(word.length() != 0)
  254. {
  255. addWord(word.toString(),index,title);
  256. word.setLength(0);
  257. }
  258. }
  259. else
  260. word.append(ch);
  261. }
  262. }
  263. finally
  264. {
  265. in.close();
  266. }
  267. if(titleText.length() == 0)
  268. file.title = fileName;
  269. else
  270. file.title = titleText.toString();
  271. } //}}}
  272. //{{{ addWord() method
  273. private void addWord(String word, int file, boolean title)
  274. {
  275. word = word.toLowerCase();
  276. Object o = words.get(word);
  277. if(o == IGNORE)
  278. return;
  279. if(o == null)
  280. words.put(word,new Word(word,file,title));
  281. else
  282. ((Word)o).addOccurrence(file,title);
  283. } //}}}
  284. //}}}
  285. //{{{ Word class
  286. static class Word
  287. {
  288. // how much an occurrence in the title is worth
  289. static final int TITLE_OCCUR = 10;
  290. // the word
  291. String word;
  292. // files it occurs in
  293. int occurCount = 0;
  294. Occurrence[] occurrences;
  295. Word(String word, int file, boolean title)
  296. {
  297. this.word = word;
  298. occurrences = new Occurrence[5];
  299. addOccurrence(file,title);
  300. }
  301. void addOccurrence(int file, boolean title)
  302. {
  303. for(int i = 0; i < occurCount; i++)
  304. {
  305. if(occurrences[i].file == file)
  306. {
  307. occurrences[i].count += (title ? TITLE_OCCUR : 1);
  308. return;
  309. }
  310. }
  311. if(occurCount >= occurrences.length)
  312. {
  313. Occurrence[] newOccur = new Occurrence[occurrences.length * 2];
  314. System.arraycopy(occurrences,0,newOccur,0,occurCount);
  315. occurrences = newOccur;
  316. }
  317. occurrences[occurCount++] = new Occurrence(file,title);
  318. }
  319. static class Occurrence
  320. {
  321. int file;
  322. int count;
  323. Occurrence(int file, boolean title)
  324. {
  325. this.file = file;
  326. this.count = (title ? TITLE_OCCUR : 1);
  327. }
  328. }
  329. } //}}}
  330. //{{{ HelpFile class
  331. static class HelpFile
  332. {
  333. String file;
  334. String title;
  335. HelpFile(String file)
  336. {
  337. this.file = file;
  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. }