package org.camunda.bpm.extension.osgi.container.deployment;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.camunda.bpm.container.impl.deployment.scanning.spi.ProcessApplicationScanner;
import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.impl.bpmn.deployer.BpmnDeployer;
import org.camunda.bpm.engine.impl.util.IoUtil;
import org.osgi.framework.Bundle;
/**
*
* @author Ronny Bräunlich
*
*/
public class OSGiProcessApplicationScanner implements ProcessApplicationScanner {
private Bundle bundle;
private static Logger log = Logger.getLogger(OSGiProcessApplicationScanner.class.getName());
public OSGiProcessApplicationScanner(Bundle bundle) {
this.bundle = bundle;
}
@Override
public Map<String, byte[]> findResources(ClassLoader classLoader, String paResourceRootPath, URL metaFileUrl) {
return findResources(classLoader, paResourceRootPath, metaFileUrl, null);
}
@Override
public Map<String, byte[]> findResources(ClassLoader classLoader, String paResourceRootPath, URL metaFileUrl, String[] additionalResourceSuffixes) {
final Map<String, byte[]> resourceMap = new HashMap<String, byte[]>();
List<String> suffixes = Arrays.asList(BpmnDeployer.BPMN_RESOURCE_SUFFIXES);
if (additionalResourceSuffixes != null) {
suffixes.addAll(Arrays.asList(additionalResourceSuffixes));
}
if (paResourceRootPath != null && !paResourceRootPath.startsWith("pa:")) {
// 1. CASE: paResourceRootPath specified AND it is a "classpath:" resource
// root
String strippedPath = paResourceRootPath.replace("classpath:", "");
scanPathInBundle(suffixes, resourceMap, strippedPath);
} else if (paResourceRootPath == null) {
// 3. CASE: paResourceRootPath not specified
scanPathInBundle(suffixes, resourceMap, "/");
} else {
// 2nd. CASE: paResourceRootPath is PA-local
//FIXME fix this by using BundleWiring.listResources() when moving to OSGi 4.3
throw new ProcessEngineException("PA-loca resourceRootPaths are not supported in an OSGi-environment");
}
return resourceMap;
}
private void scanPathInBundle(List<String> suffixes, final Map<String, byte[]> resourceMap, String strippedPath) {
for (String suffix : suffixes) {
Enumeration<URL> entries = bundle.findEntries(strippedPath, "*." + suffix, true);
if (entries != null) {
for (URL entry : Collections.list(entries)) {
addResource(entry, resourceMap, strippedPath, entry.getPath());
}
}
}
}
protected Enumeration<URL> loadClasspathResourceRoots(final ClassLoader classLoader, String strippedPaResourceRootPath) {
Enumeration<URL> resourceRoots;
try {
resourceRoots = classLoader.getResources(strippedPaResourceRootPath);
} catch (IOException e) {
throw new ProcessEngineException("Could not load resources at '" + strippedPaResourceRootPath + "' using classloaded '" + classLoader + "'", e);
}
return resourceRoots;
}
protected void addResource(URL source, Map<String, byte[]> resourceMap, String resourceRootPath, String resourceName) {
String resourcePath = (resourceRootPath == null ? "" : resourceRootPath).concat(resourceName);
log.log(Level.FINEST, "discovered process resource {0}", resourcePath);
InputStream inputStream = null;
try {
inputStream = source.openStream();
byte[] bytes = IoUtil.readInputStream(inputStream, resourcePath);
resourceMap.put(resourcePath, bytes);
} catch (IOException e) {
throw new ProcessEngineException("Could not open file for reading " + source + ". " + e.getMessage(), e);
} finally {
if (inputStream != null) {
IoUtil.closeSilently(inputStream);
}
}
}
}