| |
| 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); |
| } |
| } |