/*******************************************************************************
* 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.File;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.virgo.kernel.artifact.fs.ArtifactFSFactory;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity;
import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage;
import org.eclipse.virgo.medic.eventlog.EventLogger;
import org.eclipse.virgo.util.io.PathReference;
/**
* Standard implementation of {@link ArtifactStorage} that creates storage locations using a nested directory structure
* of the form scope/type/name/version.
*
* <p />
*
* <strong>Concurrent Semantics</strong><br />
*
* Thread-safe
*
*/
public final class StandardArtifactStorageFactory implements ArtifactStorageFactory {
private static final String DEPLOYER_STAGING_DIRECTORY = "s";
private final PathReference workDirectory;
private final ArtifactFSFactory artifactFSFactory;
private final EventLogger eventLogger;
private final String unpackBundles;
private final Object monitor = new Object();
private final Map<PathReference, Long> uniqueId = new HashMap<PathReference, Long>();
public StandardArtifactStorageFactory(PathReference workDirectory, ArtifactFSFactory artifactFSFactory, EventLogger eventLogger,
String unpackBundles) {
this.workDirectory = workDirectory;
this.artifactFSFactory = artifactFSFactory;
this.eventLogger = eventLogger;
this.unpackBundles = unpackBundles;
this.workDirectory.newChild(DEPLOYER_STAGING_DIRECTORY).delete(true);
}
public ArtifactStorage create(File file, ArtifactIdentity artifactIdentity) {
PathReference sourcePathReference = new PathReference(file);
PathReference stagingPathReference = createStagingPathReference(artifactIdentity, file.getName());
return new StandardArtifactStorage(sourcePathReference, stagingPathReference, this.artifactFSFactory, this.eventLogger, this.unpackBundles);
}
public ArtifactStorage createDirectoryStorage(ArtifactIdentity artifactIdentity, String directoryName) {
PathReference stagingPathReference = createStagingPathReference(artifactIdentity, directoryName);
stagingPathReference.createDirectory();
return new StandardArtifactStorage(null, stagingPathReference, this.artifactFSFactory, this.eventLogger, this.unpackBundles);
}
private PathReference createStagingPathReference(ArtifactIdentity artifactIdentity, String name) {
PathReference scopeDir = this.workDirectory.newChild(DEPLOYER_STAGING_DIRECTORY).newChild(normalizeScopeName(artifactIdentity.getScopeName()));
return createNextChild(scopeDir).newChild(name);
}
private String normalizeScopeName(String scopeName) {
return scopeName == null ? "global" : scopeName;
}
private PathReference createNextChild(PathReference scopeDir) {
synchronized (this.monitor) {
Long uniqueId = this.uniqueId.get(scopeDir);
uniqueId = uniqueId == null ? 0L : uniqueId + 1;
this.uniqueId.put(scopeDir, uniqueId);
return scopeDir.newChild(uniqueId.toString());
}
}
}