/******************************************************************************
 * 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.io;

import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.gemini.blueprint.io.internal.OsgiHeaderUtils;
import org.eclipse.gemini.blueprint.io.internal.OsgiResourceUtils;
import org.eclipse.gemini.blueprint.io.internal.OsgiUtils;
import org.eclipse.gemini.blueprint.io.internal.resolver.DependencyResolver;
import org.eclipse.gemini.blueprint.io.internal.resolver.ImportedBundle;
import org.eclipse.gemini.blueprint.io.internal.resolver.PackageAdminResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;

/**
 * OSGi-aware {@link ResourcePatternResolver}.
 * 
 * Can find resources in the <em>bundle jar</em> and <em>bundle space</em>. See {@link OsgiBundleResource} for more
 * information.
 * 
 * <p/> <b>ClassPath support</b>
 * 
 * <p/> As mentioned by {@link PathMatchingResourcePatternResolver}, class-path pattern matching needs to resolve the
 * class-path structure to a file-system location (be it an actual folder or a jar). Inside the OSGi environment this is
 * problematic as the bundles can be loaded in memory directly from input streams. To avoid relying on each platform
 * bundle storage structure, this implementation tries to determine the bundles that assemble the given bundle
 * class-path and analyze each of them individually. This involves the bundle archive (including special handling of the
 * <code>Bundle-Classpath</code> as it is computed at runtime), the bundle required packages and its attached fragments.
 * 
 * Depending on the configuration of running environment, this might cause significant IO activity which can affect
 * performance.
 * 
 * <p/> <b>Note:</b> Currently, <em>static</em> imports as well as <code>Bundle-Classpath</code> and
 * <code>Required-Bundle</code> entries are supported. Support for <code>DynamicPackage-Import</code> depends on
 * how/when the underlying platform does the wiring between the dynamically imported bundle and the given bundle.
 * 
 * <p/> <b>Portability Note:</b> Since it relies only on the OSGi API, this implementation depends heavily on how
 * closely the platform implements the OSGi spec. While significant tests have been made to ensure compatibility, one
 * <em>might</em> experience different behaviour especially when dealing with jars with missing folder entries or
 * boot-path delegation. It is strongly recommended that wildcard resolution be thoroughly tested before switching to a
 * different platform before you rely on it.
 * 
 * @see Bundle
 * @see OsgiBundleResource
 * @see PathMatchingResourcePatternResolver
 * 
 * @author Costin Leau
 *
 * TODO: Rework to use WIRE Admin
 */
public class OsgiBundleResourcePatternResolver extends PathMatchingResourcePatternResolver {

	/**
	 * Our own logger to protect against incompatible class changes.
	 */
	private static final Log logger = LogFactory.getLog(OsgiBundleResourcePatternResolver.class);

	/**
	 * The bundle on which this resolver works on.
	 */
	private final Bundle bundle;

	/**
	 * The bundle context associated with this bundle.
	 */
	private final BundleContext bundleContext;

	private static final String FOLDER_SEPARATOR = "/";

	private static final String FOLDER_WILDCARD = "**";

	private static final String JAR_EXTENSION = ".jar";

	private static final String BUNDLE_DEFAULT_CP = ".";

	private static final char SLASH = '/';

	private static final char DOT = '.';

	// use the default package admin version
	private final DependencyResolver resolver;

	public OsgiBundleResourcePatternResolver(Bundle bundle) {
		this(new OsgiBundleResourceLoader(bundle));
	}

	public OsgiBundleResourcePatternResolver(ResourceLoader resourceLoader) {
		super(resourceLoader);
		if (resourceLoader instanceof OsgiBundleResourceLoader) {
			this.bundle = ((OsgiBundleResourceLoader) resourceLoader).getBundle();
		} else {
			this.bundle = null;
		}

		this.bundleContext = (bundle != null ? OsgiUtils.getBundleContext(this.bundle) : null);
		this.resolver = (bundleContext != null ? new PackageAdminResolver(bundleContext) : null);
	}

