/*******************************************************************************
* Copyright (c) 2008, 2011 VMware Inc. and others
* 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
* EclipseSource - Bug 358442 Change InstallArtifact graph from a tree to a DAG
*******************************************************************************/
package org.eclipse.virgo.kernel.deployer.core.internal;
import java.io.IOException;
import java.util.Map;
import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
import org.eclipse.virgo.kernel.install.environment.InstallEnvironment;
import org.eclipse.virgo.kernel.install.pipeline.stage.transform.Transformer;
import org.eclipse.virgo.util.common.GraphNode;
import org.eclipse.virgo.util.common.GraphNode.ExceptionThrowingDirectedAcyclicGraphVisitor;
import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
/**
* {@link Transformer} implementation that converts deployment properties on bundle artifacts into the corresponding
* manifest headers.
* <p/>
* Any deployment property with a key prefixed by <code>header:</code> will be treated a as bundle header.
*
* <strong>Concurrent Semantics</strong><br />
*
* Thread-safe.
*
*/
final class BundleDeploymentPropertiesTransformer implements Transformer {
private static final String HEADER_PREFIX = "header:";
public void transform(GraphNode<InstallArtifact> installGraph, InstallEnvironment installEnvironment) throws DeploymentException {
installGraph.visit(new Visitor());
}
private void doTransformBundleArtifact(BundleInstallArtifact value, Map<String, String> deploymentProperties) throws IOException {
BundleManifest manifest = value.getBundleManifest();
for(Map.Entry<String, String> entries : deploymentProperties.entrySet()) {
String headerName = convertToHeaderName(entries.getKey());
if(headerName != null) {
manifest.setHeader(headerName, entries.getValue());
}
}
}
/**
* Attempts to convert the supplied property key into a header name. If the key is not a valid header name (it
* doesn't have the header: prefix) then <code>null</code> is returned.
*/
private String convertToHeaderName(String propertyKey) {
if(propertyKey.startsWith(HEADER_PREFIX)) {
return propertyKey.substring(HEADER_PREFIX.length());
} else {
return null;
}
}
private final class Visitor implements ExceptionThrowingDirectedAcyclicGraphVisitor<InstallArtifact, DeploymentException> {
public boolean visit(GraphNode<InstallArtifact> graph) throws DeploymentException {
InstallArtifact value = graph.getValue();
if (value instanceof BundleInstallArtifact) {
Map<String, String> deploymentProperties = ((BundleInstallArtifact)value).getDeploymentProperties();
if (deploymentProperties != null && !deploymentProperties.isEmpty()) {
try {
doTransformBundleArtifact((BundleInstallArtifact) value, deploymentProperties);
} catch (Exception e) {
throw new DeploymentException("Unable to apply deployment for artifact '" + value.getName() + "'", e);
}
}
}
return true;
}
}
}