All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.uniroma2.art.coda.osgi.bundle.OSGiAwareAbstractComponentProvider Maven / Gradle / Ivy

There is a newer version: 1.8.1
Show newest version
package it.uniroma2.art.coda.osgi.bundle;

import it.uniroma2.art.coda.provisioning.ComponentProvider;
import it.uniroma2.art.coda.provisioning.ComponentProvisioningException;
import it.uniroma2.art.owlart.filter.StatementWithAnyOfGivenComponents_Predicate;
import it.uniroma2.art.owlart.model.ARTNode;
import it.uniroma2.art.owlart.model.ARTStatement;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.model.NodeFilters;
import it.uniroma2.art.owlart.models.LinkedDataResolver;
import it.uniroma2.art.owlart.models.OWLArtModelFactory;
import it.uniroma2.art.owlart.navigation.ARTNodeIterator;
import it.uniroma2.art.owlart.sesame2impl.factory.ARTModelFactorySesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.models.conf.Sesame2ModelConfiguration;
import it.uniroma2.art.owlart.utilities.RDFIterators;
import it.uniroma2.art.owlart.vocabulary.VocabUtilities;

import java.io.File;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.felix.bundlerepository.RepositoryAdmin;
import org.apache.felix.bundlerepository.Requirement;
import org.apache.felix.bundlerepository.Resolver;
import org.apache.felix.bundlerepository.Resource;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Collections2;

public abstract class OSGiAwareAbstractComponentProvider implements ComponentProvider {
	private static final Logger logger = LoggerFactory.getLogger(ComponentProvider.class);

	private BundleContext hostBundleContext;

	private Map serviceReferencesMap;
	private Map serviceObjectsMap;

	//private File tempDir;

	private ServiceTracker convertersTracker;

	public OSGiAwareAbstractComponentProvider(BundleContext hostBundleContext) throws Exception {
		this.hostBundleContext = hostBundleContext;
		//this.tempDir = tempDir;

		this.serviceReferencesMap = new HashMap();
		this.serviceObjectsMap = new HashMap();

		this.convertersTracker = new ServiceTracker(hostBundleContext,
				hostBundleContext.createFilter("(it.uniroma2.art.coda.contract=*)"), null);
		this.convertersTracker.open();

	}

	@Override
	public void close() {
		this.convertersTracker.close();

		// for (ServiceReference sr : serviceReferencesMap.values()) {
		// this.hostBundleContext.ungetService(sr);
		// }
	}

	@Override
	public Object lookup(String contract) throws ComponentProvisioningException {

		// Uses an already provisioned converter, if any
		Object service = serviceObjectsMap.get(contract);

		if (service != null) {
			return service;
		}

		// Looks-up the service registry for a suitable converter, if any
		service = lookupServiceRegistry(contract);

		if (service != null) {
			return service;
		}

		// Attempts to locate a suitable bundle in the known OBR repositories
		RepositoryAdmin repoAdmin = getRepositoryAdmin();

		Requirement req = repoAdmin.getHelper().requirement("service",
				String.format("(it.uniroma2.art.coda.contract=%s)", contract));
		Resource[] candidateResources = repoAdmin.discoverResources(new Requirement[] { req });

		// If no candidate is found, attempts to discover a new OBR repository
		if (candidateResources.length == 0) {
			try {
				discover(contract);
			} catch (Exception e) {
				throw new ComponentProvisioningException(e);
			}
			candidateResources = repoAdmin.discoverResources(new Requirement[] { req });
			if (candidateResources.length == 0) {
				throw new ComponentProvisioningException(
						"No converter has been found that matches the contract: " + contract);
			}
		}

		// Always choose the first candidate
		int chosen = 0;

		Resource chosenResource = candidateResources[0];

		Resolver resolver = repoAdmin.resolver();
		resolver.add(chosenResource);

		boolean success = resolver.resolve();

		if (!success) {
			throw new ComponentProvisioningException("Cannot resolve the bundle: " + chosenResource
					+ " providing a converter for contract: " + contract);
		}

		resolver.deploy(Resolver.START);
		logger.info("deploying: " + chosenResource);

		for (int i = 0; i < 5; i++) {

			service = lookupServiceRegistry(contract);
			if (service != null) {
				return service;
			}

			try {
				Thread.sleep((i + 1) * 500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}

		throw new ComponentProvisioningException("Cannot get the service");

	}

	private Object lookupServiceRegistry(String contract) {

		for (ServiceReference sr : atLeastEmpty(ServiceReference.class,
				convertersTracker.getServiceReferences())) {
			if (contract.equals(sr.getProperty("it.uniroma2.art.coda.contract"))) {
				return convertersTracker.getService(sr);
			}
		}

		return null;
	}

	private static  T[] atLeastEmpty(Class clazz, T[] array) {
		if (array == null) {
			return (T[]) Array.newInstance(clazz, 0);
		}

		return array;
	}

	private void discover(String contract) throws Exception {
		logger.info("discover({})", contract);
		ARTModelFactorySesame2Impl factImpl = new ARTModelFactorySesame2Impl();
		OWLArtModelFactory fact = OWLArtModelFactory.createModelFactory(factImpl);

		LinkedDataResolver ldResolver = fact.loadLinkedDataResolver();

		ARTURIResource contractResource = VocabUtilities.nodeFactory.createURIResource(contract);
		
		Collection contractDescription;
		
		try {
			contractDescription = ldResolver.lookup(contractResource);
		} catch (Exception e) {
			logger.debug("Linked data resolver throwed an exception", e);
			return;
		}
		
		ARTNodeIterator authoritativeRepoIt = RDFIterators.listObjects(RDFIterators.createARTStatementIterator(Collections2.filter(contractDescription, StatementWithAnyOfGivenComponents_Predicate.getFilter(
				contractResource, VocabUtilities.nodeFactory
						.createURIResource("http://art.uniroma2.it/coda/ns/authoritativeOBR"),
				NodeFilters.ANY)).iterator()));

		RepositoryAdmin repoAdmin = getRepositoryAdmin();
		
		while (authoritativeRepoIt.streamOpen()) {
			ARTNode authRepo = authoritativeRepoIt.getNext();
			
			if (authRepo.isURIResource()) {
				repoAdmin.addRepository(authRepo.asURIResource().getURI());
				logger.info("adding repository: " + authRepo.asURIResource().getURI());
			}
		}
		authoritativeRepoIt.close();
	}
	
	protected abstract RepositoryAdmin getRepositoryAdmin() throws ComponentProvisioningException;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy