package org.cg.services.core.util;

import io.swagger.jaxrs.Reader;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.models.Swagger;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.cg.services.core.osgi.Activator;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;

import com.google.common.base.Strings;

/**
 * Override setScan for BeanConfig so it supports services in multiple bundles
 * @author WZ
 *
 */
public class ServiceAwareBeanConfig extends BeanConfig {

	Reader reader = new Reader(new Swagger());

	@Override
	public void setScan(boolean shouldScan) {
		if (!Strings.isNullOrEmpty(getBasePath())) {
			// Set current class loader
			ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
			try {
				Set<Class<?>> classes = classes();
				if (classes != null) {
					reader.read(classes)
					.host(getHost())
					.basePath(getBasePath())
					.info(getInfo());
				}
				ServiceAwareScannerFactory.setScanner(getBasePath(), this);
			} finally {
				Thread.currentThread().setContextClassLoader(originalClassLoader);
			}
		}
	}

	@Override
	public Set<Class<?>> classes() {
		// Set current class loader
		JoinClassLoader loader = new JoinClassLoader(Thread.currentThread().getContextClassLoader(), getAllBundlesClassLoaders());
		Thread.currentThread().setContextClassLoader(loader);
		return super.classes();
	}

	private ClassLoader[] getAllBundlesClassLoaders() {
		List<ClassLoader> loaders = new ArrayList<>();
		Bundle[] bundles = Activator.getBundleContext().getBundles();
		for (Bundle bundle : bundles) {
			BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
			if (bundleWiring != null) {
				try {
					ClassLoader classLoader = bundleWiring.getClassLoader();
					if (classLoader != null) {
						loaders.add(classLoader);
					}
				} catch (ClassCastException e) {
					// Ignore as some bundles cannot get class loader
				}
			}
		}
		return loaders.toArray(new ClassLoader[loaders.size()]);
	}

}

@@ -691,134 +691,8 @@
 ) %7B%0A
-%09%09%09// Set current class loader%0A%09%09%09ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();%0A%09%09%09try %7B%0A%09
 %09%09%09S
@@ -725,17 +725,16 @@
 sses();%0A
-%09
 %09%09%09if (c
@@ -755,17 +755,16 @@
 ) %7B%0A%09%09%09%09
-%09
 reader.r
@@ -780,17 +780,16 @@
 es)%0A%09%09%09%09
-%09
 .host(ge
@@ -793,25 +793,24 @@
 (getHost())%0A
-%09
 %09%09%09%09.basePat
@@ -830,17 +830,16 @@
 ())%0A%09%09%09%09
-%09
 .info(ge
@@ -851,20 +851,18 @@
 ());%0A%09%09%09
-%09
 %7D%0A
-%09
 %09%09%09Servi
@@ -920,27 +920,98 @@
 s);%0A
+%0A
 %09%09
-%09%7D finally %7B%0A%09%09%09%09
+%7D%0A%09%7D%0A%0A%09@Override%0A%09public Set%3CClass%3C?%3E%3E classes() %7B%0A%09%09ClassLoader originalClassLoader = 
 Thre
@@ -1021,33 +1021,33 @@
 currentThread().
-s
+g
 etContextClassLo
@@ -1055,88 +1055,20 @@
 der(
-originalClassLoader);%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A%09@Override%0A%09public Set%3CClass%3C?%3E%3E classes()
+);%0A%09%09try
  %7B%0A
+%09
 %09%09//
@@ -1093,16 +1093,17 @@
  loader%0A
+%09
 %09%09JoinCl
@@ -1221,16 +1221,17 @@
 s());%0A%09%09
+%09
 Thread.c
@@ -1278,16 +1278,17 @@
 der);%0A%09%09
+%09
 return s
@@ -1303,16 +1303,104 @@
 sses();%0A
+%09%09%7D finally %7B%0A%09%09%09Thread.currentThread().setContextClassLoader(originalClassLoader);%0A%09%09%7D%0A
 %09%7D%0A%0A%09pri

reset class loader