|
59 | 59 | import java.io.Writer;
|
60 | 60 | import java.net.URL;
|
61 | 61 | import java.util.ArrayList;
|
| 62 | +import java.util.Collection; |
62 | 63 | import java.util.Collections;
|
63 | 64 | import java.util.Comparator;
|
64 | 65 | import java.util.Date;
|
|
107 | 108 | import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
|
108 | 109 | import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
109 | 110 | import org.fife.ui.rsyntaxtextarea.TokenMakerFactory;
|
| 111 | +import org.reflections.Reflections; |
| 112 | +import org.reflections.scanners.SubTypesScanner; |
| 113 | +import org.reflections.util.ClasspathHelper; |
| 114 | +import org.reflections.util.ConfigurationBuilder; |
110 | 115 | import org.scijava.Context;
|
111 | 116 | import org.scijava.command.CommandService;
|
112 | 117 | import org.scijava.event.ContextDisposingEvent;
|
@@ -168,6 +173,7 @@ public class TextEditor extends JFrame implements ActionListener,
|
168 | 173 | }
|
169 | 174 |
|
170 | 175 | private static AbstractTokenMakerFactory tokenMakerFactory = null;
|
| 176 | + private static Reflections reflections = null; |
171 | 177 |
|
172 | 178 | private JTabbedPane tabbed;
|
173 | 179 | private JMenuItem newFile, open, save, saveas, compileAndRun, compile,
|
@@ -2064,9 +2070,37 @@ public String getSelectedTextOrAsk(final String label) {
|
2064 | 2070 | public String getSelectedClassNameOrAsk() {
|
2065 | 2071 | String className = getSelectedTextOrAsk("Class name");
|
2066 | 2072 | if (className != null) className = className.trim();
|
| 2073 | + |
2067 | 2074 | return className;
|
2068 | 2075 | }
|
2069 | 2076 |
|
| 2077 | + /** |
| 2078 | + * Returns the static Reflections instance, constructing it |
| 2079 | + * if it doesn't already exist. This is to limit the number of |
| 2080 | + * classpath scans. |
| 2081 | + * |
| 2082 | + * @return static {@link Reflections} instance |
| 2083 | + */ |
| 2084 | + private static Reflections getReflections() { |
| 2085 | + if (reflections == null) { |
| 2086 | + synchronized(TextEditor.class) { |
| 2087 | + if (reflections == null) { |
| 2088 | + final Collection<URL> packages = new HashSet<>(); |
| 2089 | + packages.addAll(ClasspathHelper.forPackage("net.imagej")); |
| 2090 | + packages.addAll(ClasspathHelper.forPackage("org.scijava")); |
| 2091 | + packages.addAll(ClasspathHelper.forPackage("net.imglib2")); |
| 2092 | + packages.addAll(ClasspathHelper.forPackage("io.scif")); |
| 2093 | + packages.addAll(ClasspathHelper.forPackage("sc.fiji")); |
| 2094 | + packages.addAll(ClasspathHelper.forPackage("ij")); |
| 2095 | + reflections = new Reflections(new ConfigurationBuilder().setUrls( |
| 2096 | + packages).setScanners(new SubTypesScanner(false))); |
| 2097 | + } |
| 2098 | + } |
| 2099 | + } |
| 2100 | + |
| 2101 | + return reflections; |
| 2102 | + } |
| 2103 | + |
2070 | 2104 | private static void append(final JTextArea textArea, final String text) {
|
2071 | 2105 | final int length = textArea.getDocument().getLength();
|
2072 | 2106 | textArea.insert(text, length);
|
@@ -2209,7 +2243,38 @@ private void updateGitDirectory() {
|
2209 | 2243 |
|
2210 | 2244 | public void addImport(final String className) {
|
2211 | 2245 | if (className != null) {
|
2212 |
| - new TokenFunctions(getTextArea()).addImport(className.trim()); |
| 2246 | + |
| 2247 | + boolean addRaw = true; |
| 2248 | + |
| 2249 | + // If there are NO package separators then this is a raw class name. Try |
| 2250 | + // and find matching packages |
| 2251 | + |
| 2252 | + // NB: decided to only look for complete class names without packages. |
| 2253 | + // Matching "endsWith(className) can produce a plethora of false positives |
| 2254 | + // which we want to limit, because the current implementation imports |
| 2255 | + // all matches. |
| 2256 | + // Some alternatives to consider (including combinations): |
| 2257 | + // - match *className |
| 2258 | + // - match *className* |
| 2259 | + // - match .className* |
| 2260 | + // - if >1 match show list to the user to choose a "winner" to import |
| 2261 | + if (!className.contains(".")) { |
| 2262 | + final String packagedClass = "." + className; |
| 2263 | + final Reflections refl = TextEditor.getReflections(); |
| 2264 | + final StringBuilder sb = new StringBuilder(); |
| 2265 | + |
| 2266 | + for (final String type : refl.getAllTypes()) { |
| 2267 | + // look for "blah.className" |
| 2268 | + if (type.endsWith(packagedClass)) { |
| 2269 | + addRaw = false; |
| 2270 | + new TokenFunctions(getTextArea()).addImport(type.trim()); |
| 2271 | + } |
| 2272 | + } |
| 2273 | + } |
| 2274 | + |
| 2275 | + // If there was a package separator or no matching packages, import the raw |
| 2276 | + // class. |
| 2277 | + if (addRaw) new TokenFunctions(getTextArea()).addImport(className.trim()); |
2213 | 2278 | }
|
2214 | 2279 | }
|
2215 | 2280 |
|
|
0 commit comments