package org.gcube.common.scope.impl; import java.net.URL; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import org.gcube.common.scope.api.ServiceMap; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Scans the classpath for {@link ServiceMap}s. * * @author Fabio Simeoni * */ class ServiceMapScanner { private static Logger log = LoggerFactory.getLogger(ServiceMapScanner.class); /** * The path used to find service map configuration files. */ static final String mapConfigPattern = ".*\\.servicemap"; /** * Scans the classpath for {@link ServiceMap}s. */ static Map maps() { log.info("scanning form maps"); Map maps = new HashMap(); try { Collection urls = ClasspathHelper.forJavaClassPath(); ConfigurationBuilder reflectionConf = new ConfigurationBuilder().addUrls(ClasspathHelper.forJavaClassPath()).addUrls(ClasspathHelper.forClassLoader()).setScanners(new ResourcesScanner()); Reflections reflection = new Reflections(reflectionConf); JAXBContext context = JAXBContext.newInstance(DefaultServiceMap.class); Set resources = reflection.getResources(Pattern.compile(".*\\.servicemap")); log.info("loading {} ", resources); Unmarshaller um = context.createUnmarshaller(); for (String resource: resources) { log.info("loading {} ", resource); URL url = Thread.currentThread().getContextClassLoader().getResource(resource); DefaultServiceMap map = (DefaultServiceMap) um.unmarshal(url); ServiceMap current = maps.get(map.scope()); if (current != null && current.version() != null) if (current.version().compareToIgnoreCase(map.version()) == 1) { log.warn("discarding {} because older (v.{}) than one previously loaded (v.{}) for {} ", new Object[] { url, map.version(), current.version(), map.scope() }); continue; } else log.info("overwriting older map (v.{}) with newer map (v.{}) for {} ", new Object[] { current.version(), map.version(), map.scope() }); maps.put(map.scope(), map); } } catch (Throwable e) { log.error("errror scanning service amps",e); throw new RuntimeException("could not load service maps", e); } return maps; } }