/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.extender.internal.blueprint.activator.support; import java.util.ArrayList; import java.util.Dictionary; import java.util.List; import org.osgi.framework.Constants; import org.eclipse.gemini.blueprint.context.support.OsgiBundleXmlApplicationContext; import org.eclipse.gemini.blueprint.extender.support.internal.ConfigUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** * RFC124-version of {@link ConfigUtils} class. Basically a small util class that handles the retrieval of relevant * headers from the any given bundle. * * @author Costin Leau * */ public class BlueprintConfigUtils { private static final String EQUALS = "="; private static final String SEMI_COLON = ";"; private static final String COMMA = ","; /** Manifest entry name for configuring Blueprint modules */ public static final String BLUEPRINT_HEADER = "Bundle-Blueprint"; /** Standard wait for dependencies header */ public static final String BLUEPRINT_GRACE_PERIOD = "blueprint.graceperiod"; /** Standard timeout header */ public static final String BLUEPRINT_TIMEOUT = "blueprint.timeout"; public static final String EXTENDER_VERSION = "BlueprintExtender-Version"; /** * Returns the {@value #BLUEPRINT_HEADER} if present from the given dictionary. * * @param headers * @return */ public static String getBlueprintHeader(Dictionary headers) { Object header = null; if (headers != null) header = headers.get(BLUEPRINT_HEADER); return (header != null ? header.toString().trim() : null); } public static String getSymNameHeader(Dictionary headers) { Object header = null; if (headers != null) header = headers.get(Constants.BUNDLE_SYMBOLICNAME); return (header != null ? header.toString().trim() : null); } /** * Shortcut method to retrieve directive values. Used internally by the dedicated getXXX. * * @param directiveName * @return */ private static String getDirectiveValue(Dictionary headers, String directiveName) { String header = getBlueprintHeader(headers); if (header != null) { String directive = ConfigUtils.getDirectiveValue(header, directiveName); if (directive != null) return directive; } return null; } /** * Shortcut method for retrieving the directive values. Different then * {@link #getDirectiveValue(Dictionary, String)} since it looks at the Bundle-Symbolic header and not at * Spring-Context. * * @param headers * @param directiveName * @return */ private static String getBlueprintDirectiveValue(Dictionary headers, String directiveName) { String header = getSymNameHeader(headers); if (header != null) { String directive = ConfigUtils.getDirectiveValue(header, directiveName); if (directive != null) return directive; } return null; } public static boolean hasTimeout(Dictionary headers) { String header = getSymNameHeader(headers); if (header != null) { return StringUtils.hasText(ConfigUtils.getDirectiveValue(header, BLUEPRINT_TIMEOUT)); } return false; } /** * Shortcut for finding the boolean value for {@link #BLUEPRINT_TIMEOUT} directive using the given headers. * * Assumes the headers belong to a Spring powered bundle. Returns the timeout (in milliseconds) for which the application * context should wait to have its dependencies satisfied. * * @param headers * @return */ public static long getTimeOut(Dictionary headers) { String value = getBlueprintDirectiveValue(headers, BLUEPRINT_TIMEOUT); if (value != null) { if (ConfigUtils.DIRECTIVE_TIMEOUT_VALUE_NONE.equalsIgnoreCase(value)) { return ConfigUtils.DIRECTIVE_NO_TIMEOUT; } return Long.valueOf(value).longValue(); } return ConfigUtils.DIRECTIVE_TIMEOUT_DEFAULT * 1000; } /** * Shortcut for finding the boolean value for {@link #BLUEPRINT_GRACE_PERIOD} directive using the given headers. * Assumes the headers belong to a Spring powered bundle. * * @param headers * @return */ public static boolean getWaitForDependencies(Dictionary headers) { String value = getBlueprintDirectiveValue(headers, BLUEPRINT_GRACE_PERIOD); return (value != null ? Boolean.valueOf(value).booleanValue() : ConfigUtils.DIRECTIVE_WAIT_FOR_DEPS_DEFAULT); } /** * Shortcut for finding the boolean value for {@link #DIRECTIVE_PUBLISH_CONTEXT} directive using the given headers. * Assumes the headers belong to a Spring powered bundle. * * @param headers * @return */ public static boolean getPublishContext(Dictionary headers) { String value = getDirectiveValue(headers, ConfigUtils.DIRECTIVE_PUBLISH_CONTEXT); return (value != null ? Boolean.valueOf(value).booleanValue() : ConfigUtils.DIRECTIVE_PUBLISH_CONTEXT_DEFAULT); } /** * Shortcut for finding the boolean value for {@link #DIRECTIVE_CREATE_ASYNCHRONOUSLY} directive using the given * headers. * * Assumes the headers belong to a Spring powered bundle. * * @param headers * @return */ public static boolean getCreateAsync(Dictionary headers) { String value = getDirectiveValue(headers, ConfigUtils.DIRECTIVE_CREATE_ASYNCHRONOUSLY); return (value != null ? Boolean.valueOf(value).booleanValue() : ConfigUtils.DIRECTIVE_CREATE_ASYNCHRONOUSLY_DEFAULT); } /** * Returns the location headers (if any) specified by the Blueprint-Bundle header (if available). The returned * Strings can be sent to a {@link org.springframework.core.io.ResourceLoader} for loading the configurations. * * Different from {@link ConfigUtils#getLocationsFromHeader(String, String)} since "," is used for separating * clauses while ; is used inside a clause to allow parameters or directives besides paths. * * Since the presence of the header, disables any processing this method will return null if the header is not * specified, an empty array if it's empty (disabled) or a populated array otherwise. * * @param headers bundle headers * @return array of locations specified (if any) */ public static String[] getBlueprintHeaderLocations(Dictionary headers) { String header = getBlueprintHeader(headers); // no header specified if (header == null) { return null; } // empty header specified if (header.length() == 0) { return new String[0]; } List<String> ctxEntries = new ArrayList<String>(4); if (StringUtils.hasText(header)) { String[] clauses = header.split(COMMA); for (String clause : clauses) { // split into directives String[] directives = clause.split(SEMI_COLON); if (!ObjectUtils.isEmpty(directives)) { // check if it's a path or not for (String directive : directives) { if (!directive.contains(EQUALS)) { ctxEntries.add(directive.trim()); } } } } } // replace * with a 'digestable' location for (int i = 0; i < ctxEntries.size(); i++) { String ctxEntry = ctxEntries.get(i); if (ConfigUtils.CONFIG_WILDCARD.equals(ctxEntry)) ctxEntry = OsgiBundleXmlApplicationContext.DEFAULT_CONFIG_LOCATION; } return (String[]) ctxEntries.toArray(new String[ctxEntries.size()]); } }