/plugins/OpenIt/tags/OpenIt-1_04/src/org/etheridge/openit/sourcepath/QuickAccessSourcePath.java

# · Java · 221 lines · 100 code · 29 blank · 92 comment · 22 complexity · 15cdc538f7e6323cc55af16834f02d63 MD5 · raw file

  1. /*
  2. * OpenIt jEdit Plugin (QuickAccessSourcePath.java)
  3. *
  4. * Copyright (C) 2003 Matt Etheridge (matt@etheridge.org)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. package org.etheridge.openit.sourcepath;
  21. import gnu.regexp.RE;
  22. import gnu.regexp.REException;
  23. import gnu.regexp.RESyntax;
  24. import java.util.ArrayList;
  25. import java.util.Collections;
  26. import java.util.HashMap;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.Map;
  30. import org.etheridge.openit.OpenItProperties;
  31. import org.etheridge.openit.sourcepath.SourcePath;
  32. import org.etheridge.openit.sourcepath.SourcePathElement;
  33. import org.etheridge.openit.sourcepath.SourcePathFile;
  34. import org.gjt.sp.jedit.jEdit;
  35. import org.gjt.sp.util.Log;
  36. /**
  37. * This class is a wrapper around a SourcePath that provides quicker access to
  38. * the elements in a source path.
  39. *
  40. * On construction it will take all of the elements in the source path and store
  41. * them in data structures that provide quick access to the underlying source
  42. * path files.
  43. *
  44. * NOTE: this wrapper is provided to provide for better GUI response time.
  45. */
  46. public class QuickAccessSourcePath
  47. {
  48. // the wrapped source path
  49. private SourcePath mWrappedSourcePath;
  50. // quick access data map - this is where the "quick" access is implemented.
  51. // maps between each letter of the alphabet (a-z) and a list of source path
  52. // files that begin with that letter.
  53. //
  54. // Theoretically this should increase data access 26 times faster, however
  55. // letter distribution is not quite so simple ;)
  56. //
  57. // NOTE: if there are NO classes starting with a particular letter, there will
  58. // be NO entry in the map.
  59. //
  60. // For example:
  61. //
  62. // a -> [Alpha.java, Animal.java, Allo.java]
  63. // b -> [Bob.java, Builder.java]
  64. // ...
  65. // z -> [Zebra.java]
  66. private Map mQuickAccessMap;
  67. /**
  68. * Substring index size - this integer determines how many characters should
  69. * be used as a substring index into the quick access map.
  70. *
  71. * For example, if the index size is 2, and the file to be indexed is
  72. * "this.java", the following indexes will be added to the quick access map
  73. * if they do not already exist (and "this.java" will be mapped):
  74. *
  75. * th - this.java
  76. * hi - this.java
  77. * is - this.java
  78. * s. - this.java
  79. * .j - this.java
  80. * ja - this.java
  81. * av - this.java
  82. * va - this.java
  83. *
  84. * The higher the substring index size the more potential indexes there will
  85. * be, meaning it will take longer to index, but will be quicker doing lookups.
  86. *
  87. * This value *could* be user-configurable, to allow the user to control this
  88. * ratio.
  89. */
  90. private static final int msIndexSize = 2;
  91. /**
  92. * Constructs a QuickAccessSourcePath
  93. *
  94. * NOTE: this is a *BUSY* constructor - it will potentially take a while!
  95. */
  96. public QuickAccessSourcePath(SourcePath sourcePath)
  97. {
  98. mWrappedSourcePath = sourcePath;
  99. initialize();
  100. }
  101. /**
  102. * Gets a list of all SourceFiles starting with the specified character.
  103. */
  104. public List getSourceFilesStartingWith(char ch)
  105. {
  106. List sourceFileList = (List) mQuickAccessMap.get(String.valueOf(ch).toLowerCase());
  107. if(sourceFileList == null) {
  108. return new ArrayList();
  109. }
  110. return Collections.unmodifiableList(sourceFileList);
  111. }
  112. /**
  113. * Gets a list of all SourceFiles containing the specified substring.
  114. */
  115. public List getSourceFilesContaining(String string)
  116. {
  117. if (string.length() > msIndexSize) {
  118. string = string.substring(0,msIndexSize);
  119. }
  120. List sourceFileList = (List) mQuickAccessMap.get(string.toLowerCase());
  121. if(sourceFileList == null) {
  122. return new ArrayList();
  123. }
  124. return Collections.unmodifiableList(sourceFileList);
  125. }
  126. //
  127. // private helper methods
  128. //
  129. private void initialize()
  130. {
  131. RE regularExpression = null;
  132. try {
  133. String regularExpressionProperty =
  134. jEdit.getProperty(OpenItProperties.EXCLUDES_REGULAR_EXPRESSION);
  135. if (regularExpressionProperty != null) {
  136. regularExpression = new RE(org.gjt.sp.jedit.MiscUtilities.globToRE(
  137. regularExpressionProperty), RE.REG_MULTILINE, RESyntax.RE_SYNTAX_POSIX_EXTENDED);
  138. }
  139. } catch (REException e) {
  140. Log.log(Log.MESSAGE, QuickAccessSourcePath.class,
  141. "[OpenIt Plugin]: Invalid excludes regular expression: " +
  142. jEdit.getProperty(OpenItProperties.EXCLUDES_REGULAR_EXPRESSION));
  143. }
  144. // initialize the quick access map
  145. mQuickAccessMap = new HashMap();
  146. // for each element in the source path, go through its list of classes
  147. // and
  148. for (Iterator i = mWrappedSourcePath.getSourcePathElements().iterator(); i.hasNext();) {
  149. SourcePathElement sourcePathElement = (SourcePathElement) i.next();
  150. // iterate through files and store in quick access map
  151. for (Iterator j = sourcePathElement.getSourcePathFiles().iterator(); j.hasNext();) {
  152. SourcePathFile sourcePathFile = (SourcePathFile) j.next();
  153. // if the filename does not match the excludes regular expression then
  154. // add it to the quick access map, otherwise ignore it.
  155. if (regularExpression == null || !regularExpression.isMatch(sourcePathFile.getFullName())) {
  156. // get first letter
  157. String firstLetter = sourcePathFile.getFullName().toLowerCase().substring(0,1);
  158. List currentLetterList = (List) mQuickAccessMap.get(firstLetter);
  159. if (currentLetterList == null) {
  160. currentLetterList = new ArrayList();
  161. mQuickAccessMap.put(firstLetter, currentLetterList);
  162. }
  163. if (!currentLetterList.contains(sourcePathFile)) {
  164. currentLetterList.add(sourcePathFile);
  165. }
  166. // index substrings if user wants them indexed
  167. if (jEdit.getBooleanProperty(OpenItProperties.ALLOW_SUBSTRING_MATCHING, true)) {
  168. String fileName = sourcePathFile.getFullName().toLowerCase();
  169. for (int x = 0; x < fileName.length(); x++) {
  170. if (x <= fileName.length() - msIndexSize) {
  171. String currentSubstring = fileName.substring(x, x+msIndexSize);
  172. List substringList = (List) mQuickAccessMap.get(currentSubstring);
  173. if (substringList == null) {
  174. substringList = new ArrayList();
  175. mQuickAccessMap.put(currentSubstring, substringList);
  176. }
  177. if (!substringList.contains(sourcePathFile)) {
  178. substringList.add(sourcePathFile);
  179. }
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. // sort each list in the quick access map
  187. for (Iterator i = mQuickAccessMap.values().iterator(); i.hasNext();) {
  188. List currentList = (List) i.next();
  189. Collections.sort(currentList);
  190. }
  191. }
  192. }