	/**
	 * Finds existing resources. This method returns the actual resources found w/o adding any extra decoration (such as
	 * non-existing resources).
	 * 
	 * @param locationPattern location pattern
	 * @return found resources (w/o any decoration)
	 * @throws IOException in case of I/O errors
	 */
	protected Resource[] findResources(String locationPattern) throws IOException {
		Assert.notNull(locationPattern, "Location pattern must not be null");
		int type = OsgiResourceUtils.getSearchType(locationPattern);

		// look for patterns (includes classpath*:)
		if (getPathMatcher().isPattern(locationPattern)) {
			// treat classpath as a special case
			if (OsgiResourceUtils.isClassPathType(type))
				return findClassPathMatchingResources(locationPattern, type);

			return findPathMatchingResources(locationPattern, type);
		}
		// even though we have no pattern
		// the OSGi space can return multiple entries for the same resource name
		// - treat this case below
		else {
			Resource[] result = null;

			OsgiBundleResource resource = new OsgiBundleResource(bundle, locationPattern);

			switch (type) {
			// same as bundle space
			case OsgiResourceUtils.PREFIX_TYPE_NOT_SPECIFIED:
				// consider bundle-space which can return multiple URLs
			case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_SPACE:
				result = resource.getAllUrlsFromBundleSpace(locationPattern);
				break;
			// for the rest go with the normal resolving
			default:
				if (!resource.exists())
					result = new Resource[] { resource };
				break;
			}
			return result;
		}
	}

	// add a non-existing resource, if none was found and no pattern was specified
	public Resource[] getResources(final String locationPattern) throws IOException {

		Resource[] resources = findResources(locationPattern);

		// check whether we found something or we should fall-back to a
		// non-existing resource
		if (ObjectUtils.isEmpty(resources) && (!getPathMatcher().isPattern(locationPattern))) {
			return new Resource[] { getResourceLoader().getResource(locationPattern) };
		}
		// return the original array
		return resources;

	}

