/****************************************************************************** * 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.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.gemini.blueprint.extender.support.scanning.ConfigurationScanner; import org.eclipse.gemini.blueprint.io.OsgiBundleResource; import org.eclipse.gemini.blueprint.io.OsgiBundleResourcePatternResolver; import org.osgi.framework.Bundle; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternResolver; import org.eclipse.gemini.blueprint.util.OsgiStringUtils; import org.springframework.util.ObjectUtils; /** * Dedication {@link ConfigurationScanner scanner} implementation suitable for Blueprint bundles. * * @author Costin Leau */ public class BlueprintConfigurationScanner implements ConfigurationScanner { /** logger */ private static final Log log = LogFactory.getLog(BlueprintConfigurationScanner.class); private static final String CONTEXT_DIR = "OSGI-INF/blueprint/"; private static final String CONTEXT_FILES = "*.xml"; /** Default configuration location */ public static final String DEFAULT_CONFIG = OsgiBundleResource.BUNDLE_URL_PREFIX + CONTEXT_DIR + CONTEXT_FILES; public String[] getConfigurations(Bundle bundle) { String bundleName = OsgiStringUtils.nullSafeName(bundle); boolean trace = log.isTraceEnabled(); boolean debug = log.isDebugEnabled(); if (debug) log.debug("Scanning bundle " + bundleName + " for blueprint configurations..."); String[] locations = BlueprintConfigUtils.getBlueprintHeaderLocations(bundle.getHeaders()); // if no location is specified in the header, try the defaults if (locations == null) { if (trace) { log.trace("Bundle " + bundleName + " has no declared locations; trying default " + DEFAULT_CONFIG); } locations = new String[] { DEFAULT_CONFIG }; } else { // check whether the header is empty if (ObjectUtils.isEmpty(locations)) { log.info("Bundle " + bundleName + " has an empty blueprint header - ignoring bundle..."); return new String[0]; } } String[] configs = findValidBlueprintConfigs(bundle, locations); if (debug) log.debug("Discovered in bundle" + bundleName + " blueprint configurations=" + Arrays.toString(configs)); return configs; } /** * Checks if the given bundle contains existing configurations. The absolute paths are returned without performing * any checks. * * @return */ private String[] findValidBlueprintConfigs(Bundle bundle, String[] locations) { List<String> configs = new ArrayList<String>(locations.length); ResourcePatternResolver loader = new OsgiBundleResourcePatternResolver(bundle); boolean debug = log.isDebugEnabled(); for (String location : locations) { if (isAbsolute(location)) { configs.add(location); } // resolve the location to check if it's present else { try { String loc = location; if (loc.endsWith("/")) { loc = loc + "*.xml"; } Resource[] resources = loader.getResources(loc); if (!ObjectUtils.isEmpty(resources)) { for (Resource resource : resources) { if (resource.exists()) { String value = resource.getURL().toString(); if (debug) log.debug("Found location " + value); configs.add(value); } } } } catch (IOException ex) { if (debug) log.debug("Cannot resolve location " + location, ex); } } } return (String[]) configs.toArray(new String[configs.size()]); } private boolean isAbsolute(String location) { return !(location.endsWith("/") || location.contains("*")); } }