/** * Fail if the copied content is different from the one specified in the metadata. This should be true in most of the * cases. Only removing a module does not really match this, since we are creating a removed-module rather than * removing the contents. * * @param context the task context * @return */ protected boolean failOnContentMismatch(PatchingTaskContext context) { return context.getCurrentMode() != PatchingTaskContext.Mode.UNDO; }
@Override public boolean isSatisfied(PatchingTaskContext ctx) throws PatchingException { return ctx.getTargetFile(contentItem).exists(); }
static PatchingTask createMiscTask(final PatchingTaskDescription description, final MiscContentItem item, final PatchingTaskContext context) { // Create the task final File target = context.getTargetFile(item); final File backup = context.getBackupFile(item); final ModificationType type = description.getModificationType(); switch (type) { case ADD: case MODIFY: return new FileUpdateTask(description, target, backup); case REMOVE: return new FileRemoveTask(description, target, backup); default: throw new IllegalStateException(); } } }
@Override byte[] backup(PatchingTaskContext context) throws IOException { final File[] repoRoots = context.getTargetModulePath(); final String moduleName = contentItem.getName(); final String slot = contentItem.getSlot(); for(final File path : repoRoots) { // Find the first module and calculate the hash final File modulePath = PatchContentLoader.getModulePath(path, moduleName, slot); final File moduleXml = new File(modulePath, MODULE_XML); if(moduleXml.exists()) { PatchLogger.ROOT_LOGGER.debugf("found in path (%s)", moduleXml.getAbsolutePath()); context.invalidateRoot(modulePath); return HashUtils.hashFile(modulePath); } } return notFound(contentItem); }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { if (context.getCurrentMode() == PatchingTaskContext.Mode.ROLLBACK) { return getContentItem().getContentHash(); } // Copy the new bundle resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); final File[] moduleResources = sourceDir.listFiles(); if(! targetDir.mkdirs() && ! targetDir.exists()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } if(moduleResources == null || moduleResources.length == 0) { return NO_CONTENT; } for(final File file : moduleResources) { final File target = new File(targetDir, file.getName()); IoUtils.copy(file, target); } return contentItem.getContentHash(); }
@Override byte[] backup(PatchingTaskContext context) throws IOException { // Check the bundle dir hash final File[] repoRoots = context.getTargetBundlePath(); final String bundleName = contentItem.getName(); final String slot = contentItem.getSlot(); for(final File path : repoRoots) { // Check the bundle path final File bundlePath = PatchContentLoader.getModulePath(path, bundleName, slot); if(bundlePath.exists()) { PatchLogger.ROOT_LOGGER.debugf("found in path (%s)", bundlePath.getAbsolutePath()); // Bundles don't contain a modules.xml final File[] children = bundlePath.listFiles(); if(children == null || children.length == 0) { return NO_CONTENT; } context.invalidateRoot(bundlePath); return HashUtils.hashFile(bundlePath); } } return NO_CONTENT; }
@Override public void execute(final PatchingTaskContext context) throws IOException { if (ignoreApply) { return; } final PatchContentLoader contentLoader = description.getLoader(); final boolean skip = skipExecution | context.isExcluded(contentItem); final byte[] contentHash; if(skip) { contentHash = backupHash; // Reuse the backup hash } else { contentHash = apply(context, contentLoader); // Copy the content } // Add the rollback action final ContentModification original = getOriginalModification(contentHash, backupHash); final ContentModification rollbackAction = createRollbackEntry(original, contentHash, backupHash); context.recordChange(original, rollbackAction); // Fail after adding the undo action if (! Arrays.equals(contentHash, contentItem.getContentHash()) && failOnContentMismatch(context)) { throw PatchLogger.ROOT_LOGGER.wrongCopiedContent(contentItem); } }
@Override public void execute(PatchingTaskContext context) throws IOException { // delete the file or directory recursively boolean ok = IoUtils.recursiveDelete(target); for(ContentModification mod : rollback) { // Add the rollback (add actions) // We skip the change - misc files are reused in the processed patch context.recordChange(null, mod); } if(! ok) { throw PatchLogger.ROOT_LOGGER.failedToDelete(target.getAbsolutePath()); } }
static PatchingTask createMiscTask(final PatchingTaskDescription description, final MiscContentItem item, final PatchingTaskContext context) { // Create the task final File target = context.getTargetFile(item); final File backup = context.getBackupFile(item); final ModificationType type = description.getModificationType(); switch (type) { case ADD: case MODIFY: return new FileUpdateTask(description, target, backup); case REMOVE: return new FileRemoveTask(description, target, backup); default: throw new IllegalStateException(); } } }
@Override byte[] backup(PatchingTaskContext context) throws IOException { final File[] repoRoots = context.getTargetModulePath(); final String moduleName = contentItem.getName(); final String slot = contentItem.getSlot(); for(final File path : repoRoots) { // Find the first module and calculate the hash final File modulePath = PatchContentLoader.getModulePath(path, moduleName, slot); final File moduleXml = new File(modulePath, MODULE_XML); if(moduleXml.exists()) { PatchLogger.ROOT_LOGGER.debugf("found in path (%s)", moduleXml.getAbsolutePath()); context.invalidateRoot(modulePath); return HashUtils.hashFile(modulePath); } } return notFound(contentItem); }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { if (context.getCurrentMode() == PatchingTaskContext.Mode.ROLLBACK) { return getContentItem().getContentHash(); } // Copy the new bundle resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); final File[] moduleResources = sourceDir.listFiles(); if(! targetDir.mkdirs() && ! targetDir.exists()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } if(moduleResources == null || moduleResources.length == 0) { return NO_CONTENT; } for(final File file : moduleResources) { final File target = new File(targetDir, file.getName()); IoUtils.copy(file, target); } return contentItem.getContentHash(); }
@Override byte[] backup(PatchingTaskContext context) throws IOException { // Check the bundle dir hash final File[] repoRoots = context.getTargetBundlePath(); final String bundleName = contentItem.getName(); final String slot = contentItem.getSlot(); for(final File path : repoRoots) { // Check the bundle path final File bundlePath = PatchContentLoader.getModulePath(path, bundleName, slot); if(bundlePath.exists()) { PatchLogger.ROOT_LOGGER.debugf("found in path (%s)", bundlePath.getAbsolutePath()); // Bundles don't contain a modules.xml final File[] children = bundlePath.listFiles(); if(children == null || children.length == 0) { return NO_CONTENT; } context.invalidateRoot(bundlePath); return HashUtils.hashFile(bundlePath); } } return NO_CONTENT; }
@Override public void execute(final PatchingTaskContext context) throws IOException { if (ignoreApply) { return; } final PatchContentLoader contentLoader = description.getLoader(); final boolean skip = skipExecution | context.isExcluded(contentItem); final byte[] contentHash; if(skip) { contentHash = backupHash; // Reuse the backup hash } else { contentHash = apply(context, contentLoader); // Copy the content } // Add the rollback action final ContentModification original = getOriginalModification(contentHash, backupHash); final ContentModification rollbackAction = createRollbackEntry(original, contentHash, backupHash); context.recordChange(original, rollbackAction); // Fail after adding the undo action if (! Arrays.equals(contentHash, contentItem.getContentHash()) && failOnContentMismatch(context)) { throw PatchLogger.ROOT_LOGGER.wrongCopiedContent(contentItem); } }
@Override public void execute(PatchingTaskContext context) throws IOException { // delete the file or directory recursively boolean ok = IoUtils.recursiveDelete(target); for(ContentModification mod : rollback) { // Add the rollback (add actions) // We skip the change - misc files are reused in the processed patch context.recordChange(null, mod); } if(! ok) { throw PatchLogger.ROOT_LOGGER.failedToDelete(target.getAbsolutePath()); } }
@Override public boolean isSatisfied(PatchingTaskContext ctx) throws PatchingException { return ctx.getTargetFile(contentItem).exists(); }
/** * Fail if the copied content is different from the one specified in the metadata. This should be true in most of the * cases. Only removing a module does not really match this, since we are creating a removed-module rather than * removing the contents. * * @param context the task context * @return */ protected boolean failOnContentMismatch(PatchingTaskContext context) { return context.getCurrentMode() != PatchingTaskContext.Mode.UNDO; }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { final File targetDir = context.getTargetFile(contentItem); if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final File moduleXml = new File(targetDir, MODULE_XML); try (final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem))){ return copy(is, moduleXml); } }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { final File targetDir = context.getTargetFile(contentItem); if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final File moduleXml = new File(targetDir, MODULE_XML); try (final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem))){ return copy(is, moduleXml); } }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { // Copy the new module resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); if(sourceDir.exists()) { // Recursively copy module contents (incl. native libs) IoUtils.copyFile(sourceDir, targetDir); } else { // ADD an absent module // this situation happens when merging ADD and REMOVE modifications // which results in an ADD of an absent module if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final Path moduleXml = targetDir.toPath().resolve(MODULE_XML); final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem)); Files.copy(is, moduleXml, StandardCopyOption.REPLACE_EXISTING); } // return contentItem.getContentHash(); return HashUtils.hashFile(targetDir); }
@Override byte[] apply(PatchingTaskContext context, PatchContentLoader loader) throws IOException { // Copy the new module resources to the patching directory final File targetDir = context.getTargetFile(contentItem); final File sourceDir = loader.getFile(contentItem); if(sourceDir.exists()) { // Recursively copy module contents (incl. native libs) IoUtils.copyFile(sourceDir, targetDir); } else { // ADD an absent module // this situation happens when merging ADD and REMOVE modifications // which results in an ADD of an absent module if(!targetDir.exists() && ! targetDir.mkdirs()) { throw PatchLogger.ROOT_LOGGER.cannotCreateDirectory(targetDir.getAbsolutePath()); } final Path moduleXml = targetDir.toPath().resolve(MODULE_XML); final ByteArrayInputStream is = new ByteArrayInputStream(PatchUtils.getAbsentModuleContent(contentItem)); Files.copy(is, moduleXml, StandardCopyOption.REPLACE_EXISTING); } // return contentItem.getContentHash(); return HashUtils.hashFile(targetDir); }