	/**
	 * Special classpath method. Will try to detect the imported bundles (which are part of the classpath) and look for
	 * resources in all of them. This implementation will try to determine the bundles that compose the current bundle
	 * classpath and then it will inspect the bundle space of each of them individually.
	 * 
	 * <p/> Since the bundle space is considered, runtime classpath entries such as dynamic imports are not supported
	 * (yet).
	 * 
	 * @param locationPattern
	 * @param type
	 * @return classpath resources
	 */
	@SuppressWarnings("unchecked")
	private Resource[] findClassPathMatchingResources(String locationPattern, int type) throws IOException {

		if (resolver == null)
			throw new IllegalArgumentException(
					"PackageAdmin service/a started bundle is required for classpath matching");

		final ImportedBundle[] importedBundles = resolver.getImportedBundles(bundle);

		// eliminate classpath path
		final String path = OsgiResourceUtils.stripPrefix(locationPattern);

		final Collection<String> foundPaths = new LinkedHashSet<String>();

		// 1. search the imported packages

		// find folder path matching
		final String rootDirPath = determineFolderPattern(path);

		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {

					public Object run() throws IOException {
						for (int i = 0; i < importedBundles.length; i++) {
							final ImportedBundle importedBundle = importedBundles[i];
							if (!bundle.equals(importedBundle.getBundle())) {
								findImportedBundleMatchingResource(importedBundle, rootDirPath, path, foundPaths);
							}
						}
						return null;
					}
				});
			} catch (PrivilegedActionException pe) {
				throw (IOException) pe.getException();
			}
		} else {
			for (int i = 0; i < importedBundles.length; i++) {
				final ImportedBundle importedBundle = importedBundles[i];
				if (!bundle.equals(importedBundle.getBundle())) {
					findImportedBundleMatchingResource(importedBundle, rootDirPath, path, foundPaths);
				}
			}
		}

		// 2. search the target bundle
		findSyntheticClassPathMatchingResource(bundle, path, foundPaths);

		// 3. resolve the entries using the official class-path method (as some of them might be hidden)
		List<Resource> resources = new ArrayList<Resource>(foundPaths.size());

		for (String resourcePath : foundPaths) {
			// classpath*: -> getResources()
			if (OsgiResourceUtils.PREFIX_TYPE_CLASS_ALL_SPACE == type) {
				CollectionUtils.mergeArrayIntoCollection(convertURLEnumerationToResourceArray(bundle
						.getResources(resourcePath), resourcePath), resources);
			}
			// classpath -> getResource()
			else {
				URL url = bundle.getResource(resourcePath);
				if (url != null)
					resources.add(new UrlContextResource(url, resourcePath));
			}
		}

		if (logger.isTraceEnabled()) {
			logger.trace("Fitered " + foundPaths + " to " + resources);
		}

		return (Resource[]) resources.toArray(new Resource[resources.size()]);
	}

	private String determineFolderPattern(String path) {
		int index = path.lastIndexOf(FOLDER_SEPARATOR);
		return (index > 0 ? path.substring(0, index + 1) : "");
	}

	private ContextResource[] convertURLEnumerationToResourceArray(Enumeration<URL> enm, String path) {
		Set<ContextResource> resources = new LinkedHashSet<ContextResource>(4);
		while (enm != null && enm.hasMoreElements()) {
			resources.add(new UrlContextResource(enm.nextElement(), path));
		}
		return (ContextResource[]) resources.toArray(new ContextResource[resources.size()]);
	}

	/**
	 * Searches for the given pattern inside the imported bundle. This translates to pattern matching on the imported
	 * packages.
	 * 
	 * @param importedBundle imported bundle
	 * @param path path used for pattern matching
	 * @param foundPaths collection of found results
	 */
	@SuppressWarnings("unchecked")
	private void findImportedBundleMatchingResource(final ImportedBundle importedBundle, String rootPath, String path,
			final Collection<String> foundPaths) throws IOException {

		final boolean trace = logger.isTraceEnabled();

		String[] packages = importedBundle.getImportedPackages();

		if (trace)
			logger.trace("Searching path [" + path + "] on imported pkgs " + ObjectUtils.nullSafeToString(packages)
					+ "...");

		final boolean startsWithSlash = rootPath.startsWith(FOLDER_SEPARATOR);

		for (int i = 0; i < packages.length; i++) {
			// transform the package name into a path
			String pkg = packages[i].replace(DOT, SLASH) + SLASH;

			if (startsWithSlash) {
				pkg = FOLDER_SEPARATOR + pkg;
			}

			final PathMatcher matcher = getPathMatcher();
			// if the imported package matches the path
			if (matcher.matchStart(path, pkg)) {
				Bundle bundle = importedBundle.getBundle();
				// 1. look at the Bundle jar root
				Enumeration<String> entries = bundle.getEntryPaths(pkg);
				while (entries != null && entries.hasMoreElements()) {
					String entry = entries.nextElement();
					if (startsWithSlash)
						entry = FOLDER_SEPARATOR + entry;

					if (matcher.match(path, entry)) {
						if (trace)
							logger.trace("Found entry [" + entry + "]");
						foundPaths.add(entry);
					}
				}
				// 2. Do a Bundle-Classpath lookup (since the jar might use a different classpath)
				Collection<String> cpMatchingPaths = findBundleClassPathMatchingPaths(bundle, path);
				foundPaths.addAll(cpMatchingPaths);
			}
		}
	}

	/**
	 * Applies synthetic class-path analysis. That is, search the bundle space and the bundle class-path for entries
	 * matching the given path.
	 * 
	 * @param bundle
	 * @param path
	 * @param foundPaths
	 * @throws IOException
	 */
	private void findSyntheticClassPathMatchingResource(Bundle bundle, String path, Collection<String> foundPaths)
			throws IOException {
		// 1. bundle space lookup
		OsgiBundleResourcePatternResolver localPatternResolver = new OsgiBundleResourcePatternResolver(bundle);
		Resource[] foundResources = localPatternResolver.findResources(path);

		boolean trace = logger.isTraceEnabled();

		if (trace)
			logger.trace("Found synthetic cp resources " + ObjectUtils.nullSafeToString(foundResources));

		for (int j = 0; j < foundResources.length; j++) {
			// assemble only the OSGi paths
			foundPaths.add(foundResources[j].getURL().getPath());
		}
		// 2. Bundle-Classpath lookup (on the path stripped of the prefix)
		Collection<String> cpMatchingPaths = findBundleClassPathMatchingPaths(bundle, path);

		if (trace)
			logger.trace("Found Bundle-ClassPath matches " + cpMatchingPaths);

		foundPaths.addAll(cpMatchingPaths);

		// 3. Required-Bundle is considered already by the dependency resolver
	}

	/**
	 * Searches the bundle classpath (Bundle-Classpath) entries for the given pattern.
	 * 
	 * @param bundle
	 * @param pattern
	 * @return
	 * @throws IOException
	 */
	private Collection<String> findBundleClassPathMatchingPaths(Bundle bundle, String pattern) throws IOException {
		// list of strings pointing to the matching resources
		List<String> list = new ArrayList<String>(4);

		boolean trace = logger.isTraceEnabled();
		if (trace)
			logger.trace("Analyzing " + Constants.BUNDLE_CLASSPATH + " entries for bundle [" + bundle.getBundleId()
					+ "|" + bundle.getSymbolicName() + "]");
		// see if there is a bundle class-path defined
		String[] entries = OsgiHeaderUtils.getBundleClassPath(bundle);

		if (trace)
			logger.trace("Found " + Constants.BUNDLE_CLASSPATH + " entries " + ObjectUtils.nullSafeToString(entries));

		// 1. if so, look at the entries
		for (int i = 0; i < entries.length; i++) {
			String entry = entries[i];

			// make sure to exclude the default entry
			if (!entry.equals(BUNDLE_DEFAULT_CP)) {

				// 2. locate resource first from the bundle space (since it might not exist)
				OsgiBundleResource entryResource = new OsgiBundleResource(bundle, entry);
				// call the internal method to avoid catching an exception
				URL url = null;
				ContextResource res = entryResource.getResourceFromBundleSpace(entry);
				if (res != null) {
					url = res.getURL();
				}

				if (trace)
					logger.trace("Classpath entry [" + entry + "] resolves to [" + url + "]");
				// we've got a valid entry so let's parse it
				if (url != null) {
					String cpEntryPath = url.getPath();
					// is it a jar ?
					if (entry.endsWith(JAR_EXTENSION))
						findBundleClassPathMatchingJarEntries(list, url, pattern);
					// no, so it must be a folder
					else
						findBundleClassPathMatchingFolders(list, bundle, cpEntryPath, pattern);
				}
			}
		}

		return list;
	}

	/**
	 * Checks the jar entries from the Bundle-Classpath for the given pattern.
	 */
	private void findBundleClassPathMatchingJarEntries(List<String> list, URL url, String pattern) throws IOException {
		// get the stream to the resource and read it as a jar
		JarInputStream jis = new JarInputStream(url.openStream());
		Set<String> result = new LinkedHashSet<String>(8);

		boolean patternWithFolderSlash = pattern.startsWith(FOLDER_SEPARATOR);

		// parse the jar and do pattern matching
		try {
			while (jis.available() > 0) {
				JarEntry jarEntry = jis.getNextJarEntry();
				// if the jar has ended, the entry can be null (on Sun JDK at least)
				if (jarEntry != null) {
					String entryPath = jarEntry.getName();

					// check if leading "/" is needed or not (it depends how the jar was created)
					if (entryPath.startsWith(FOLDER_SEPARATOR)) {
						if (!patternWithFolderSlash) {
							entryPath = entryPath.substring(FOLDER_SEPARATOR.length());
						}
					} else {
						if (patternWithFolderSlash) {
							entryPath = FOLDER_SEPARATOR.concat(entryPath);
						}
					}
					if (getPathMatcher().match(pattern, entryPath)) {
						result.add(entryPath);
					}
				}
			}
		} finally {
			try {
				jis.close();
			} catch (IOException io) {
				// ignore it - nothing we can't do about it
			}
		}

		if (logger.isTraceEnabled())
			logger.trace("Found in nested jar [" + url + "] matching entries " + result);

		list.addAll(result);
	}

	/**
	 * Checks the folder entries from the Bundle-Classpath for the given pattern.
	 * 
	 * @param list
	 * @param bundle
	 * @param cpEntryPath
	 * @param pattern
	 * @throws IOException
	 */
	private void findBundleClassPathMatchingFolders(List<String> list, Bundle bundle, String cpEntryPath, String pattern)
			throws IOException {
		// append path to the pattern and do a normal search
		// folder/<pattern> starts being applied

		String bundlePathPattern;

		boolean entryWithFolderSlash = cpEntryPath.endsWith(FOLDER_SEPARATOR);
		boolean patternWithFolderSlash = pattern.startsWith(FOLDER_SEPARATOR);
		// concatenate entry + pattern w/o double slashes
		if (entryWithFolderSlash) {
			if (patternWithFolderSlash)
				bundlePathPattern = cpEntryPath + pattern.substring(1, pattern.length());
			else
				bundlePathPattern = cpEntryPath + pattern;
		} else {
			if (patternWithFolderSlash)
				bundlePathPattern = cpEntryPath + pattern;
			else
				bundlePathPattern = cpEntryPath + FOLDER_SEPARATOR + pattern;
		}

		// search the bundle space for the detected resource
		OsgiBundleResourcePatternResolver localResolver = new OsgiBundleResourcePatternResolver(bundle);
		Resource[] resources = localResolver.getResources(bundlePathPattern);

		boolean trace = logger.isTraceEnabled();
		List<String> foundResources = (trace ? new ArrayList<String>(resources.length) : null);

		try {
			// skip when dealing with non-existing resources
			if (resources.length == 1 && !resources[0].exists()) {
				return;
			} else {
				int cutStartingIndex = cpEntryPath.length();
				// add the resource stripping the cp
				for (int i = 0; i < resources.length; i++) {
					String path = resources[i].getURL().getPath().substring(cutStartingIndex);
					list.add(path);
					if (trace)
						foundResources.add(path);
				}
			}
		} finally {
			if (trace)
				logger.trace("Searching for [" + bundlePathPattern + "] revealed resources (relative to the cp entry ["
						+ cpEntryPath + "]): " + foundResources);
		}
	}

	/**
	 * Replace the super class implementation to pass in the searchType parameter.
	 * 
	 * @see PathMatchingResourcePatternResolver#findPathMatchingResources(String)
	 */
	private Resource[] findPathMatchingResources(String locationPattern, int searchType) throws IOException {
		String rootDirPath = determineRootDir(locationPattern);
		String subPattern = locationPattern.substring(rootDirPath.length());
		Resource[] rootDirResources = getResources(rootDirPath);

		boolean trace = logger.isTraceEnabled();

		if (trace)
			logger.trace("Found root resources for [" + rootDirPath + "] :"
					+ ObjectUtils.nullSafeToString(rootDirResources));

		Set<Resource> result = new LinkedHashSet<Resource>();
		for (int i = 0; i < rootDirResources.length; i++) {
			Resource rootDirResource = rootDirResources[i];
			if (isJarResource(rootDirResource)) {
				// FIXME: Spring 5 Migration
				result.addAll(doFindPathMatchingJarResources(rootDirResource, new URL(""), subPattern));
			} else {
				result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern, searchType));
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Resolved location pattern [" + locationPattern + "] to resources " + result);
		}
		return result.toArray(new Resource[result.size()]);
	}

	/**
	 * {@inheritDoc}
	 *
	 * Overrides the default check up since computing the URL can be fairly expensive operation as there is no caching
	 * (due to the framework dynamic nature).
	 */
	protected boolean isJarResource(Resource resource) throws IOException {
		if (resource instanceof OsgiBundleResource) {
			// check the resource type
			OsgiBundleResource bundleResource = (OsgiBundleResource) resource;
			// if it's known, then it's not a jar
			if (bundleResource.getSearchType() != OsgiResourceUtils.PREFIX_TYPE_UNKNOWN) {
				return false;
			}
			// otherwise the normal parsing occur
		}
		return super.isJarResource(resource);
	}

	/**
	 * Based on the search type, uses the appropriate searching method.
	 *
	 * @see OsgiBundleResource#BUNDLE_URL_PREFIX
	 * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver#getResources(java.lang.String)
	 */
	private Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern, int searchType)
			throws IOException {

		String rootPath = null;

		if (rootDirResource instanceof OsgiBundleResource) {
			OsgiBundleResource bundleResource = (OsgiBundleResource) rootDirResource;
			rootPath = bundleResource.getPath();
			searchType = bundleResource.getSearchType();
		} else if (rootDirResource instanceof UrlResource) {
			rootPath = rootDirResource.getURL().getPath();
		}

		if (rootPath != null) {
			String cleanPath = OsgiResourceUtils.stripPrefix(rootPath);
			// sanitize the root folder (since it's possible to not specify the root which fails any further matches)
			if (!cleanPath.endsWith(FOLDER_SEPARATOR)) {
				cleanPath = cleanPath + FOLDER_SEPARATOR;
			}
			String fullPattern = cleanPath + subPattern;
			Set<Resource> result = new LinkedHashSet<Resource>();
			doRetrieveMatchingBundleEntries(bundle, fullPattern, cleanPath, result, searchType);
			return result;
		} else {
			return super.doFindPathMatchingFileResources(rootDirResource, subPattern);
		}
	}

	/**
	 * Searches each level inside the bundle for entries based on the search strategy chosen.
	 * 
	 * @param bundle the bundle to do the lookup
	 * @param fullPattern matching pattern
	 * @param dir directory inside the bundle
	 * @param result set of results (used to concatenate matching sub dirs)
	 * @param searchType the search strategy to use
	 * @throws IOException
	 */
	private void doRetrieveMatchingBundleEntries(Bundle bundle, String fullPattern, String dir, Set<Resource> result,
			int searchType) throws IOException {

		Enumeration<?> candidates;

		switch (searchType) {
		case OsgiResourceUtils.PREFIX_TYPE_NOT_SPECIFIED:
		case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_SPACE:
			// returns an enumeration of URLs
			candidates = bundle.findEntries(dir, null, false);
			break;
		case OsgiResourceUtils.PREFIX_TYPE_BUNDLE_JAR:
			// returns an enumeration of Strings
			candidates = bundle.getEntryPaths(dir);
			break;
		case OsgiResourceUtils.PREFIX_TYPE_CLASS_SPACE:
			// returns an enumeration of URLs
			throw new IllegalArgumentException("class space does not support pattern matching");
		default:
			throw new IllegalArgumentException("unknown searchType " + searchType);
		}

		// entries are relative to the root path - miss the leading /
		if (candidates != null) {
			boolean dirDepthNotFixed = (fullPattern.indexOf(FOLDER_WILDCARD) != -1);
			while (candidates.hasMoreElements()) {
				Object path = candidates.nextElement();
				String currPath;

				if (path instanceof String)
					currPath = handleString((String) path);
				else
					currPath = handleURL((URL) path);

				if (!currPath.startsWith(dir)) {
					// Returned resource path does not start with relative
					// directory:
					// assuming absolute path returned -> strip absolute path.
					int dirIndex = currPath.indexOf(dir);
					if (dirIndex != -1) {
						currPath = currPath.substring(dirIndex);
					}
				}

				if (currPath.endsWith(FOLDER_SEPARATOR)
						&& (dirDepthNotFixed || StringUtils.countOccurrencesOf(currPath, FOLDER_SEPARATOR) < StringUtils
								.countOccurrencesOf(fullPattern, FOLDER_SEPARATOR))) {
					// Search subdirectories recursively: we manually get the
					// folders on only one level

					doRetrieveMatchingBundleEntries(bundle, fullPattern, currPath, result, searchType);
				}
				if (getPathMatcher().match(fullPattern, currPath)) {
					if (path instanceof URL)
						result.add(new UrlContextResource((URL) path, currPath));
					else
						result.add(new OsgiBundleResource(bundle, currPath));

				}
			}
		}
	}

	/**
	 * Handles candidates returned as URLs.
	 * 
	 * @param path
	 * @return
	 */
	private String handleURL(URL path) {
		return path.getPath();
	}

	/**
	 * Handles candidates returned as Strings.
	 * 
	 * @param path
	 * @return
	 */
	private String handleString(String path) {
		return FOLDER_SEPARATOR.concat(path);
	}
}