/*
|
* CDDL HEADER START
|
*
|
* The contents of this file are subject to the terms of the
|
* Common Development and Distribution License, Version 1.0 only
|
* (the "License"). You may not use this file except in compliance
|
* with the License.
|
*
|
* You can obtain a copy of the license at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
|
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
|
* See the License for the specific language governing permissions
|
* and limitations under the License.
|
*
|
* When distributing Covered Code, include this CDDL HEADER in each
|
* file and include the License file at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
|
* add the following below this CDDL HEADER, with the fields enclosed
|
* by brackets "[]" replaced with your own identifying information:
|
* Portions Copyright [yyyy] [name of copyright owner]
|
*
|
* CDDL HEADER END
|
*
|
*
|
* Copyright 2008 Sun Microsystems, Inc.
|
*/
|
|
package org.opends.quicksetup.upgrader;
|
|
import org.opends.messages.Message;
|
import static org.opends.messages.QuickSetupMessages.*;
|
|
import org.opends.quicksetup.*;
|
import org.opends.quicksetup.event.ProgressUpdateListener;
|
|
import org.opends.quicksetup.util.Utils;
|
import org.opends.quicksetup.util.ZipExtractor;
|
import org.opends.quicksetup.util.FileManager;
|
import org.opends.quicksetup.util.ProgressMessageFormatter;
|
|
import java.io.File;
|
import java.util.logging.Level;
|
import java.util.logging.Logger;
|
|
/**
|
* BuildExtractor runs prior to an upgrade or reversion operation. Its main
|
* purpose is to unzip an OpenDS installation package (.zip file) from a user
|
* specified location into the current builds staging directory. However,
|
* this program is also responsible for determining whether or not this
|
* invocation is intended to be an upgrade or reversion operation. If this
|
* is a reversion, this program just exists with the appropriate exit code
|
* indicating reversion. If this is an upgrade this program unzips the
|
* installation package.
|
*
|
* This Java program handles unzipping files so that we don't need to rely on
|
* the operating system's tools for managing zip files.
|
*
|
* This tool is a stand-alone program since it is run in preparation for a
|
* off line upgrade and runs using the current program's jars rather than
|
* the new build's jars as is manditory for the Upgrader itself. Since this
|
* tool itself is run using the old bits prior to upgrade and the upgrade
|
* itself is dependent upon this tool, it should be kept simple and stable
|
* to insure that the upgrade will work.
|
*/
|
public class BuildExtractor extends UpgradeLauncher implements CliApplication {
|
|
static private final Logger LOG =
|
Logger.getLogger(BuildExtractor.class.getName());
|
|
/** Return code indicating that this invocation is an upgrade. */
|
private static final int RC_CONTINUE_WITH_UPGRADE = 99;
|
|
/** Return code indicating that this invocation is a reversion. */
|
private static final int RC_CONTINUE_WITH_REVERSION = 98;
|
|
/**
|
* Creates and run a BuildExtractor using command line arguments.
|
* @param args String[] command line arguments
|
*/
|
public static void main(String[] args) {
|
try {
|
QuickSetupLog.initLogFileHandler(
|
File.createTempFile(
|
UpgradeLauncher.LOG_FILE_PREFIX + "ext-",
|
QuickSetupLog.LOG_FILE_SUFFIX));
|
} catch (Throwable t) {
|
System.err.println(
|
INFO_ERROR_INITIALIZING_LOG.get());
|
t.printStackTrace();
|
}
|
new BuildExtractor(args).launch();
|
}
|
|
private UpgradeUserData userData;
|
|
private boolean finished;
|
|
private ApplicationException error;
|
|
private ReturnCode rc;
|
|
private BuildExtractor(String[] args) {
|
super(args);
|
}
|
|
/**
|
* Executes this build extractor. First and attempt is made to extract the
|
* build file name from the command line arguments. If no such file has been
|
* specified this program simply exits with a return code of 0. If such a
|
* file has been specified this program performs a certain amount of
|
* verification on the file. If the verification fails this program prints
|
* a message and exits with with a return code of 1 meaning that the upgrade
|
* process should end. If verification succeeeds this program unzips its
|
* contents into the current build's staging are and exits with return code 0.
|
*/
|
public void run() {
|
UpgradeUserData uud = (UpgradeUserData)getUserData();
|
if (UpgradeUserData.Operation.REVERSION.equals(uud.getOperation())) {
|
rc = new ReturnCode(RC_CONTINUE_WITH_REVERSION);
|
} else {
|
try {
|
File buildFile = uud.getInstallPackage();
|
if (buildFile != null) {
|
LOG.log(Level.INFO, "Expanding zip file " + buildFile.getPath());
|
File stageDirectory = initStageDirectory();
|
ZipExtractor extractor = new ZipExtractor(buildFile);
|
extractor.extract(stageDirectory);
|
LOG.log(Level.INFO, "Extraction finished");
|
Installation installation = new Installation(stageDirectory);
|
if (!installation.isValid()) {
|
LOG.log(Level.INFO, "Extraction produed an invalid OpenDS" +
|
"installation: " + installation.getInvalidityReason());
|
Message invalidMsg = INFO_BUILD_EXTRACTOR_FILE_INVALID.get(
|
Utils.getPath(buildFile),
|
installation.getInvalidityReason());
|
error = new ApplicationException(
|
ReturnCode.APPLICATION_ERROR,
|
invalidMsg, null);
|
System.err.println(invalidMsg);
|
}
|
rc = new ReturnCode(RC_CONTINUE_WITH_UPGRADE);
|
} else {
|
// This should never happen assuming createUserData did the
|
// right thing
|
LOG.log(Level.INFO, "Build extractor failed to " +
|
"specify valid installation zip file");
|
throw new IllegalStateException("Build extractor failed to " +
|
"specify valid installation zip file");
|
}
|
} catch (Throwable t) {
|
LOG.log(Level.INFO, "Unexpected error extracting build", t);
|
String reason = t.getLocalizedMessage();
|
error = new ApplicationException(
|
ReturnCode.APPLICATION_ERROR,
|
INFO_BUILD_EXTRACTOR_ERROR.get(reason), t);
|
System.err.println(reason);
|
} finally {
|
finished = true;
|
}
|
}
|
}
|
|
private File initStageDirectory() throws ApplicationException {
|
File stageDir;
|
Installation installation = new Installation(getInstallationPath());
|
stageDir = installation.getTemporaryUpgradeDirectory();
|
if (stageDir.exists()) {
|
FileManager fm = new FileManager();
|
fm.deleteRecursively(stageDir);
|
}
|
if (!stageDir.mkdirs()) {
|
Message msg = INFO_ERROR_FAILED_TO_CREATE_STAGE_DIRECTORY.get(
|
Utils.getPath(stageDir));
|
throw ApplicationException.createFileSystemException(msg, null);
|
}
|
LOG.log(Level.INFO, "stage directory " + stageDir.getPath());
|
return stageDir;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
protected CliApplication createCliApplication() {
|
return this;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public String getInstallationPath() {
|
return Utils.getInstallPathFromClasspath();
|
}
|
|
/**
|
* {@inheritDoc}
|
* @param launcher
|
*/
|
public UserData createUserData(Launcher launcher)
|
throws UserDataException
|
{
|
BuildExtractorCliHelper helper =
|
new BuildExtractorCliHelper((UpgradeLauncher)launcher);
|
UpgradeUserData uud = helper.createUserData(args);
|
|
if (uud != null)
|
{
|
// Build Extractor is always quiet
|
uud.setQuiet(true);
|
|
// The user may have indicated the operation via interactivity
|
if (UpgradeUserData.Operation.UPGRADE.equals(uud.getOperation())) {
|
isUpgrade = true;
|
} else if (UpgradeUserData.Operation.REVERSION.equals(
|
uud.getOperation())) {
|
isReversion = true;
|
}
|
}
|
|
return uud;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public UserData getUserData() {
|
return userData;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public void setUserData(UserData userData) {
|
if (userData instanceof UpgradeUserData) {
|
this.userData = (UpgradeUserData)userData;
|
}
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public void setProgressMessageFormatter(ProgressMessageFormatter formatter) {
|
// ignore
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public boolean isFinished() {
|
return finished;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public ApplicationException getRunError() {
|
return error;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public ReturnCode getReturnCode() {
|
return rc;
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public void addProgressUpdateListener(ProgressUpdateListener l) {
|
// ignored; no progress messages
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public void removeProgressUpdateListener(ProgressUpdateListener l) {
|
// ignored; no progress messages
|
}
|
|
/**
|
* {@inheritDoc}
|
*/
|
public void notifyListeners(Integer ratio, Message currentPhaseSummary,
|
Message newLogDetail) {
|
// ignored; no progress messages
|
}
|
|
}
|