/******************************************************************************* * Copyright (c) 2008, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.kernel.install.artifact.internal; import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.Locale; import org.eclipse.virgo.kernel.artifact.fs.ArtifactFS; import org.eclipse.virgo.kernel.artifact.fs.ArtifactFSFactory; import org.eclipse.virgo.nano.deployer.api.core.DeployerLogEvents; import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage; import org.eclipse.virgo.medic.eventlog.EventLogger; import org.eclipse.virgo.util.io.JarUtils; import org.eclipse.virgo.util.io.PathReference; final class StandardArtifactStorage implements ArtifactStorage { private static final String DEPLOYER_UNPACK_BUNDLES_TRUE = "true"; private static final List<String> CONSTANT_PATH_EXTENSIONS = Arrays.asList("par", "zip"); private static final List<String> ALWAYS_UNPACKED_EXTENSIONS = Arrays.asList("par", "zip"); private static final List<String> CONFIGURABLY_UNPACKED_EXTENSIONS = Arrays.asList("jar", "war"); private final PathReference sourcePathReference; private final ArtifactFSFactory artifactFSFactory; private final EventLogger eventLogger; private final boolean unpackBundles; private final ArtifactStore pathGenerator; public StandardArtifactStorage(PathReference sourcePathReference, PathReference baseStagingPathReference, ArtifactFSFactory artifactFSFactory, EventLogger eventLogger, String unpackBundlesOption) { this.sourcePathReference = sourcePathReference; this.artifactFSFactory = artifactFSFactory; this.eventLogger = eventLogger; this.unpackBundles = unpackBundlesOption == null || DEPLOYER_UNPACK_BUNDLES_TRUE.equalsIgnoreCase(unpackBundlesOption); this.pathGenerator = CONSTANT_PATH_EXTENSIONS.contains(getFileExtension(sourcePathReference)) ? new FileMovingArtifactStore( baseStagingPathReference) : new GenerationalArtifactStore(baseStagingPathReference); PathReference currentPathReference = this.pathGenerator.getCurrentPath(); currentPathReference.delete(true); synchronize(this.sourcePathReference); } @Override public void synchronize() { this.pathGenerator.save(); synchronize(this.sourcePathReference); } @Override public ArtifactFS getArtifactFS() { return this.artifactFSFactory.create(this.pathGenerator.getCurrentPath().toFile()); } @Override public void synchronize(URI sourceUri) { this.pathGenerator.save(); synchronize(new PathReference(sourceUri)); } @Override public void rollBack() { this.pathGenerator.restore(); } @Override public void delete() { PathReference currentPathReference = this.pathGenerator.getCurrentPath(); currentPathReference.delete(true); } private void synchronize(PathReference normalizedSourcePathReference) { PathReference currentPathReference = this.pathGenerator.getCurrentPath(); if (normalizedSourcePathReference != null && !normalizedSourcePathReference.isDirectory() && needsUnpacking(normalizedSourcePathReference)) { try { JarUtils.unpackTo(normalizedSourcePathReference, currentPathReference); } catch (IOException e) { this.eventLogger.log(DeployerLogEvents.JAR_UNPACK_ERROR, e, normalizedSourcePathReference); throw new RuntimeException(String.format("Exception unpacking '%s'", normalizedSourcePathReference), e); } } else if (normalizedSourcePathReference != null) { normalizedSourcePathReference.copy(currentPathReference, true); } else { currentPathReference.createDirectory(); } } private boolean needsUnpacking(PathReference pathReference) { String fileExtension = getFileExtension(pathReference); if (fileExtension == null) { return false; } // Always unpack .par/.zip. Unpack .jar/.war if and only if kernel property deployer.unpackBundles is either not // specified or is "true" return ALWAYS_UNPACKED_EXTENSIONS.contains(fileExtension) || this.unpackBundles && CONFIGURABLY_UNPACKED_EXTENSIONS.contains(fileExtension); } private static String getFileExtension(PathReference pathReference) { if (pathReference == null) { return null; } String name = pathReference.getName(); String fileName = name.toLowerCase(Locale.ENGLISH); int dotLocation = fileName.lastIndexOf('.'); if (dotLocation == -1) { return null; } return fileName.substring(dotLocation + 1); } }