/* * (C) Copyright 2011-2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Julien Carsique */ package org.nuxeo.connect.update.task.standalone.commands; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.Map; import org.apache.commons.io.FileUtils; import org.nuxeo.connect.update.PackageException; import org.nuxeo.connect.update.ValidationStatus; import org.nuxeo.connect.update.task.Command; import org.nuxeo.connect.update.task.Task; import org.nuxeo.connect.update.task.standalone.UninstallTask; import org.nuxeo.connect.update.util.IOUtils; import org.nuxeo.connect.update.xml.XmlWriter; import org.w3c.dom.Element; /** * Rollback command for {@link Append} and {@link Copy} (with {@link Copy#append}=true) commands. * * @since 5.5 */ public class UnAppend extends AbstractCommand { public static final String ID = "unappend"; private static final String newLine = System.getProperty("line.separator"); private File contentToRemove; private File fromFile; public UnAppend() { this(ID); } protected UnAppend(String id) { super(id); } /** * @param contentToRemove File which content must be removed. * @param fromFile Destination file from which content is removed. */ public UnAppend(File contentToRemove, File fromFile) { this(ID); this.contentToRemove = contentToRemove; this.fromFile = fromFile; } @Override public void writeTo(XmlWriter writer) { writer.start(ID); if (contentToRemove != null) { writer.attr("contentToRemove", contentToRemove.getAbsolutePath()); } if (fromFile != null) { writer.attr("fromFile", fromFile.getAbsolutePath()); } writer.end(); } @Override protected Command doRun(Task task, Map<String, String> prefs) throws PackageException { BufferedReader brToRemove = null, brFromFile = null; File bak; StringBuilder linesToKeep = new StringBuilder(); StringBuilder linesToRemove = new StringBuilder(); try { try { brToRemove = new BufferedReader(new FileReader(contentToRemove)); String lineToRemove = brToRemove.readLine(); brFromFile = new BufferedReader(new FileReader(fromFile)); String lineToCheck; boolean found = false; while ((lineToCheck = brFromFile.readLine()) != null) { if (lineToCheck.equals(lineToRemove)) { // Maybe the line to remove, but let's check the next // lines found = true; linesToRemove.append(lineToCheck).append(newLine); lineToRemove = brToRemove.readLine(); } else { if (lineToRemove != null && found) { // Previously found lines must finally be kept found = false; linesToKeep.append(linesToRemove.toString()); linesToRemove = new StringBuilder(); org.apache.commons.io.IOUtils.closeQuietly(brToRemove); brToRemove = new BufferedReader(new FileReader(contentToRemove)); } linesToKeep.append(lineToCheck).append(newLine); } } if (lineToRemove != null) { throw new PackageException("All lines to remove were not found."); } } finally { org.apache.commons.io.IOUtils.closeQuietly(brToRemove); org.apache.commons.io.IOUtils.closeQuietly(brFromFile); } if (task instanceof UninstallTask) { bak = null; } else { bak = IOUtils.backup(task.getPackage(), contentToRemove); } FileUtils.writeStringToFile(fromFile, linesToKeep.toString()); return new Append(bak, fromFile); } catch (PackageException e) { throw e; } catch (IOException e) { throw new PackageException(e); } } @Override protected void doValidate(Task task, ValidationStatus status) throws PackageException { if (contentToRemove == null || fromFile == null) { status.addError("Cannot execute command in installer." + " Invalid unappend syntax: contentToRemove or fromFile was not specified."); } } @Override public void readFrom(Element element) throws PackageException { String v = element.getAttribute("contentToRemove"); if (v.length() > 0) { contentToRemove = new File(v); } v = element.getAttribute("fromFile"); if (v.length() > 0) { fromFile = new File(v); } } }