com.izforge.izpack.installer.multiunpacker.MultiVolumeUnpacker.java Source code

Java tutorial

Introduction

Here is the source code for com.izforge.izpack.installer.multiunpacker.MultiVolumeUnpacker.java

Source

/*
 * IzPack - Copyright 2001-2012 Julien Ponge, All Rights Reserved.
 *
 * http://izpack.org/
 * http://izpack.codehaus.org/
 *
 * Copyright 2007 Dennis Reil
 * Copyright 2012 Tim Anderson
 *
 * 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.
 */

package com.izforge.izpack.installer.multiunpacker;

import com.izforge.izpack.api.data.InstallData;
import com.izforge.izpack.api.data.Pack;
import com.izforge.izpack.api.data.PackFile;
import com.izforge.izpack.api.event.InstallerListener;
import com.izforge.izpack.api.event.ProgressListener;
import com.izforge.izpack.api.exception.InstallerException;
import com.izforge.izpack.api.exception.IzPackException;
import com.izforge.izpack.api.handler.Prompt;
import com.izforge.izpack.api.rules.RulesEngine;
import com.izforge.izpack.api.substitutor.VariableSubstitutor;
import com.izforge.izpack.core.io.FileSpanningInputStream;
import com.izforge.izpack.core.io.VolumeLocator;
import com.izforge.izpack.installer.data.UninstallData;
import com.izforge.izpack.installer.event.InstallerListeners;
import com.izforge.izpack.installer.unpacker.*;
import com.izforge.izpack.util.Housekeeper;
import com.izforge.izpack.util.PlatformModelMatcher;
import com.izforge.izpack.util.os.FileQueue;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.CodeSource;
import java.util.List;
import java.util.logging.Logger;

/**
 * Unpacker class for a multi volume installation.
 *
 * @author Dennis Reil, <izpack@reil-online.de>
 * @author Tim Anderson
 */
public class MultiVolumeUnpacker extends UnpackerBase {

    /**
     * The volume locator.
     */
    private final VolumeLocator locator;

    /**
     * The pack data volumes stream.
     */
    private FileSpanningInputStream volumes;

    /**
     * Volume meta-data resource name.
     */
    static final String VOLUMES_INFO = "volumes.info";

    /**
     * The logger.
     */
    private static final Logger logger = Logger.getLogger(MultiVolumeUnpacker.class.getName());

    /**
     * Constructs a <tt>MultiVolumeUnpacker</tt>.
     *
     * @param installData         the installation data
     * @param resources           the pack resources
     * @param rules               the rules engine
     * @param variableSubstitutor the variable substituter
     * @param uninstallData       the uninstallation data
     * @param queue               the queue
     * @param housekeeper         the housekeeper
     * @param listeners           the listeners
     * @param prompt              the prompt
     * @param locator             the multi-volume locator
     * @param matcher             the platform-model matcher
     */
    public MultiVolumeUnpacker(InstallData installData, PackResources resources, RulesEngine rules,
            VariableSubstitutor variableSubstitutor, UninstallData uninstallData, FileQueueFactory queue,
            Housekeeper housekeeper, InstallerListeners listeners, Prompt prompt, VolumeLocator locator,
            PlatformModelMatcher matcher) {
        super(installData, resources, rules, variableSubstitutor, uninstallData, queue, housekeeper, listeners,
                prompt, matcher);
        this.locator = locator;
    }

    /**
     * Invoked prior to unpacking.
     * <p/>
     * This notifies the {@link ProgressListener}, and any registered {@link InstallerListener listeners}.
     *
     * @param packs the packs to unpack
     * @throws IzPackException for any error
     */
    @Override
    protected void preUnpack(List<Pack> packs) {
        super.preUnpack(packs);

        InputStream in = null;
        ObjectInputStream objectIn = null;
        try {
            // get volume metadata
            in = getResources().getInputStream(VOLUMES_INFO);
            objectIn = new ObjectInputStream(in);
            int volumeCount = objectIn.readInt();
            String volumeName = objectIn.readUTF();
            logger.fine("Reading from " + volumeCount + " volumes with basename " + volumeName + " ");

            String mediaPath = getInstallData().getMediaPath();
            if ((mediaPath == null) || (mediaPath.length() == 0)) {
                mediaPath = getDefaultMediaPath();
            }
            logger.fine("Using mediaDirectory = " + mediaPath);
            File volume = new File(mediaPath, volumeName);
            if (!volume.exists()) {
                volume = locator.getVolume(volume.getAbsolutePath(), false);
            }
            volumes = new FileSpanningInputStream(volume, volumeCount);
            volumes.setLocator(locator);
        } catch (IOException exception) {
            throw new InstallerException(exception);
        } finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(objectIn);
        }
    }

    /**
     * Creates an unpacker to unpack a pack file.
     *
     * @param file        the pack file to unpack
     * @param pack        the parent pack
     * @param queue       the file queue. May be {@code null}
     * @param cancellable determines if the unpacker should be cancelled
     * @return the unpacker
     * @throws InstallerException for any installer error
     */
    @Override
    protected FileUnpacker createFileUnpacker(PackFile file, Pack pack, FileQueue queue, Cancellable cancellable)
            throws InstallerException {
        FileUnpacker unpacker;
        if (pack.isLoose()) {
            unpacker = new LooseFileUnpacker(cancellable, queue, getPrompt());
        } else {
            unpacker = new MultiVolumeFileUnpacker(volumes, cancellable, queue);
        }
        return unpacker;
    }

    @Override
    protected void skip(PackFile file, Pack pack, InputStream packInputStream) throws IOException {
        // this operation is a no-op for MultiVolumeUnpacker as the file is not in the pack stream
    }

    @Override
    protected void skip(InputStream stream, long bytes) throws IOException {
        // this operation is a no-op for MultiVolumeUnpacker as the file is not in the pack stream
    }

    @Override
    protected void cleanup() {
        super.cleanup();
        IOUtils.closeQuietly(volumes);
    }

    /**
     * Tries to return a sensible default media path for multi-volume installations.
     * <p/>
     * This returns:
     * <ul>
     * <li>the directory the installer is located in; or </li>
     * <li>the user directory, if the installer location can't be determined</li>
     * </ul>
     *
     * @return the default media path. May be <tt>null</tt>
     */
    private String getDefaultMediaPath() {
        String result = null;
        try {
            CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
            if (codeSource != null) {
                URI uri = codeSource.getLocation().toURI();
                if ("file".equals(uri.getScheme())) {
                    File dir = new File(uri.getSchemeSpecificPart()).getAbsoluteFile();
                    if (dir.getName().endsWith(".jar")) {
                        dir = dir.getParentFile();
                    }
                    result = dir.getPath();
                }
            }
        } catch (URISyntaxException exception) {
            // ignore
        }
        if (result == null) {
            result = System.getProperty("user.dir");
        }
        return result;
    }

}