/*
 * Copyright 2013 Harald Wellmann
 *
 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 * you may not use  this file  except in  compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed  under the  License is distributed on an "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 * implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
package org.ops4j.pax.web.service.spi.util;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import org.apache.commons.collections4.map.LRUMap;
import org.ops4j.pax.swissbox.core.BundleClassLoader;
import org.osgi.framework.Bundle;

/**
 * A bundle class loader which delegates resource loading to a list of delegate
 * bundles.
 * 
 * @author Harald Wellmann
 */
public class ResourceDelegatingBundleClassLoader extends BundleClassLoader {

	private List<Bundle> bundles;

	private int cacheSize = 100; //equals the default size of the LRUMap, might be changed in a later version.

	private static ThreadLocal<LRUMap<String, Enumeration<URL>>> lruCache = new ThreadLocal<LRUMap<String, Enumeration<URL>>>();

	public ResourceDelegatingBundleClassLoader(List<Bundle> bundles) {
		super(bundles.get(0));
		this.bundles = bundles;
	}

	public ResourceDelegatingBundleClassLoader(List<Bundle> bundles, ClassLoader parent) {
		super(bundles.get(0), parent);
		this.bundles = bundles;
	}

	public void addBundle(Bundle bundle) {
		bundles.add(bundle);
	}

	public List<Bundle> getBundles() {
		return bundles;
	}

	protected URL findResource(String name) {
		for (Bundle delegate : bundles) {
			try {
				URL resource = delegate.getResource(name);
				if (resource != null) {
					return resource;
				}
			} catch (IllegalStateException exc) {
				// ignore
			}
		}
		return null;
	}

	@Override
	protected Enumeration<URL> findResources(String name) throws IOException {
		Enumeration<URL> url = getFromCache(name);
		if (url != null) {
			return url;
		} else {

			Vector<URL> resources = new Vector<URL>();

			for (Bundle delegate : bundles) {
				try {
					Enumeration<URL> urls = delegate.getResources(name);
					if (urls != null) {
						while (urls.hasMoreElements()) {
							resources.add(urls.nextElement());
						}
					}
				} catch (IllegalStateException exc) {
					// ignore
				}
			}

			url = resources.elements();
			addToCache(name, url);
			return url;
		}
	}

	protected void addToCache(String name, Enumeration<URL> urls) {
		if (lruCache.get() == null) {
			lruCache.set(new LRUMap<String, Enumeration<URL>>(cacheSize));
		}

		lruCache.get().put(name, urls);
	}

	protected Enumeration<URL> getFromCache(String name) {
		Enumeration<URL> url = null;
		if (lruCache.get() != null) {
			url = lruCache.get().get(name);
		}

		return url;
	}
}
@@ -1286,27 +1286,8 @@
 ate 
-static ThreadLocal%3C
 LRUM
@@ -1297,34 +1297,28 @@
 String, 
-Enumeration
+Vector
 %3CURL%3E%3E
-%3E
  lruCach
@@ -1329,54 +1329,26 @@
 new 
-ThreadLocal%3CLRUMap%3CString, Enumeration%3CURL%3E%3E%3E(
+LRUMap%3C%3E(cacheSize
 );%0A%0A
@@ -1684,16 +1684,36 @@
 undle);%0A
+%09%09lruCache.clear();%0A
 %09%7D%0A%0A%09pub
@@ -2129,36 +2129,37 @@
 ion %7B%0A%09%09
-Enumeration%3CURL%3E url
+Vector%3CURL%3E resources
  = getFr
@@ -2177,19 +2177,26 @@
 e);%0A
+%0A
 %09%09if (
-url !
+resources =
 = nu
@@ -2208,47 +2208,8 @@
 %0A%09%09%09
-return url;%0A%09%09%7D else %7B%0A%0A%09%09%09Vector%3CURL%3E 
 reso
@@ -2231,17 +2231,13 @@
 tor%3C
-URL
 %3E();%0A
-%0A
 %09%09%09f
@@ -2530,256 +2530,144 @@
 %09%09%7D%0A
-%0A%09%09%09url = resources.elements();%0A%09%09%09addToCache(name, url);%0A%09%09%09return url;%0A%09%09%7D%0A%09%7D%0A%0A%09protected void addToCache(String name, Enumeration%3CURL%3E urls) %7B%0A%09%09if (lruCache.get() == null) %7B%0A%09%09%09lruCache.set(new LRUMap%3CString, Enumeration%3CURL%3E%3E(cacheSize));%0A%09%09%7D%0A
+%09%09%09addToCache(name, resources);%0A%09%09%7D%0A%0A%09%09return resources.elements();%0A%09%7D%0A%0A%09protected void addToCache(String name, Vector%3CURL%3E resources) %7B
 %0A%09%09l
@@ -2674,22 +2674,16 @@
 ruCache.
-get().
 put(name
@@ -2684,19 +2684,24 @@
 t(name, 
-url
+resource
 s);%0A%09%7D%0A%0A
@@ -2707,35 +2707,30 @@
 %0A%09protected 
-Enumeration
+Vector
 %3CURL%3E getFro
@@ -2757,121 +2757,33 @@
 %7B%0A%09%09
-Enumeration%3CURL%3E url = null;%0A%09%09if (lruCache.get() != null) %7B%0A%09%09%09url = lruCache.get().get(name);%0A%09%09%7D%0A%0A%09%09return url
+return lruCache.get(name)
 ;%0A%09%7D

Fix problem with the cache