Java tutorial
/* * 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; } }