1 16 package org.apache.commons.vfs.tasks; 17 18 import org.apache.commons.vfs.FileName; 19 import org.apache.commons.vfs.FileObject; 20 import org.apache.commons.vfs.FileType; 21 import org.apache.commons.vfs.NameScope; 22 import org.apache.commons.vfs.Selectors; 23 import org.apache.commons.vfs.util.Messages; 24 import org.apache.tools.ant.BuildException; 25 import org.apache.tools.ant.Project; 26 27 import java.util.ArrayList ; 28 import java.util.HashSet ; 29 import java.util.Set ; 30 import java.util.StringTokenizer ; 31 32 52 public abstract class AbstractSyncTask 53 extends VfsTask 54 { 55 private final ArrayList srcFiles = new ArrayList (); 56 private String destFileUrl; 57 private String destDirUrl; 58 private String srcDirUrl; 59 private boolean srcDirIsBase; 60 private String filesList; 61 62 65 public void setDestFile(final String destFile) 66 { 67 this.destFileUrl = destFile; 68 } 69 70 73 public void setDestDir(final String destDir) 74 { 75 this.destDirUrl = destDir; 76 } 77 78 81 public void setSrc(final String srcFile) 82 { 83 final SourceInfo src = new SourceInfo(); 84 src.setFile(srcFile); 85 addConfiguredSrc(src); 86 } 87 88 91 public void setSrcDir(final String srcDir) 92 { 93 this.srcDirUrl = srcDir; 94 } 95 96 99 public void setSrcDirIsBase(final boolean srcDirIsBase) 100 { 101 this.srcDirIsBase = srcDirIsBase; 102 } 103 104 107 public void setIncludes(final String filesList) 108 { 109 this.filesList = filesList; 110 } 111 112 115 public void addConfiguredSrc(final SourceInfo srcInfo) 116 throws BuildException 117 { 118 if (srcInfo.file == null) 119 { 120 final String message = Messages.getString("vfs.tasks/sync.no-source-file.error"); 121 throw new BuildException(message); 122 } 123 srcFiles.add(srcInfo); 124 } 125 126 129 public void execute() throws BuildException 130 { 131 if (destFileUrl == null && destDirUrl == null) 133 { 134 final String message = 135 Messages.getString("vfs.tasks/sync.no-destination.error"); 136 throw new BuildException(message); 137 } 138 139 if (destFileUrl != null && destDirUrl != null) 140 { 141 final String message = 142 Messages.getString("vfs.tasks/sync.too-many-destinations.error"); 143 throw new BuildException(message); 144 } 145 146 if (srcDirUrl != null && !srcDirUrl.equals(destDirUrl) && filesList != null && filesList.length() > 0) 148 { 149 if (!srcDirUrl.endsWith("/")) 150 { 151 srcDirUrl += "/"; 152 } 153 StringTokenizer tok = new StringTokenizer (filesList, ", \t\n\r\f", false); 154 while (tok.hasMoreTokens()) 155 { 156 String nextFile = tok.nextToken(); 157 158 if (nextFile.endsWith("/**")) 160 { 161 nextFile = nextFile.substring(0, nextFile.length() - 2); 162 } 163 164 final SourceInfo src = new SourceInfo(); 165 src.setFile(srcDirUrl + nextFile); 166 addConfiguredSrc(src); 167 } 168 } 169 170 if (srcFiles.size() == 0) 171 { 172 final String message = Messages.getString("vfs.tasks/sync.no-source-files.warn"); 173 log(message, Project.MSG_WARN); 174 return; 175 } 176 177 try 179 { 180 if (destFileUrl != null) 181 { 182 handleSingleFile(); 183 } 184 else 185 { 186 handleFiles(); 187 } 188 } 189 catch (final BuildException e) 190 { 191 throw e; 192 } 193 catch (final Exception e) 194 { 195 throw new BuildException(e.getMessage(), e); 196 } 197 } 198 199 202 private void handleFiles() throws Exception 203 { 204 final FileObject destFolder = resolveFile(destDirUrl); 206 destFolder.createFolder(); 207 208 FileName srcDirName = null; 210 if (srcDirUrl !=null ) 211 { 212 srcDirName = resolveFile(srcDirUrl).getName(); 213 } 214 final ArrayList srcs = new ArrayList (); 215 for (int i = 0; i < srcFiles.size(); i++) 216 { 217 final SourceInfo src = (SourceInfo) srcFiles.get(i); 219 final FileObject srcFile = resolveFile(src.file); 220 if (!srcFile.exists()) 221 { 222 final String message = 223 Messages.getString("vfs.tasks/sync.src-file-no-exist.warn", srcFile); 224 log(message, Project.MSG_WARN); 225 } 226 else 227 { 228 srcs.add(srcFile); 229 } 230 } 231 232 final Set destFiles = new HashSet (); 234 for (int i = 0; i < srcs.size(); i++) 235 { 236 final FileObject rootFile = (FileObject) srcs.get(i); 237 final FileName rootName = rootFile.getName(); 238 239 if (rootFile.getType() == FileType.FILE) 240 { 241 String relName = null; 243 if (srcDirName == null || !srcDirIsBase) 244 { 245 relName = rootName.getBaseName(); 246 } 247 else 248 { 249 relName = srcDirName.getRelativeName(rootName); 250 } 251 final FileObject destFile = destFolder.resolveFile(relName, NameScope.DESCENDENT); 252 253 handleFile(destFiles, rootFile, destFile); 255 } 256 else 257 { 258 final FileObject[] files = rootFile.findFiles(srcDirIsBase ? Selectors.SELECT_ALL : Selectors.SELECT_FILES); 261 262 for (int j = 0; j < files.length; j++) 263 { 264 final FileObject srcFile = files[j]; 265 266 String relName = null; 268 if (srcDirName == null || !srcDirIsBase) 269 { 270 relName = rootName.getRelativeName(srcFile.getName()); 271 } 272 else 273 { 274 relName = srcDirName.getRelativeName(srcFile.getName()); 275 } 276 277 final FileObject destFile = 278 destFolder.resolveFile(relName, NameScope.DESCENDENT); 279 280 handleFile(destFiles, srcFile, destFile); 282 } 283 } 284 } 285 286 if (detectMissingSourceFiles()) 288 { 289 final FileObject[] allDestFiles = destFolder.findFiles(Selectors.SELECT_FILES); 290 for (int i = 0; i < allDestFiles.length; i++) 291 { 292 final FileObject destFile = allDestFiles[i]; 293 if (!destFiles.contains(destFile)) 294 { 295 handleMissingSourceFile(destFile); 296 } 297 } 298 } 299 } 300 301 305 private void handleFile(final Set destFiles, 306 final FileObject srcFile, 307 final FileObject destFile) throws Exception 308 309 { 310 if (destFiles.contains(destFile)) 312 { 313 final String message = Messages.getString("vfs.tasks/sync.duplicate-source-files.warn", destFile); 314 log(message, Project.MSG_WARN); 315 } 316 else 317 { 318 destFiles.add(destFile); 319 } 320 321 handleFile(srcFile, destFile); 323 } 324 325 328 private void handleSingleFile() throws Exception 329 { 330 if (srcFiles.size() > 1) 333 { 334 final String message = 335 Messages.getString("vfs.tasks/sync.too-many-source-files.error"); 336 throw new BuildException(message); 337 } 338 final SourceInfo src = (SourceInfo) srcFiles.get(0); 339 final FileObject srcFile = resolveFile(src.file); 340 if (srcFile.getType() != FileType.FILE) 341 { 342 final String message = 343 Messages.getString("vfs.tasks/sync.source-not-file.error", srcFile); 344 throw new BuildException(message); 345 } 346 347 final FileObject destFile = resolveFile(destFileUrl); 349 350 handleFile(srcFile, destFile); 352 } 353 354 357 private void handleFile(final FileObject srcFile, 358 final FileObject destFile) 359 throws Exception 360 { 361 if (!destFile.exists() 362 || srcFile.getContent().getLastModifiedTime() > destFile.getContent().getLastModifiedTime()) 363 { 364 handleOutOfDateFile(srcFile, destFile); 366 } 367 else 368 { 369 handleUpToDateFile(srcFile, destFile); 371 } 372 } 373 374 379 protected void handleOutOfDateFile(final FileObject srcFile, 380 final FileObject destFile) 381 throws Exception 382 { 383 } 384 385 389 protected void handleUpToDateFile(final FileObject srcFile, 390 final FileObject destFile) 391 throws Exception 392 { 393 } 394 395 399 protected void handleMissingSourceFile(final FileObject destFile) 400 throws Exception 401 { 402 } 403 404 408 protected boolean detectMissingSourceFiles() 409 { 410 return false; 411 } 412 413 416 public static class SourceInfo 417 { 418 private String file; 419 420 public void setFile(final String file) 421 { 422 this.file = file; 423 } 424 } 425 426 } 427 | Popular Tags |