1 19 20 package org.netbeans.spi.java.project.support.ui; 21 22 import java.awt.EventQueue ; 23 import java.io.File ; 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import java.util.SortedSet ; 27 import java.util.TreeSet ; 28 import java.util.regex.Pattern ; 29 import javax.swing.JComponent ; 30 import javax.swing.event.ChangeEvent ; 31 import javax.swing.event.ChangeListener ; 32 import org.netbeans.spi.project.support.ant.PathMatcher; 33 import org.openide.util.NbPreferences; 34 import org.openide.util.Parameters; 35 import org.openide.util.RequestProcessor; 36 37 48 public class IncludeExcludeVisualizer { 49 50 private File [] roots = {}; 51 private String includes = "**"; private String excludes = ""; private final List <ChangeListener > listeners = new ArrayList <ChangeListener >(1); 54 private IncludeExcludeVisualizerPanel panel; 55 private SortedSet <File > included = new TreeSet <File >(); 56 private SortedSet <File > excluded = new TreeSet <File >(); 57 private boolean busy = false; 58 private boolean interrupted = false; 59 private static final RequestProcessor RP = new RequestProcessor(IncludeExcludeVisualizer.class.getName()); 60 private final RequestProcessor.Task task = RP.create(new RecalculateTask()); 61 62 67 public IncludeExcludeVisualizer() {} 68 69 74 public synchronized void setRoots(File [] roots) throws IllegalArgumentException { 75 Parameters.notNull("roots", roots); 76 for (File root : roots) { 77 if (!root.isDirectory()) { 78 throw new IllegalArgumentException (root.getAbsolutePath()); 79 } 80 } 81 this.roots = roots; 82 recalculate(); 83 } 84 85 89 public synchronized String getIncludePattern() { 90 return includes; 91 } 92 93 98 public synchronized void setIncludePattern(String pattern) { 99 Parameters.notNull("pattern", pattern); 100 includes = pattern; 101 updateIncludesExcludes(); 102 recalculate(); 103 } 104 105 109 public synchronized String getExcludePattern() { 110 return excludes; 111 } 112 113 118 public synchronized void setExcludePattern(String pattern) { 119 Parameters.notNull("pattern", pattern); 120 excludes = pattern; 121 updateIncludesExcludes(); 122 recalculate(); 123 } 124 125 private synchronized void updateIncludesExcludes() { 126 if (panel != null) { 127 EventQueue.invokeLater(new Runnable () { 128 public void run() { 129 panel.setFields(includes, excludes); 130 } 131 }); 132 } 133 } 134 135 139 public synchronized void addChangeListener(ChangeListener l) { 140 listeners.add(l); 141 } 142 143 147 public synchronized void removeChangeListener(ChangeListener l) { 148 listeners.remove(l); 149 } 150 151 154 synchronized void changedPatterns(String includes, String excludes) { 155 this.includes = includes; 156 this.excludes = excludes; 157 recalculate(); 158 fireChange(); 159 } 160 161 private synchronized void fireChange() { 162 ChangeEvent e = new ChangeEvent (this); 163 for (ChangeListener l : listeners) { 164 l.stateChanged(e); 165 } 166 } 167 168 173 public synchronized JComponent getVisualizerPanel() { 174 if (!EventQueue.isDispatchThread()) { 175 throw new IllegalThreadStateException ("must be called in EQ"); 176 } 177 if (panel == null) { 178 panel = new IncludeExcludeVisualizerPanel(this); 179 panel.setFields(includes, excludes); 180 panel.setFiles(included.toArray(new File [included.size()]), excluded.toArray(new File [excluded.size()]), busy); 181 } 182 return panel; 183 } 184 185 private static final int DELAY = 200; 186 private synchronized void recalculate() { 187 interrupted = true; 188 task.schedule(DELAY); 189 } 190 191 private void updateFiles() { 192 assert Thread.holdsLock(this); 193 EventQueue.invokeLater(new Runnable () { 194 public void run() { 195 synchronized (IncludeExcludeVisualizer.this) { 196 if (panel != null) { 197 panel.setFiles(included.toArray(new File [included.size()]), excluded.toArray(new File [excluded.size()]), busy); 198 } 199 } 200 } 201 }); 202 } 203 204 private int scanCounter; 205 private static final int GRANULARITY = 1000; 206 private void scan(File d, String prefix, PathMatcher matcher, Pattern ignoredFiles) { 207 String [] children = d.list(); 208 if (children == null) { 209 return; 210 } 211 for (String child : children) { 212 if (ignoredFiles.matcher(child).find()) { 213 continue; 214 } 215 File f = new File (d, child); 216 boolean dir = f.isDirectory(); 217 if (dir) { 218 scan(f, prefix + child + "/", matcher, ignoredFiles); } else { 220 synchronized (this) { 221 if (interrupted) { 222 return; 223 } 224 if (matcher.matches(prefix + child, false)) { 225 included.add(f); 226 } else { 227 excluded.add(f); 228 } 229 if (++scanCounter % GRANULARITY == 0) { 230 updateFiles(); 231 } 232 } 233 } 234 } 235 } 236 237 private final class RecalculateTask implements Runnable { 238 239 final Pattern ignoredFiles = Pattern.compile(NbPreferences.root().node("/org/netbeans/core"). get("IgnoredFiles", "^(CVS|SCCS|vssver\\.scc|#.*#|%.*%|\\.(cvsignore|svn|DS_Store)|_svn)$|~$|^\\..*$")); 244 public void run() { 245 File [] _roots; 246 String _includes, _excludes; 247 synchronized (IncludeExcludeVisualizer.this) { 248 busy = true; 249 included.clear(); 250 excluded.clear(); 251 _roots = roots.clone(); 252 _includes = includes; 253 _excludes = excludes; 254 interrupted = false; 255 updateFiles(); 256 } 257 PathMatcher matcher = new PathMatcher(_includes, _excludes, null); 258 for (File root : _roots) { 259 scan(root, "", matcher, ignoredFiles); 260 } 261 synchronized (IncludeExcludeVisualizer.this) { 262 busy = false; 263 updateFiles(); 264 } 265 } 266 267 } 268 269 } 270 | Popular Tags |