1 6 7 package net.sourceforge.cvsgrab; 8 9 import net.sourceforge.cvsgrab.util.ThreadPool; 10 11 import org.apache.commons.jrcs.diff.Revision; 12 import org.apache.commons.jrcs.diff.myers.MyersDiff; 13 import org.apache.commons.jrcs.diff.print.UnifiedPrint; 14 15 import java.io.BufferedReader ; 16 import java.io.File ; 17 import java.io.FileReader ; 18 import java.io.IOException ; 19 import java.io.PrintWriter ; 20 import java.util.ArrayList ; 21 import java.util.Date ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.Properties ; 25 26 33 public class RemoteFile { 34 37 public static final String TEXT_TYPE = "text"; 38 41 public static final String BINARY_TYPE = "binary"; 42 43 private static List textMatches = new ArrayList (); 44 private static List binaryMatches = new ArrayList (); 45 private RemoteDirectory _directory; 46 private String _name; 47 private String _version; 48 private boolean _inAttic = false; 49 private Date _lastModified; 50 51 57 public static void setFileTypes(Properties fileTypes) { 58 for (Iterator i = fileTypes.keySet().iterator(); i.hasNext();) { 59 String pattern = (String ) i.next(); 60 String fileType = (String ) fileTypes.get(pattern); 61 if (TEXT_TYPE.equalsIgnoreCase(fileType)) { 62 textMatches.add(new FileMatcher(pattern)); 63 } else if (BINARY_TYPE.equals(fileType)) { 64 binaryMatches.add(new FileMatcher(pattern)); 65 } else { 66 CVSGrab.getLog().error("Invalid file type for pattern " + pattern + 67 ". Was expecting text or binary instead of " + fileType); 68 } 69 } 70 } 71 72 75 public RemoteFile(String name, String version) { 76 super(); 77 _name = name; 78 _version = version; 79 } 80 81 84 public String getName() { 85 return _name; 86 } 87 88 91 public String getVersion() { 92 return _version; 93 } 94 95 98 public RemoteDirectory getDirectory() { 99 return _directory; 100 } 101 102 105 public boolean isInAttic() { 106 return _inAttic; 107 } 108 109 112 public void setName(String name) { 113 _name = name; 114 } 115 116 119 public void setInAttic(boolean inAttic) { 120 _inAttic = inAttic; 121 } 122 123 127 public void setDirectory(RemoteDirectory directory) { 128 _directory = directory; 129 } 130 131 public Date getLastModified() { 132 return _lastModified; 133 } 134 135 138 public void grab(LocalRepository repository) { 139 _directory.registerRemoteFile(this); 141 RemoteRepository remoteRepository = _directory.getRemoteRepository(); 142 LocalRepository localRepository = remoteRepository.getLocalRepository(); 143 int updateStatus = localRepository.checkUpdateStatus(this); 144 switch (updateStatus) { 145 case LocalRepository.UPDATE_NO_CHANGES: 146 return; 147 case LocalRepository.UPDATE_LOCAL_CHANGE: 148 CVSGrab.getLog().info("M " + this); 149 return; 150 case LocalRepository.UPDATE_IMPOSSIBLE: 151 CVSGrab.getLog().warn("cvs update: warning: cannot update " + this + ". A file with the same name is in the way."); 152 break; 153 case LocalRepository.UPDATE_NEEDED: 154 CVSGrab.getLog().info("U " + this); 155 doUpload(); 156 break; 157 case LocalRepository.UPDATE_MERGE_NEEDED: 158 if (repository.isCleanUpdate()) { 159 repository.backupFile(this); 160 CVSGrab.getLog().info("U " + this); 161 doUpload(); 162 } else { 163 CVSGrab.getLog().info("C " + this); 164 CVSGrab.getLog().warn("cvs update: warning: cannot merge this modified file with the new remote version, feature not yet supported"); 165 } 166 break; 167 default: 168 throw new RuntimeException ("Invalid status " + updateStatus); 169 } 170 } 171 172 176 public void diff(LocalRepository repository, PrintWriter writer, CVSGrab grabber) { 177 RemoteRepository remoteRepository = _directory.getRemoteRepository(); 178 LocalRepository localRepository = remoteRepository.getLocalRepository(); 179 String localVersion = localRepository.getLocalVersion(this); 181 if (localVersion != null) { 182 _version = localVersion; 183 } 184 int updateStatus = localRepository.checkUpdateStatus(this); 185 switch (updateStatus) { 186 case LocalRepository.UPDATE_NO_CHANGES: 187 CVSGrab.getLog().debug("File not updated " + this); 188 return; 189 case LocalRepository.UPDATE_IMPOSSIBLE: 190 CVSGrab.getLog().warn("cvs update: warning: cannot update " + this + ". A file with the same name is in the way."); 191 return; 192 case LocalRepository.UPDATE_NEEDED: 193 CVSGrab.getLog().info("U " + this); 194 return; 195 case LocalRepository.UPDATE_LOCAL_CHANGE: 196 case LocalRepository.UPDATE_MERGE_NEEDED: 197 CVSGrab.getLog().info("M " + this); 198 if (isBinary()) { 199 CVSGrab.getLog().warn("File is modified locally but its type is binary. Update FileTypes.properties if needed."); 200 return; 201 } 202 try { 203 String url = remoteRepository.getDownloadUrl(this); 204 File origFile = File.createTempFile(_name, null); 205 File revFile = localRepository.getLocalFile(this); 206 207 String [] orig = new String [0]; 209 if (localVersion != null) { 210 WebBrowser.getInstance().loadFile(url, origFile); 212 orig = loadFile(origFile.getAbsolutePath()); 213 } 214 215 String [] rev = loadFile(revFile.getAbsolutePath()); 216 MyersDiff diff = new MyersDiff(); 217 Revision revision = diff.diff(orig, rev); 218 StringBuffer sb = new StringBuffer (); 219 UnifiedPrint print = new UnifiedPrint(sb, orig, rev); 220 String localName = localRepository.getLocalFile(this).getCanonicalPath(); 222 localName = localName.substring(new File (grabber.getDestDir()).getCanonicalPath().length() + 1); 223 print.setFileName(localName); 224 String rcsName = WebBrowser.forceFinalSlash(grabber.getCvsRoot()) 226 + WebBrowser.forceFinalSlash(getDirectory().getDirectoryPath()) + getName(); 227 rcsName = rcsName.substring(rcsName.lastIndexOf(':') + 1); 228 print.setRCSFileName(rcsName); 229 print.setOriginalVersion(localRepository.getLocalVersion(this)); 230 print.setRevisedModifDate(new Date (revFile.lastModified())); 231 revision.accept(print); 232 print.close(); 233 writer.print(sb.toString()); 234 } catch (Exception ex) { 235 CVSGrab.getLog().error("IO Error: " + ex); 236 ex.printStackTrace(); 237 } 238 239 break; 240 default: 241 throw new RuntimeException ("Invalid status " + updateStatus); 242 } 243 } 244 245 248 public boolean isBinary() { 249 for (Iterator i = textMatches.iterator(); i.hasNext();) { 250 FileMatcher matcher = (FileMatcher) i.next(); 251 if (matcher.match(getName())) { 252 return false; 253 } 254 } 255 for (Iterator i = binaryMatches.iterator(); i.hasNext();) { 256 FileMatcher matcher = (FileMatcher) i.next(); 257 if (matcher.match(getName())) { 258 return true; 259 } 260 } 261 CVSGrab.getLog().warn("Unknown file type for " + getName() + ", assuming it's binary"); 262 return true; 263 } 264 265 private void doUpload() { 266 if (ThreadPool.getInstance() != null) { 267 ThreadPool.getInstance().doTask(new Runnable () { 268 public void run() { 269 upload(); 270 } 271 }); 272 } else { 273 upload(); 274 } 275 } 276 277 281 public String toString() { 282 return getDirectory().toString() + getName(); 283 } 284 285 protected void upload() { 286 RemoteRepository remoteRepository = _directory.getRemoteRepository(); 287 LocalRepository localRepository = remoteRepository.getLocalRepository(); 288 try { 289 File localDir = localRepository.getLocalDir(_directory); 291 localDir.mkdirs(); 292 File destFile = new File (localDir, _name); 293 String url = remoteRepository.getDownloadUrl(this); 294 295 WebBrowser.getInstance().loadFile(url, destFile); 297 _lastModified = new Date (); 298 299 localRepository.updateFileVersion(this); 300 301 } catch (Exception ex) { 302 localRepository.unregisterFile(this); 303 _directory.unregisterRemoteFile(this); 304 CVSGrab.getLog().error("IO Error: " + ex); 305 ex.printStackTrace(); 306 } 307 } 308 309 private static final String [] loadFile(String name) throws IOException { 310 BufferedReader data = new BufferedReader (new FileReader (name)); 311 List lines = new ArrayList (); 312 String s; 313 while ((s = data.readLine()) != null) { 314 lines.add(s); 315 } 316 return (String [])lines.toArray(new String [lines.size()]); 317 } 318 319 private static class FileMatcher { 320 private String pattern; 321 322 326 public FileMatcher(String pattern) { 327 super(); 328 this.pattern = pattern; 329 } 330 331 public boolean match(String fileName) { 332 if (pattern.startsWith("*")) { 333 return fileName.endsWith(pattern.substring(1)); 334 } else { 335 return pattern.equalsIgnoreCase(fileName); 336 } 337 } 338 } 339 340 } 341 | Popular Tags |