package org.camunda.bpm.extension.osgi.internal;
import static org.camunda.bpm.extension.osgi.Constants.BUNDLE_PROCESS_DEFINITIONS_HEADER;
import static org.camunda.bpm.extension.osgi.Constants.BUNDLE_PROCESS_DEFINTIONS_DEFAULT;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.camunda.bpm.extension.osgi.Constants;
import org.camunda.bpm.extension.osgi.util.HeaderParser;
import org.camunda.bpm.extension.osgi.util.HeaderParser.PathElement;
import org.osgi.framework.Bundle;
/**
* Helper class to parse the paths of process definitions inside a bundle.
*
* @author Ronny Bräunlich
*
*/
public final class ProcessDefinitionParser {
private ProcessDefinitionParser() {
}
private static final Logger LOGGER = Logger
.getLogger(ProcessDefinitionParser.class.getName());
/**
* Scans a bundle if it contains process definitions at the place pointed to
* by the {@link Constants#BUNDLE_PROCESS_DEFINITIONS_HEADER} or at the
* default location {@link Constants#BUNDLE_PROCESS_DEFINTIONS_DEFAULT}.
*
* @param bundle
* @return list of URLs pointing to process definitions or an empty list
*
*/
public static List<URL> scanForProcesses(Bundle bundle) {
LOGGER.log(Level.FINE, "Scanning bundle {} for process",
bundle.getSymbolicName());
String processDefHeader = bundle.getHeaders().get(
BUNDLE_PROCESS_DEFINITIONS_HEADER);
if (processDefHeader == null) {
processDefHeader = BUNDLE_PROCESS_DEFINTIONS_DEFAULT;
}
List<PathElement> paths = HeaderParser.parseHeader(processDefHeader);
List<URL> pathList = parsePaths(paths, bundle);
return pathList;
}
/**
* Takes the list of {@link PathElement}s and uses the bundle to find the
* URLs of those elements.
*
* @param paths
* @param bundle
* @return
*/
private static List<URL> parsePaths(List<PathElement> paths, Bundle bundle) {
List<URL> pathList = new ArrayList<URL>();
for (PathElement path : paths) {
String name = path.getName();
if (name.endsWith("/")) {
// we have a directory
addEntries(bundle, name, "*.*", pathList);
} else {
// we have a file name
String baseName;
String filePattern;
int pos = name.lastIndexOf('/');
if (pos < 0) {
baseName = "/";
filePattern = name;
} else {
baseName = name.substring(0, pos + 1);
filePattern = name.substring(pos + 1);
}
if (hasWildcards(filePattern)) {
addEntries(bundle, baseName, filePattern, pathList);
} else {
pathList.add(bundle.getEntry(name));
}
}
}
return pathList;
}
private static boolean hasWildcards(String path) {
return path.indexOf("*") >= 0;
}
/**
* Searches the bundle for files matching the path and filepattern and puts
* them into the list.
*
* @param bundle
* @param path
* @param filePattern
* @param pathList
*/
private static void addEntries(Bundle bundle, String path,
String filePattern, List<URL> pathList) {
Enumeration<?> e = bundle.findEntries(path, filePattern, false);
while (e != null && e.hasMoreElements()) {
URL u = (URL) e.nextElement();
pathList.add(u);
}
}
}