/plugins/OpenIt/trunk/src/org/etheridge/openit/sourcepath/QuickAccessSourcePath.java

# · Java · 250 lines · 115 code · 36 blank · 99 comment · 23 complexity · 02704b9a42b5d0a47fb633dd032c152d MD5 · raw file

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