1 19 package org.netbeans.modules.subversion.ui.history; 20 21 import org.openide.util.NbBundle; 22 import org.openide.util.RequestProcessor; 23 import org.openide.ErrorManager; 24 import org.netbeans.modules.subversion.util.SvnUtils; 25 import org.netbeans.modules.subversion.Subversion; 26 import org.netbeans.modules.subversion.client.SvnProgressSupport; 27 import org.netbeans.modules.subversion.client.SvnClient; 28 import org.tigris.subversion.svnclientadapter.*; 29 30 import javax.swing.*; 31 import java.text.SimpleDateFormat ; 32 import java.text.DateFormat ; 33 import java.util.*; 34 import java.io.File ; 35 36 41 class SearchExecutor implements Runnable { 42 43 public static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm"); 45 static final SimpleDateFormat fullDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss Z"); static final DateFormat [] dateFormats = new DateFormat [] { 47 fullDateFormat, 48 new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"), simpleDateFormat, 50 new SimpleDateFormat ("yyyy-MM-dd"), }; 52 53 private final SearchHistoryPanel master; 54 private Map<SVNUrl, Set<File >> workFiles; 55 private Map<String ,File > pathToRoot; 56 private final SearchCriteriaPanel criteria; 57 private boolean filterUsername; 58 private boolean filterMessage; 59 60 private int completedSearches; 61 private boolean searchCanceled; 62 private List<RepositoryRevision> results = new ArrayList<RepositoryRevision>(); 63 64 public SearchExecutor(SearchHistoryPanel master) { 65 this.master = master; 66 criteria = master.getCriteria(); 67 filterUsername = criteria.getUsername() != null; 68 filterMessage = criteria.getCommitMessage() != null; 69 70 pathToRoot = new HashMap<String , File >(); 71 if (searchingUrl()) { 72 String rootPath = SvnUtils.getRepositoryPath(master.getRoots()[0]); 73 pathToRoot.put(rootPath, master.getRoots()[0]); 74 } else { 75 workFiles = new HashMap<SVNUrl, Set<File >>(); 76 for (File file : master.getRoots()) { 77 String rootPath = SvnUtils.getRepositoryPath(file); 78 String fileAbsPath = file.getAbsolutePath().replace(File.separatorChar, '/'); 79 int commonPathLength = getCommonPostfixLength(rootPath, fileAbsPath); 80 pathToRoot.put(rootPath.substring(0, rootPath.length() - commonPathLength), 81 new File (fileAbsPath.substring(0, fileAbsPath.length() - commonPathLength))); 82 SVNUrl rootUrl = SvnUtils.getRepositoryRootUrl(file); 83 Set<File > set = workFiles.get(rootUrl); 84 if (set == null) { 85 set = new HashSet<File >(2); 86 workFiles.put(rootUrl, set); 87 } 88 set.add(file); 89 } 90 } 91 } 92 93 private int getCommonPostfixLength(String a, String b) { 94 int ai = a.length() - 1; 95 int bi = b.length() - 1; 96 int slash = -1; 97 for (;;) { 98 if (ai < 0 || bi < 0) break; 99 char ca = a.charAt(ai); 100 char cb = b.charAt(bi); 101 if(ca == '/') slash = ai; 102 if ( ca != cb ) { 103 if(slash > -1) { 104 return a.length() - slash; 105 } 106 break; 107 } 108 ai--; bi--; 109 } 110 return a.length() - ai - 1; 111 } 112 113 114 115 public void run() { 116 117 final SVNRevision fromRevision = criteria.getFrom(); 118 final SVNRevision toRevision = criteria.getTo(); 119 120 completedSearches = 0; 121 if (searchingUrl()) { 122 RequestProcessor rp = Subversion.getInstance().getRequestProcessor(master.getRepositoryUrl()); 123 SvnProgressSupport support = new SvnProgressSupport() { 124 public void perform() { 125 search(master.getRepositoryUrl(), null, fromRevision, toRevision, this); 126 } 127 }; 128 support.start(rp, master.getRepositoryUrl(), NbBundle.getMessage(SearchExecutor.class, "MSG_Search_Progress")); } else { 130 for (Iterator i = workFiles.keySet().iterator(); i.hasNext();) { 131 final SVNUrl rootUrl = (SVNUrl) i.next(); 132 final Set<File > files = workFiles.get(rootUrl); 133 RequestProcessor rp = Subversion.getInstance().getRequestProcessor(rootUrl); 134 SvnProgressSupport support = new SvnProgressSupport() { 135 public void perform() { 136 search(rootUrl, files, fromRevision, toRevision, this); 137 } 138 }; 139 support.start(rp, rootUrl, NbBundle.getMessage(SearchExecutor.class, "MSG_Search_Progress")); } 141 } 142 } 143 144 private void search(SVNUrl rootUrl, Set<File > files, SVNRevision fromRevision, SVNRevision toRevision, SvnProgressSupport progressSupport) { 145 SvnClient client; 146 try { 147 client = Subversion.getInstance().getClient(rootUrl, progressSupport); 148 } catch (SVNClientException ex) { 149 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 150 return; 151 } 152 if (progressSupport.isCanceled()) { 153 searchCanceled = true; 154 return; 155 } 156 157 if (searchingUrl()) { 158 try { 159 ISVNLogMessage [] messages = client.getLogMessages(rootUrl, null, fromRevision, toRevision, false, true, 0); 160 appendResults(rootUrl, messages); 161 } catch (SVNClientException e) { 162 progressSupport.annotate(e); 163 } 164 } else { 165 String [] paths = new String [files.size()]; 166 int idx = 0; 167 for (File file : files) { 168 paths[idx++] = SvnUtils.getRelativePath(rootUrl, file); 169 } 170 try { 171 ISVNLogMessage [] messages = client.getLogMessages(rootUrl, paths, fromRevision, toRevision, false, true); 172 appendResults(rootUrl, messages); 173 } catch (SVNClientException e) { 174 progressSupport.annotate(e); 175 } 176 } 177 } 178 179 185 private synchronized void appendResults(SVNUrl rootUrl, ISVNLogMessage[] logMessages) { 186 Map<String , String > historyPaths = new HashMap<String , String >(); 188 189 for (int i = logMessages.length - 1; i >= 0; i--) { 191 ISVNLogMessage logMessage = logMessages[i]; 192 if (filterUsername && !criteria.getUsername().equals(logMessage.getAuthor())) continue; 193 if (filterMessage && logMessage.getMessage().indexOf(criteria.getCommitMessage()) == -1) continue; 194 RepositoryRevision rev = new RepositoryRevision(logMessage, rootUrl); 195 for (RepositoryRevision.Event event : rev.getEvents()) { 196 if (event.getChangedPath().getAction() == 'A' && event.getChangedPath().getCopySrcPath() != null) { 197 String existingMapping = historyPaths.get(event.getChangedPath().getPath()); 199 if (existingMapping == null) { 200 existingMapping = event.getChangedPath().getPath(); 201 } 202 historyPaths.put(event.getChangedPath().getCopySrcPath(), existingMapping); 203 } 204 String originalFilePath = event.getChangedPath().getPath(); 205 for (String srcPath : historyPaths.keySet()) { 206 if (originalFilePath.startsWith(srcPath)) { 207 originalFilePath = historyPaths.get(srcPath) + originalFilePath.substring(srcPath.length()); 208 break; 209 } 210 } 211 File file = computeFile(originalFilePath); 212 event.setFile(file); 213 } 214 results.add(rev); 215 } 216 checkFinished(); 217 } 218 219 private boolean searchingUrl() { 220 return master.getRepositoryUrl() != null; 221 } 222 223 private File computeFile(String path) { 224 for (String s : pathToRoot.keySet()) { 225 if (path.startsWith(s)) { 226 return new File (pathToRoot.get(s), path.substring(s.length())); 227 } 228 } 229 return null; 230 } 231 232 private void checkFinished() { 233 completedSearches++; 234 if (searchingUrl() && completedSearches >= 1 || workFiles.size() == completedSearches) { 235 SwingUtilities.invokeLater(new Runnable () { 236 public void run() { 237 master.setResults(results); 238 } 239 }); 240 } 241 } 242 243 244 } 245 | Popular Tags |