001/*
002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu, jcarsique
016 */
017package org.nuxeo.connect.update.task.update;
018
019import java.io.File;
020import java.util.Map;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024import org.nuxeo.connect.update.PackageException;
025import org.nuxeo.connect.update.ValidationStatus;
026import org.nuxeo.connect.update.task.Command;
027import org.nuxeo.connect.update.task.Task;
028import org.nuxeo.connect.update.task.standalone.AbstractTask;
029import org.nuxeo.connect.update.task.standalone.commands.AbstractCommand;
030import org.nuxeo.connect.update.task.standalone.commands.UndeployPlaceholder;
031import org.nuxeo.connect.update.xml.XmlWriter;
032import org.w3c.dom.Element;
033
034/**
035 * @since 5.5
036 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
037 */
038public class Rollback extends AbstractCommand {
039
040    protected static final Log log = LogFactory.getLog(Rollback.class);
041
042    public static String ID = "rollback";
043
044    protected String pkgId;
045
046    protected String key;
047
048    protected String version;
049
050    protected boolean deleteOnExit;
051
052    public Rollback() {
053        super(ID);
054    }
055
056    public Rollback(RollbackOptions opt) {
057        super(ID);
058        this.pkgId = opt.pkgId;
059        this.key = opt.key;
060        this.version = opt.version;
061        this.deleteOnExit = opt.deleteOnExit;
062    }
063
064    @Override
065    public void writeTo(XmlWriter writer) {
066        writer.start(ID);
067        if (key != null) {
068            writer.attr("key", key);
069        }
070        if (pkgId != null) {
071            writer.attr("pkgId", pkgId);
072        }
073        if (version != null) {
074            writer.attr("version", version);
075        }
076        if (deleteOnExit) {
077            writer.attr("deleteOnExit", "true");
078        }
079        writer.end();
080    }
081
082    @Override
083    public void readFrom(Element element) throws PackageException {
084        String v = element.getAttribute("version");
085        if (v.length() > 0) {
086            version = v;
087        }
088        v = element.getAttribute("pkgId");
089        if (v.length() > 0) {
090            pkgId = v;
091        }
092        v = element.getAttribute("key");
093        if (v.length() > 0) {
094            key = v;
095        }
096        v = element.getAttribute("deleteOnExit");
097        if (v.length() > 0) {
098            deleteOnExit = Boolean.parseBoolean(v);
099        }
100    }
101
102    @Override
103    protected void doValidate(Task task, ValidationStatus status) throws PackageException {
104        // allow null version for Studio snapshot jar
105        if (key == null) {
106            status.addError("Cannot execute command in installer." + " Invalid rollback syntax: key was not specified.");
107        }
108    }
109
110    @Override
111    protected Command doRun(Task task, Map<String, String> prefs) throws PackageException {
112        UpdateManager mgr = ((AbstractTask) task).getUpdateManager();
113        RollbackOptions opt = new RollbackOptions(task.getPackage().getId(), key, version);
114        File rollbackTarget = mgr.getRollbackTarget(opt);
115        if (rollbackTarget != null) {
116            Command undeploy = getUndeployCommand(rollbackTarget);
117            if (undeploy != null) {
118                undeploy.run(task, prefs);
119            }
120        }
121        opt.setDeleteOnExit(deleteOnExit);
122        mgr.rollback(opt);
123        return null;
124    }
125
126    public RollbackOptions getRollbackOptions() {
127        return new RollbackOptions(pkgId, key, version);
128    }
129
130    /**
131     * Method to be overridden by subclasses to provide a undeploy command for hot reload
132     *
133     * @since 5.6
134     */
135    protected Command getUndeployCommand(File targetFile) {
136        return new UndeployPlaceholder(targetFile);
137    }
138
139}