blob: ce6f5289f14592afa558917ea91279709b8dff0d [file] [log] [blame]
package org.eclipse.virgo.nano.core.internal;
import java.util.Dictionary;
import java.util.Enumeration;
import org.eclipse.virgo.util.common.StringUtils;
import org.osgi.framework.Bundle;
/**
* Utilities class for covering various Spring features like Spring Context discovery.
*
* <strong>Concurrent Semantics</strong><br />
* Thread-safe.
*
*/
public class SpringUtils {
private static final String SPRING_DM_CONTEXT_DIR = "/META-INF/spring/";
private static final String BLUEPRINT_CONTEXT_DIR = "/OSGI-INF/blueprint/";
private static final String CONTEXT_FILES = "*.xml";
private static final String BUNDLE_URL_PREFIX = "osgibundle:";
private static final String SPRING_CONTEXT_HEADER = "Spring-Context";
private static final String BUNDLE_BLUEPRINT_HEADER = "Bundle-Blueprint";
private static final String DIRECTIVE_SEPARATOR = ";";
private static final String CONTEXT_LOCATION_SEPARATOR = ",";
private static final String CONFIG_WILDCARD = "*";
/** Default configuration locations */
private static final String SPRING_DM_DEFAULT_CONFIG = BUNDLE_URL_PREFIX + SPRING_DM_CONTEXT_DIR + CONTEXT_FILES;
private static final String BLUEPRINT_DEFAULT_CONFIG = BUNDLE_URL_PREFIX + BLUEPRINT_CONTEXT_DIR + CONTEXT_FILES;
private static String[] getSpringContextConfigurations(Bundle bundle) {
String[] locations = getSpringContextHeaderLocations(bundle.getHeaders());
// if no location is specified in the header, try the defaults
if (isArrayEmpty(locations)) {
// check the default locations if the manifest doesn't provide any info
Enumeration defaultConfig = bundle.findEntries(SPRING_DM_CONTEXT_DIR, CONTEXT_FILES, false);
if (defaultConfig != null && defaultConfig.hasMoreElements()) {
return new String[] { SPRING_DM_DEFAULT_CONFIG };
} else {
defaultConfig = bundle.findEntries(BLUEPRINT_CONTEXT_DIR, CONTEXT_FILES, false);
if (defaultConfig != null && defaultConfig.hasMoreElements()) {
return new String[] { BLUEPRINT_DEFAULT_CONFIG };
} else {
return new String[0];
}
}
} else {
return locations;
}
}
/**
* Returns the location headers (if any) specified by the Spring-Context header (if available). The returned Strings
* can be sent to a {@link org.springframework.core.io.ResourceLoader} for loading the configurations.
*
* @param headers bundle headers
* @return array of locations specified (if any)
*/
static String[] getSpringContextHeaderLocations(Dictionary headers) {
String header = getSpringContextHeader(headers);
String[] ctxEntries;
if (StringUtils.hasText(header) && !(';' == header.charAt(0))) {
// get the config locations
String locations = StringUtils.tokenizeToStringArray(header, DIRECTIVE_SEPARATOR)[0];
// parse it into individual token
ctxEntries = StringUtils.tokenizeToStringArray(locations, CONTEXT_LOCATION_SEPARATOR);
// replace * with a 'digestable' location
for (int i = 0; i < ctxEntries.length; i++) {
if (CONFIG_WILDCARD.equals(ctxEntries[i]))
ctxEntries[i] = SPRING_DM_DEFAULT_CONFIG;
}
} else {
header = getBundleBlueprintHeader(headers);
if (StringUtils.hasText(header) && !(';' == header.charAt(0))) {
// get the config locations
String locations = StringUtils.tokenizeToStringArray(header, DIRECTIVE_SEPARATOR)[0];
// parse it into individual token
ctxEntries = StringUtils.tokenizeToStringArray(locations, CONTEXT_LOCATION_SEPARATOR);
// replace * with a 'digestable' location
for (int i = 0; i < ctxEntries.length; i++) {
if (CONFIG_WILDCARD.equals(ctxEntries[i]))
ctxEntries[i] = BLUEPRINT_DEFAULT_CONFIG;
}
} else {
ctxEntries = new String[0];
}
}
return ctxEntries;
}
static boolean isArrayEmpty(Object[] array) {
return (array == null || array.length == 0);
}
static String getSpringContextHeader(Dictionary headers) {
Object header = null;
if (headers != null) {
header = headers.get(SPRING_CONTEXT_HEADER);
}
return (header != null ? header.toString().trim() : null);
}
static String getBundleBlueprintHeader(Dictionary headers) {
Object header = null;
if (headers != null) {
header = headers.get(BUNDLE_BLUEPRINT_HEADER);
}
return (header != null ? header.toString().trim() : null);
}
/**
* Queries whether the supplied {@link Bundle} is Spring-DM powered.
*
* @param bundle the <code>Bundle</code>.
* @return <code>true</code> if the <code>Bundle</code> is Spring-DM powered, otherwise <code>false</code>.
*/
public static boolean isSpringDMPoweredBundle(Bundle bundle) {
String[] configurations = getSpringContextConfigurations(bundle);
return !isArrayEmpty(configurations);
}
}