@Override protected void doValidate(Task task, ValidationStatus status) throws PackageException { if (file == null || tofile == null) { status.addError( "Cannot execute command in installer." + " Invalid copy syntax: file, dir, tofile or todir was not specified."); } if (tofile.isFile() && !overwrite && !append) { if (removeOnExit) { // a plugin is still there due to a previous action that needs a // restart status.addError( "A restart is needed to perform this operation: cleaning " + tofile.getName()); } else { status.addError("Cannot overwrite existing file: " + tofile.getName()); } } if (md5 != null) { try { if (tofile.isFile() && !md5.equals(IOUtils.createMd5(tofile))) { status.addError("MD5 check failed. File: " + tofile + " has changed since its backup"); } } catch (Exception e) { throw new PackageException(e); } } }
/** * @param doOverwrite * @since 5.5 */ protected Command doCopy( Task task, Map<String, String> prefs, File fileToCopy, File dst, boolean doOverwrite) throws PackageException { String dstmd5; File bak = null; CompositeCommand rollbackCommand = new CompositeCommand(); if (fileToCopy.isDirectory()) { if (fileToCopy != file) { dst = new File(dst, fileToCopy.getName()); } dst.mkdirs(); for (File childFile : fileToCopy.listFiles()) { rollbackCommand.addCommand(doCopy(task, prefs, childFile, dst, doOverwrite)); } return rollbackCommand; } if (dst.isDirectory()) { dst = new File(dst, fileToCopy.getName()); } try { FileMatcher filenameMatcher = FileMatcher.getMatcher("{n:.*-}[0-9]+.*\\.jar"); if (filenameMatcher.match(fileToCopy.getName()) && (overwriteIfNewerVersion || upgradeOnly)) { // Compare source and destination versions set in filename FileVersion fileToCopyVersion, dstVersion = null; String filenameWithoutVersion = filenameMatcher.getValue(); FileMatcher versionMatcher = FileMatcher.getMatcher(filenameWithoutVersion + "{v:[0-9]+.*}\\.jar"); // Get new file version if (versionMatcher.match(fileToCopy.getName())) { fileToCopyVersion = new FileVersion(versionMatcher.getValue()); // Get original file name and version File dir = dst.getParentFile(); File[] list = dir.listFiles(); if (list != null) { for (File f : list) { if (versionMatcher.match(f.getName())) { dst = f; dstVersion = new FileVersion(versionMatcher.getValue()); break; } } } if (dstVersion == null) { if (upgradeOnly) { return null; } } else if (fileToCopyVersion.greaterThan(dstVersion)) { // backup dst and generate rollback command File oldDst = dst; dst = new File(dst.getParentFile(), fileToCopy.getName()); File backup = IOUtils.backup(task.getPackage(), oldDst); rollbackCommand.addCommand(new Copy(backup, oldDst, null, false)); // Delete old dst as its name differs from new version oldDst.delete(); } else if (fileToCopyVersion.isSnapshot() && fileToCopyVersion.equals(dstVersion)) { doOverwrite = true; } else if (!doOverwrite) { log.info( "Ignore " + fileToCopy + " because not newer than " + dstVersion + " and 'overwrite' is set to false."); return null; } } } if (dst.exists()) { // backup the destination file if exist. if (!doOverwrite && !append) { // force a rollback throw new PackageException( "Copy command has overwrite flag on false but destination file exists: " + dst); } if (task instanceof UninstallTask) { // no backup for uninstall task } else if (append) { bak = IOUtils.backup(task.getPackage(), fileToCopy); } else { bak = IOUtils.backup(task.getPackage(), dst); } } else { // target file doesn't exists - it will be created dst.getParentFile().mkdirs(); } // copy the file - use getContentToCopy to allow parameterization // for subclasses String content = getContentToCopy(fileToCopy, prefs); if (content != null) { if (append && dst.exists()) { RandomAccessFile rfile = new RandomAccessFile(dst, "r"); try { rfile.seek(dst.length()); if (!"".equals(rfile.readLine())) { content = System.getProperty("line.separator") + content; } } catch (IOException e) { log.error(e); } finally { rfile.close(); } } FileUtils.writeFile(dst, content, append); } else { File tmp = new File(dst.getPath() + ".tmp"); FileUtils.copy(fileToCopy, tmp); if (!tmp.renameTo(dst)) { tmp.delete(); FileUtils.copy(fileToCopy, dst); } } // check whether the copied or restored file was the launcher if (dst.getName().equals(LAUNCHER_JAR) || fileToCopy.getName().equals(LAUNCHER_JAR)) { Environment env = Environment.getDefault(); env.setProperty(LAUNCHER_CHANGED_PROPERTY, "true"); } // get the md5 of the copied file. dstmd5 = IOUtils.createMd5(dst); } catch (Exception e) { throw new PackageException("Failed to copy " + fileToCopy, e); } if (bak == null) { // no file was replaced rollbackCommand.addCommand(new Delete(dst, dstmd5, removeOnExit)); } else if (append) { rollbackCommand.addCommand(new UnAppend(bak, dst)); } else { rollbackCommand.addCommand(new Copy(bak, dst, dstmd5, true)); } return rollbackCommand; }