You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2013/03/27 10:48:28 UTC

svn commit: r1461480 - in /stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl: ReferencedSiteComponent.java ReferencedSiteImpl.java

Author: rwesten
Date: Wed Mar 27 09:48:27 2013
New Revision: 1461480

URL: http://svn.apache.org/r1461480
Log:
STANBOL-998: Separated ReferencedSite (service) and ReferencedSiteComponent

Added:
    stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteComponent.java
Modified:
    stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteImpl.java

Added: stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteComponent.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteComponent.java?rev=1461480&view=auto
==============================================================================
--- stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteComponent.java (added)
+++ stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteComponent.java Wed Mar 27 09:48:27 2013
@@ -0,0 +1,593 @@
+package org.apache.stanbol.entityhub.core.impl;
+
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ACCESS_URI;
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.CACHE_ID;
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.CACHE_STRATEGY;
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ENTITY_DEREFERENCER_TYPE;
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ENTITY_SEARCHER_TYPE;
+import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.QUERY_URI;
+import static org.apache.stanbol.entityhub.servicesapi.site.Site.PROHIBITED_SITE_IDS;
+import static org.apache.stanbol.entityhub.servicesapi.site.SiteConfiguration.DEFAULT_SYMBOL_STATE;
+import static org.apache.stanbol.entityhub.servicesapi.site.SiteConfiguration.SITE_FIELD_MAPPINGS;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyOption;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.ReferenceStrategy;
+import org.apache.stanbol.commons.namespaceprefix.NamespacePrefixService;
+import org.apache.stanbol.commons.stanboltools.offline.OfflineMode;
+import org.apache.stanbol.entityhub.core.mapping.DefaultFieldMapperImpl;
+import org.apache.stanbol.entityhub.core.mapping.FieldMappingUtils;
+import org.apache.stanbol.entityhub.core.mapping.ValueConverterFactory;
+import org.apache.stanbol.entityhub.core.site.ReferencedSiteConfigurationImpl;
+import org.apache.stanbol.entityhub.core.utils.OsgiUtils;
+import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapper;
+import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapping;
+import org.apache.stanbol.entityhub.servicesapi.site.EntityDereferencer;
+import org.apache.stanbol.entityhub.servicesapi.site.EntitySearcher;
+import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration;
+import org.apache.stanbol.entityhub.servicesapi.site.Site;
+import org.apache.stanbol.entityhub.servicesapi.site.SiteConfiguration;
+import org.apache.stanbol.entityhub.servicesapi.yard.Cache;
+import org.apache.stanbol.entityhub.servicesapi.yard.CacheStrategy;
+import org.apache.stanbol.entityhub.servicesapi.yard.YardException;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OSGI component that reads the configuration and tracks other services required
+ * for the {@link ReferencedSiteImpl}. If all those services are available it
+ * registers the referenced {@link Site} as OSGI service
+ * @author Rupert Westenthaler
+ *
+ */
+@Component(name = "org.apache.stanbol.entityhub.site.referencedSite",
+    configurationFactory = true,
+    policy = ConfigurationPolicy.REQUIRE, // the baseUri is required!
+    specVersion = "1.1",
+    metatype = true,
+    immediate = true)
+@Properties(value = {
+    @Property(name = SiteConfiguration.ID),
+    @Property(name = SiteConfiguration.NAME),
+    @Property(name = SiteConfiguration.DESCRIPTION),
+    @Property(name = SiteConfiguration.ENTITY_PREFIX, cardinality = Integer.MAX_VALUE),
+    @Property(name = ACCESS_URI),
+    @Property(name = ENTITY_DEREFERENCER_TYPE,
+        options = {
+                @PropertyOption(value = '%' + ENTITY_DEREFERENCER_TYPE + ".option.none", name = ""),
+                @PropertyOption(value = '%' + ENTITY_DEREFERENCER_TYPE + ".option.sparql",
+                    name = "org.apache.stanbol.entityhub.dereferencer.SparqlDereferencer"),
+                @PropertyOption(value = '%' + ReferencedSiteConfiguration.ENTITY_DEREFERENCER_TYPE
+                        + ".option.coolUri",
+                    name = "org.apache.stanbol.entityhub.dereferencer.CoolUriDereferencer")},
+        value = "org.apache.stanbol.entityhub.dereferencer.SparqlDereferencer"),
+    @Property(name = QUERY_URI), // the deri server has better performance
+    @Property(name = ENTITY_SEARCHER_TYPE,
+        options = {
+                @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.none", name = ""),
+                @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql",
+                    name = "org.apache.stanbol.entityhub.searcher.SparqlSearcher"),
+                @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql-virtuoso",
+                    name = "org.apache.stanbol.entityhub.searcher.VirtuosoSearcher"),
+                @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql-larq",
+                    name = "org.apache.stanbol.entityhub.searcher.LarqSearcher")},
+        value = "org.apache.stanbol.entityhub.searcher.SparqlSearcher"),
+    @Property(name = DEFAULT_SYMBOL_STATE,
+        options = {
+                @PropertyOption(value = '%' + DEFAULT_SYMBOL_STATE + ".option.proposed",
+                    name = "proposed"),
+                @PropertyOption(value = '%' + DEFAULT_SYMBOL_STATE + ".option.active", name = "active")},
+        value = "proposed"),
+//deactivate rarely used properties in the configuration UI
+//    @Property(name = DEFAULT_MAPPING_STATE,
+//        options = {
+//                @PropertyOption(value = '%' + DEFAULT_MAPPING_STATE + ".option.proposed",
+//                    name = "proposed"),
+//                @PropertyOption(value = '%' + DEFAULT_MAPPING_STATE + ".option.confirmed",
+//                    name = "confirmed")}, value = "proposed"),
+//    @Property(name = DEFAULT_EXPIRE_DURATION,
+//        options = {
+//                @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.oneMonth", name = ""
+//                        + (1000L * 60 * 60 * 24 * 30)),
+//                @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.halfYear", name = ""
+//                        + (1000L * 60 * 60 * 24 * 183)),
+//                @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.oneYear", name = ""
+//                        + (1000L * 60 * 60 * 24 * 365)),
+//                @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.none", name = "0")},
+//        value = "0"),
+    @Property(name = CACHE_STRATEGY, options = {
+            @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.none", name = "none"),
+            @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.used", name = "used"),
+            @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.all", name = "all")}, value = "none"),
+    @Property(name = CACHE_ID), 
+    @Property(name = SITE_FIELD_MAPPINGS, cardinality = Integer.MAX_VALUE)})
+public class ReferencedSiteComponent {
+    
+    private static final Logger log = LoggerFactory.getLogger(ReferencedSiteComponent.class);
+
+    private ComponentContext cc;
+    private BundleContext bc;
+
+    private ReferencedSiteConfigurationImpl siteConfiguration;
+
+    private boolean dereferencerEqualsEntitySearcherComponent;
+    /**
+     * The {@link OfflineMode} is used by Stanbol to indicate that no external service should be referenced.
+     * For the ReferencedSiteImpl this means that the {@link EntityDereferencer} and {@link EntitySearcher}
+     * interfaces are no longer used.
+     * <p>
+     * 
+     * @see #enableOfflineMode(OfflineMode)
+     * @see #disableOfflineMode(OfflineMode)
+     * @see #isOfflineMode()
+     * @see #ensureOnline(String, Class)
+     */
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
+        policy = ReferencePolicy.DYNAMIC,
+        bind = "enableOfflineMode",
+        unbind = "disableOfflineMode",
+        strategy = ReferenceStrategy.EVENT)
+    private OfflineMode offlineMode;
+
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
+            policy = ReferencePolicy.DYNAMIC,
+            bind = "bindNamespacePrefixService",
+            unbind = "unbindNamespacePrefixService",
+            strategy = ReferenceStrategy.EVENT)
+    private NamespacePrefixService nsPrefixService;
+
+    private ServiceTracker cacheTracker;
+    private Cache cache;
+
+    private final Object searcherAndDereferencerLock = new Object();
+
+    private ComponentFactoryListener searcherComponentFactoryListener;
+
+    private ComponentFactoryListener dereferencerComponentFactoryListener;
+
+    private ComponentInstance dereferencerComponentInstance;
+
+    private ComponentInstance entitySearcherComponentInstance;
+    
+    private ServiceRegistration referencedSiteRegistration;
+    
+    private Site referencedSite;
+    
+    
+    protected void bindNamespacePrefixService(NamespacePrefixService ps){
+        this.nsPrefixService = ps;
+        updateServiceRegistration(bc, siteConfiguration, 
+            dereferencerComponentInstance, entitySearcherComponentInstance, 
+            cache, nsPrefixService, offlineMode);
+    }
+    
+    protected void unbindNamespacePrefixService(NamespacePrefixService ps){
+        if(ps.equals(this.nsPrefixService)){
+            this.nsPrefixService = null;
+            updateServiceRegistration(bc, siteConfiguration, 
+                dereferencerComponentInstance, entitySearcherComponentInstance, 
+                cache, nsPrefixService, offlineMode);
+        }
+    }
+    /**
+     * Called by the ConfigurationAdmin to bind the {@link #offlineMode} if the service becomes available
+     * 
+     * @param mode
+     */
+    protected final void enableOfflineMode(OfflineMode mode) {
+        this.offlineMode = mode;
+        updateServiceRegistration(bc, siteConfiguration, 
+            dereferencerComponentInstance, entitySearcherComponentInstance, 
+            cache, nsPrefixService, offlineMode);
+
+    }
+
+    /**
+     * Called by the ConfigurationAdmin to unbind the {@link #offlineMode} if the service becomes unavailable
+     * 
+     * @param mode
+     */
+    protected final void disableOfflineMode(OfflineMode mode) {
+        if(offlineMode != null){
+            this.offlineMode = null;
+            updateServiceRegistration(bc, siteConfiguration, 
+                dereferencerComponentInstance, entitySearcherComponentInstance, 
+                cache, nsPrefixService, offlineMode);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Activate
+    protected void activate(final ComponentContext ctx) throws ConfigurationException, YardException,
+            InvalidSyntaxException {
+        log.debug("in {} activate with properties {}", ReferencedSiteImpl.class.getSimpleName(),
+            ctx.getProperties());
+        if (ctx == null || ctx.getProperties() == null) {
+            throw new IllegalStateException(
+                    "No Component Context and/or Dictionary properties object parsed to the acticate methode");
+        }
+        this.cc = ctx;
+        this.bc = ctx.getBundleContext();
+        // create the SiteConfiguration based on the parsed properties
+        // NOTE that the constructor also validation of the parsed configuration
+        siteConfiguration = new ReferencedSiteConfigurationImpl(ctx.getProperties());
+        if (PROHIBITED_SITE_IDS.contains(siteConfiguration.getId().toLowerCase())) {
+            throw new ConfigurationException(SiteConfiguration.ID, String.format(
+                "The ID '%s' of this Referenced Site is one of the following "
+                        + "prohibited IDs: {} (case insensitive)", siteConfiguration.getId(),
+                PROHIBITED_SITE_IDS));
+        }
+        
+        log.info(" > initialise Referenced Site {}", siteConfiguration.getName());
+
+        // if the accessUri is the same as the queryUri and both the
+        // dereferencer and the entitySearcher uses the same component, than we 
+        //need only one component for both dependencies.
+        this.dereferencerEqualsEntitySearcherComponent =
+                // (1) accessURI == queryURI
+                siteConfiguration.getAccessUri() != null
+                && siteConfiguration.getAccessUri().equals(siteConfiguration.getQueryUri())
+                // (2) entity dereferencer == entity searcher
+                && siteConfiguration.getEntityDereferencerType() != null
+                && siteConfiguration.getEntityDereferencerType().equals(
+                    siteConfiguration.getEntitySearcherType());
+
+        // init the fieldMapper based on the configuration
+        FieldMapper fieldMappings = new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
+        if (siteConfiguration.getFieldMappings() != null) {
+            log.debug(" > Initialise configured field mappings");
+            for (String configuredMapping : siteConfiguration.getFieldMappings()) {
+                FieldMapping mapping =
+                        FieldMappingUtils.parseFieldMapping(configuredMapping, nsPrefixService);
+                if (mapping != null) {
+                    log.debug("   - add FieldMapping {}", mapping);
+                    fieldMappings.addMapping(mapping);
+                }
+            }
+        }
+        // now init the referenced Services
+        initDereferencerAndEntitySearcher();
+
+        // If a cache is configured init the ServiceTracker used to manage the
+        // Reference to the cache!
+        if (siteConfiguration.getCacheId() != null) {
+            String cacheFilter =
+                    String.format("(&(%s=%s)(%s=%s))", Constants.OBJECTCLASS, Cache.class.getName(),
+                        Cache.CACHE_YARD, siteConfiguration.getCacheId());
+            cacheTracker = new ServiceTracker(ctx.getBundleContext(), 
+                ctx.getBundleContext().createFilter( cacheFilter), 
+                new ServiceTrackerCustomizer() {
+                    
+                    @Override
+                    public void removedService(ServiceReference reference, Object service) {
+                        if(service.equals(cache)){
+                            cache = (Cache)cacheTracker.getService();
+                            updateServiceRegistration(bc, siteConfiguration, 
+                                dereferencerComponentInstance, entitySearcherComponentInstance, 
+                                cache, nsPrefixService, offlineMode);
+                        }
+                        bc.ungetService(reference);
+                    }
+                    
+                    @Override
+                    public void modifiedService(ServiceReference reference, Object service) {
+                        //the service.ranking might have changed ... so check if the
+                        //top ranked Cache is a different one
+                        Cache newCache = (Cache)cacheTracker.getService();
+                        if(newCache == null || !newCache.equals(cache)){
+                            cache = newCache; //set the new cahce
+                            //and update the service registration
+                            updateServiceRegistration(bc, siteConfiguration, 
+                                dereferencerComponentInstance, entitySearcherComponentInstance, 
+                                cache, nsPrefixService, offlineMode);
+                        }
+                    }
+                    
+                    @Override
+                    public Object addingService(ServiceReference reference) {
+                        Object service = bc.getService(reference);
+                        if(service != null){
+                            if(cacheTracker.getServiceReference() == null || //the first added Service or
+                                    //the new service as higher ranking as the current
+                                    (reference.compareTo(cacheTracker.getServiceReference()) > 0)){
+                                cache = (Cache)service;
+                                updateServiceRegistration(bc, siteConfiguration, 
+                                    dereferencerComponentInstance, entitySearcherComponentInstance, 
+                                    cache, nsPrefixService, offlineMode);
+                            } // else the new service has lower ranking as the currently use one
+                        } //else service == null -> ignore
+                        return service;
+                    }
+                });
+            cacheTracker.open();
+        }
+    }
+
+    /**
+     * Initialise the dereferencer and searcher component as soon as the according {@link ComponentFactory}
+     * gets registered.
+     * <p>
+     * First this Methods tries to find the according {@link ServiceReference}s directly. If they are not
+     * available (e.g. because the component factories are not yet started) than it adds a
+     * {@link ServiceListener} for the missing {@link ComponentFactory} that calls the
+     * {@link #createDereferencerComponent(ComponentFactory)} and
+     * {@link #createEntitySearcherComponent(ComponentFactory)} as soon as the factory gets registered.
+     * 
+     * @throws InvalidSyntaxException
+     *             if the #entitySearcherComponentName or the {@link #dereferencerComponentName} somehow cause
+     *             an invalid formated string that can not be used to parse a {@link Filter}.
+     */
+    private void initDereferencerAndEntitySearcher() throws InvalidSyntaxException {
+        if (siteConfiguration.getAccessUri() != null && // initialise only if a
+                                                        // accessUri
+                !siteConfiguration.getAccessUri().isEmpty() && // is configured
+                siteConfiguration.getEntitySearcherType() != null) {
+            String componentNameFilterString =
+                    String.format("(%s=%s)", "component.name", siteConfiguration.getEntitySearcherType());
+            String filterString =
+                    String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, ComponentFactory.class.getName(),
+                        componentNameFilterString);
+            ServiceReference[] refs =
+                    bc.getServiceReferences(ComponentFactory.class.getName(),
+                        componentNameFilterString);
+            if (refs != null && refs.length > 0) {
+                createEntitySearcherComponent((ComponentFactory) bc.getService(
+                    refs[0]));
+            } else { // service factory not yet available -> add servicelistener
+                this.searcherComponentFactoryListener =
+                        new ComponentFactoryListener(bc);
+                // NOTE: here the filter MUST include also the objectClass!
+                bc.addServiceListener(this.searcherComponentFactoryListener,
+                    filterString);
+            }
+            // context.getComponentInstance().dispose();
+            // throw an exception to avoid an successful activation
+        }
+        if (siteConfiguration.getQueryUri() != null
+                && // initialise only if a query URI
+                !siteConfiguration.getQueryUri().isEmpty()
+                && // is configured
+                siteConfiguration.getEntityDereferencerType() != null
+                && !this.dereferencerEqualsEntitySearcherComponent) {
+            String componentNameFilterString =
+                    String.format("(%s=%s)", "component.name", siteConfiguration.getEntityDereferencerType());
+            String filterString =
+                    String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, ComponentFactory.class.getName(),
+                        componentNameFilterString);
+            ServiceReference[] refs =
+                    bc.getServiceReferences(ComponentFactory.class.getName(),
+                        componentNameFilterString);
+            if (refs != null && refs.length > 0) {
+                createDereferencerComponent((ComponentFactory) bc.getService(refs[0]));
+            } else { // service factory not yet available -> add servicelistener
+                this.dereferencerComponentFactoryListener =
+                        new ComponentFactoryListener(bc);
+                this.bc.addServiceListener(this.dereferencerComponentFactoryListener,
+                    filterString); // NOTE: here the filter MUST
+                                   // include also the objectClass!
+            }
+        }
+    }
+
+    /**
+     * Creates the entity searcher component used by this {@link Site} (and configured via the
+     * {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} property).
+     * <p>
+     * If the {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} is set to the same vale and the
+     * {@link #accessUri} also equals the {@link #queryUri}, than the component created for the entity
+     * searcher is also used as dereferencer.
+     * 
+     * @param factory
+     *            The component factory used to create the {@link #entitySearcherComponentInstance}
+     */
+    @SuppressWarnings("unchecked")
+    protected void createEntitySearcherComponent(ComponentFactory factory) {
+        // both create*** methods sync on the searcherAndDereferencerLock to
+        // avoid
+        // multiple component instances because of concurrent calls
+        synchronized (searcherAndDereferencerLock) {
+            if (entitySearcherComponentInstance == null) {
+                entitySearcherComponentInstance =
+                        factory.newInstance(OsgiUtils.copyConfig(cc.getProperties()));
+                if(dereferencerEqualsEntitySearcherComponent){
+                    //use the same instance for dereferencer and entity searcher
+                    dereferencerComponentInstance = entitySearcherComponentInstance;
+                }
+                updateServiceRegistration(bc, siteConfiguration, 
+                    dereferencerComponentInstance, entitySearcherComponentInstance, 
+                    cache, nsPrefixService, offlineMode);
+            }
+        }
+    }
+
+    /**
+     * Creates the entity dereferencer component used by this {@link Site}. The implementation used as the
+     * dereferencer is configured by the {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} property.
+     * 
+     * @param factory
+     *            the component factory used to create the {@link #dereferencer}
+     */
+    @SuppressWarnings("unchecked")
+    protected void createDereferencerComponent(ComponentFactory factory) {
+        // both create*** methods sync on searcherAndDereferencerLock to avoid
+        // multiple component instances because of concurrent calls
+        synchronized (searcherAndDereferencerLock) {
+            if (dereferencerComponentInstance == null) {
+                dereferencerComponentInstance =
+                        factory.newInstance(OsgiUtils.copyConfig(cc.getProperties()));
+                updateServiceRegistration(bc, siteConfiguration, 
+                    dereferencerComponentInstance, entitySearcherComponentInstance, 
+                    cache, nsPrefixService, offlineMode);
+            }
+        }
+    }
+
+    /**
+     * Simple {@link ServiceListener} implementation that is used to get notified if one of the
+     * {@link ComponentFactory component factories} for the configured implementation of the
+     * {@link EntityDereferencer} or {@link EntitySearcher} interfaces get registered.
+     * 
+     * @author Rupert Westenthaler
+     * 
+     */
+    private class ComponentFactoryListener implements ServiceListener {
+        private BundleContext bundleContext;
+
+        protected ComponentFactoryListener(BundleContext bundleContext) {
+            if (bundleContext == null) {
+                throw new IllegalArgumentException("The BundleContext MUST NOT be NULL!");
+            }
+            this.bundleContext = bundleContext;
+        }
+
+        @Override
+        public void serviceChanged(ServiceEvent event) {
+            Object eventComponentName = event.getServiceReference().getProperty("component.name");
+            if (event.getType() == ServiceEvent.REGISTERED) {
+                log.info("Process ServiceEvent for ComponentFactory {} and State REGISTERED",
+                    eventComponentName);
+                ComponentFactory factory =
+                        (ComponentFactory) bundleContext.getService(event.getServiceReference());
+                if (siteConfiguration.getEntityDereferencerType() != null
+                        && siteConfiguration.getEntityDereferencerType().equals(eventComponentName)) {
+                    createDereferencerComponent(factory);
+                }
+                if (siteConfiguration.getEntitySearcherType() != null
+                        && siteConfiguration.getEntitySearcherType().equals(eventComponentName)) {
+                    createEntitySearcherComponent(factory);
+                }
+            } else {
+                log.info("Ignore ServiceEvent for ComponentFactory {} and state {}", eventComponentName,
+                    event.getType() == ServiceEvent.MODIFIED ? "MODIFIED"
+                            : event.getType() == ServiceEvent.UNREGISTERING ? "UNREGISTERING"
+                                    : "MODIFIED_ENDMATCH");
+            }
+        }
+
+    }
+
+    @Deactivate
+    protected void deactivate(ComponentContext context) {
+        log.info("deactivate Referenced Site {}", siteConfiguration.getName());
+        if (this.dereferencerComponentInstance != null) {
+            this.dereferencerComponentInstance.dispose();
+            this.dereferencerComponentInstance = null;
+        }
+        if (this.entitySearcherComponentInstance != null) {
+            this.entitySearcherComponentInstance.dispose();
+            this.entitySearcherComponentInstance = null;
+        }
+        if (searcherComponentFactoryListener != null) {
+            context.getBundleContext().removeServiceListener(searcherComponentFactoryListener);
+            searcherComponentFactoryListener = null;
+        }
+        if (dereferencerComponentFactoryListener != null) {
+            context.getBundleContext().removeServiceListener(dereferencerComponentFactoryListener);
+            dereferencerComponentFactoryListener = null;
+        }
+        cache = null;
+        if (cacheTracker != null) {
+            cacheTracker.close();
+            cacheTracker = null;
+        }
+        this.siteConfiguration = null;
+        this.bc = null;
+        this.cc = null;
+        referencedSite = null;
+        if(referencedSiteRegistration != null){
+            referencedSiteRegistration.unregister();
+            referencedSiteRegistration = null;
+        }
+    }
+    /**
+     * Updates the ServiceRegistration based on the parsed parameters
+     * @param bc
+     * @param config
+     */
+    @SuppressWarnings("unchecked")
+    private synchronized void updateServiceRegistration(BundleContext bc, 
+            ReferencedSiteConfiguration config, 
+            ComponentInstance dereferencerComponentInstance,
+            ComponentInstance searcherComponentInstance,
+            Cache cache, NamespacePrefixService nsPrefixService,
+            OfflineMode offlineMode){
+        log.debug("> update ReferencedSite service:");
+        if(referencedSiteRegistration != null){
+            log.debug("  - unregister ReferencedSite '{}'",referencedSite.getId());
+            referencedSiteRegistration.unregister();
+            referencedSiteRegistration = null;
+            referencedSite = null;
+        }
+        if(bc == null || config == null){
+            log.debug(" - not active ... return");
+            return;
+        }
+        //validate the parsed parameter
+        boolean valid = true; //use state so that we check all services for logging
+        log.debug(" - validate available services:");
+        if(config.getAccessUri() != null &&
+                config.getEntityDereferencerType() != null && 
+                dereferencerComponentInstance == null){
+            log.debug("    ... EntityDereference not available");
+            valid = false;
+        }
+        if(config.getQueryUri() != null &&
+                config.getEntitySearcherType() != null &&
+                searcherComponentInstance == null){
+            log.debug("    ... EntitySearcher not available");
+            valid = false;
+        }
+        if(config.getCacheStrategy() != CacheStrategy.none &&
+                cache == null){
+            log.debug("    ... Local Cache not available");
+            valid = false;
+        }
+        if(config.getCacheStrategy() != CacheStrategy.all &&
+                offlineMode != null){
+            log.debug("    ... Offline Mode is active and CacheStrategy != ALL");
+            valid = false;
+        }
+        if(valid){
+            log.debug("    ... all required Services present.");
+            log.info(" - register ReferencedSite '{}'",config.getId());
+            try {
+                referencedSite = new ReferencedSiteImpl(config,
+                    offlineMode != null ? null : 
+                        (EntityDereferencer)dereferencerComponentInstance.getInstance(),
+                    offlineMode != null ? null :
+                        (EntitySearcher)searcherComponentInstance.getInstance(),
+                    cache, nsPrefixService);
+                referencedSiteRegistration = bc.registerService(Site.class.getName(), referencedSite, 
+                    OsgiUtils.copyConfig(cc.getProperties()));
+            } catch (RuntimeException e) {
+                log.warn("  ... unable to initialise ReferencedSite.",e);
+            }
+        }
+    }
+
+    
+    
+    
+}

Modified: stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteImpl.java
URL: http://svn.apache.org/viewvc/stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteImpl.java?rev=1461480&r1=1461479&r2=1461480&view=diff
==============================================================================
--- stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteImpl.java (original)
+++ stanbol/trunk/entityhub/generic/core/src/main/java/org/apache/stanbol/entityhub/core/impl/ReferencedSiteImpl.java Wed Mar 27 09:48:27 2013
@@ -17,88 +17,39 @@
 package org.apache.stanbol.entityhub.core.impl;
 
 import static java.util.Collections.singletonMap;
-import static org.apache.stanbol.entityhub.core.utils.SiteUtils.extractSiteMetadata;
 import static org.apache.stanbol.entityhub.core.utils.SiteUtils.initEntityMetadata;
-import static org.apache.stanbol.entityhub.servicesapi.site.Site.PROHIBITED_SITE_IDS;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ACCESS_URI;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.CACHE_ID;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.CACHE_STRATEGY;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.DEFAULT_EXPIRE_DURATION;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.DEFAULT_MAPPING_STATE;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.DEFAULT_SYMBOL_STATE;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ENTITY_DEREFERENCER_TYPE;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.ENTITY_SEARCHER_TYPE;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.QUERY_URI;
-import static org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration.SITE_FIELD_MAPPINGS;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyOption;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferenceStrategy;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.stanbol.commons.namespaceprefix.NamespacePrefixService;
-import org.apache.stanbol.commons.stanboltools.offline.OfflineMode;
 import org.apache.stanbol.entityhub.core.mapping.DefaultFieldMapperImpl;
 import org.apache.stanbol.entityhub.core.mapping.FieldMappingUtils;
 import org.apache.stanbol.entityhub.core.mapping.ValueConverterFactory;
 import org.apache.stanbol.entityhub.core.model.EntityImpl;
-import org.apache.stanbol.entityhub.core.model.InMemoryValueFactory;
 import org.apache.stanbol.entityhub.core.query.DefaultQueryFactory;
 import org.apache.stanbol.entityhub.core.query.QueryResultListImpl;
-import org.apache.stanbol.entityhub.core.site.ReferencedSiteConfigurationImpl;
-import org.apache.stanbol.entityhub.core.utils.OsgiUtils;
-import org.apache.stanbol.entityhub.core.utils.SiteUtils;
-import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
 import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapper;
 import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapping;
-import org.apache.stanbol.entityhub.servicesapi.model.Representation;
 import org.apache.stanbol.entityhub.servicesapi.model.Entity;
-import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
 import org.apache.stanbol.entityhub.servicesapi.model.rdf.RdfResourceEnum;
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
 import org.apache.stanbol.entityhub.servicesapi.query.FieldQueryFactory;
 import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
 import org.apache.stanbol.entityhub.servicesapi.site.EntityDereferencer;
 import org.apache.stanbol.entityhub.servicesapi.site.EntitySearcher;
-import org.apache.stanbol.entityhub.servicesapi.site.License;
-import org.apache.stanbol.entityhub.servicesapi.site.Site;
 import org.apache.stanbol.entityhub.servicesapi.site.ReferencedSiteConfiguration;
-import org.apache.stanbol.entityhub.servicesapi.site.SiteException;
+import org.apache.stanbol.entityhub.servicesapi.site.Site;
 import org.apache.stanbol.entityhub.servicesapi.site.SiteConfiguration;
+import org.apache.stanbol.entityhub.servicesapi.site.SiteException;
 import org.apache.stanbol.entityhub.servicesapi.yard.Cache;
 import org.apache.stanbol.entityhub.servicesapi.yard.CacheStrategy;
 import org.apache.stanbol.entityhub.servicesapi.yard.Yard;
 import org.apache.stanbol.entityhub.servicesapi.yard.YardException;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.ComponentFactory;
-import org.osgi.service.component.ComponentInstance;
-import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -108,121 +59,39 @@ import org.slf4j.LoggerFactory;
  * (See the detailed description below).
  * <p>
  * Each {@link Site} with an {@link CacheStrategy} other than {@link CacheStrategy#none} needs an associated
- * {@link Cache}.
+ * {@link Cache} (actually a wrapper over a {@link Yard}).
  * <p>
- * The Initialisation of the sub-components:
+ * Referenced Components
  * <ul>
  * <li><b>{@link EntityDereferencer}:</b> Implementations of this interface are specific to the used
  * protocol/technology of the referenced site. Because of that calls to methods defined in this interface are
  * forwarded to an site specific instance of the {@link EntityDereferencer} interface as configured by the
  * {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} property.<br>
- * During activation the the {@link BundleContext} is used to search for {@link ComponentFactory} with the
- * configuration <code>
- *      "component.name= {@link ComponentContext#getProperties()}.get(
- *      {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE})</code>. This factory is used to create an instance
- * of {@link EntityDereferencer}. <br>
- * Note also, that the configuration of this instance that is covered by the {@link SiteConfiguration}
- * interface are parsed to the {@link EntityDereferencer} instance.
  * <li><b> {@link EntitySearcher}:</b> Implementations of this interface are also specific to the used
  * protocol/technology of the referenced site. Because of that calls to methods defined in this interface are
  * forwarded to an site specific instance of the {@link EntitySearcher} interface as configured by the
- * {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} property.<br>
- * The initialisation of this instance works similar as described for the {@link EntityDereferencer}. However
- * if the value of the {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} is equals to
- * {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} or the {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} is
- * not defined at all, than the Dereferencer Instance is also used as {@link EntitySearcher}. If the according
- * cast does not succeed, an {@link ConfigurationException} for the
- * {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} property is thrown.
+ * {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} property. Support for Search is optional. If no
+ * {@link EntitySearcher} is configured that all find** methods will throw {@link SiteException}s<br>n.
  * <li><b>{@link Cache}: </b> An instance of a {@link Cache} is used to cache {@link Representation}s loaded
  * form the Site. A cache is a wrapper over a {@link Yard} instance that allows to configure what data are
- * stored for each representation cached form this referenced site. A {@link ServiceTracker} is used for
- * managing the dependency with the cache. So if a cache is no longer available a referenced site can still be
- * used - only the local cache can not be used to retrieve entity representations.
+ * stored for each representation cached form this referenced site. In case of
+ * {@link CacheStrategy#all} the Cache is also used to search for Entities. Otherwise only
+ * dereferencing of Entities is done via the Cache.
  * </ul>
  * 
  * @author Rupert Westenthaler
  * 
  */
-@Component(name = "org.apache.stanbol.entityhub.site.referencedSite",
-    configurationFactory = true,
-    policy = ConfigurationPolicy.REQUIRE, // the baseUri is required!
-    specVersion = "1.1",
-    metatype = true,
-    immediate = true)
-@Service(value = Site.class)
-@Properties(value = {
-        @Property(name = SiteConfiguration.ID),
-        @Property(name = SiteConfiguration.NAME),
-        @Property(name = SiteConfiguration.DESCRIPTION),
-        @Property(name = SiteConfiguration.ENTITY_PREFIX, cardinality = 1000),
-        @Property(name = ACCESS_URI),
-        @Property(name = ENTITY_DEREFERENCER_TYPE,
-            options = {
-                    @PropertyOption(value = '%' + ENTITY_DEREFERENCER_TYPE + ".option.none", name = ""),
-                    @PropertyOption(value = '%' + ENTITY_DEREFERENCER_TYPE + ".option.sparql",
-                        name = "org.apache.stanbol.entityhub.dereferencer.SparqlDereferencer"),
-                    @PropertyOption(value = '%' + ReferencedSiteConfiguration.ENTITY_DEREFERENCER_TYPE
-                            + ".option.coolUri",
-                        name = "org.apache.stanbol.entityhub.dereferencer.CoolUriDereferencer")},
-            value = "org.apache.stanbol.entityhub.dereferencer.SparqlDereferencer"),
-        @Property(name = QUERY_URI), // the deri server has better performance
-        @Property(name = ENTITY_SEARCHER_TYPE,
-            options = {
-                    @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.none", name = ""),
-                    @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql",
-                        name = "org.apache.stanbol.entityhub.searcher.SparqlSearcher"),
-                    @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql-virtuoso",
-                        name = "org.apache.stanbol.entityhub.searcher.VirtuosoSearcher"),
-                    @PropertyOption(value = '%' + ENTITY_SEARCHER_TYPE + ".option.sparql-larq",
-                        name = "org.apache.stanbol.entityhub.searcher.LarqSearcher")},
-            value = "org.apache.stanbol.entityhub.searcher.SparqlSearcher"),
-        @Property(name = DEFAULT_SYMBOL_STATE,
-            options = {
-                    @PropertyOption(value = '%' + DEFAULT_SYMBOL_STATE + ".option.proposed",
-                        name = "proposed"),
-                    @PropertyOption(value = '%' + DEFAULT_SYMBOL_STATE + ".option.active", name = "active")},
-            value = "proposed"),
-        @Property(name = DEFAULT_MAPPING_STATE,
-            options = {
-                    @PropertyOption(value = '%' + DEFAULT_MAPPING_STATE + ".option.proposed",
-                        name = "proposed"),
-                    @PropertyOption(value = '%' + DEFAULT_MAPPING_STATE + ".option.confirmed",
-                        name = "confirmed")}, value = "proposed"),
-        @Property(name = DEFAULT_EXPIRE_DURATION,
-            options = {
-                    @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.oneMonth", name = ""
-                            + (1000L * 60 * 60 * 24 * 30)),
-                    @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.halfYear", name = ""
-                            + (1000L * 60 * 60 * 24 * 183)),
-                    @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.oneYear", name = ""
-                            + (1000L * 60 * 60 * 24 * 365)),
-                    @PropertyOption(value = '%' + DEFAULT_EXPIRE_DURATION + ".option.none", name = "0")},
-            value = "0"),
-        @Property(name = CACHE_STRATEGY, options = {
-                @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.none", name = "none"),
-                @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.used", name = "used"),
-                @PropertyOption(value = '%' + CACHE_STRATEGY + ".option.all", name = "all")}, value = "none"),
-        @Property(name = CACHE_ID), @Property(name = SITE_FIELD_MAPPINGS, cardinality = 1000)})
 public class ReferencedSiteImpl implements Site {
-    static final int maxInt = Integer.MAX_VALUE;
-    private final Logger log;
-    private ComponentContext context;
-    private FieldMapper fieldMappings;
+    private final Logger log = LoggerFactory.getLogger(ReferencedSiteImpl.class);
 
-    private final Object searcherAndDereferencerLock = new Object();
-    private Boolean dereferencerEqualsEntitySearcherComponent;
-    private ComponentFactoryListener dereferencerComponentFactoryListener;
-    private ComponentFactoryListener searcherComponentFactoryListener;
+    private FieldMapper fieldMappings;
 
-    // private String dereferencerComponentName;
-    private ComponentInstance dereferencerComponentInstance;
     private EntityDereferencer dereferencer;
 
-    // private String entitySearcherComponentName;
     private EntitySearcher entitySearcher;
-    private ComponentInstance entitySearcherComponentInstance;
 
-    private ServiceTracker cacheTracker;
+    private Cache cache;
 
     private ReferencedSiteConfiguration siteConfiguration;
     /**
@@ -230,34 +99,43 @@ public class ReferencedSiteImpl implemen
      */
     private Map<String,Object> siteMetadata;
 
-    /**
-     * The {@link OfflineMode} is used by Stanbol to indicate that no external service should be referenced.
-     * For the ReferencedSiteImpl this means that the {@link EntityDereferencer} and {@link EntitySearcher}
-     * interfaces are no longer used.
-     * <p>
-     * 
-     * @see #enableOfflineMode(OfflineMode)
-     * @see #disableOfflineMode(OfflineMode)
-     * @see #isOfflineMode()
-     * @see #ensureOnline(String, Class)
-     */
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
-        policy = ReferencePolicy.DYNAMIC,
-        bind = "enableOfflineMode",
-        unbind = "disableOfflineMode",
-        strategy = ReferenceStrategy.EVENT)
-    private OfflineMode offlineMode;
-
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
-    private NamespacePrefixService nsPrefixService;
-
-    public ReferencedSiteImpl() {
-        this(LoggerFactory.getLogger(ReferencedSiteImpl.class));
-    }
-
-    protected ReferencedSiteImpl(Logger log) {
-        this.log = log;
-        log.info("create instance of {}", this.getClass().getName());
+    public ReferencedSiteImpl(ReferencedSiteConfiguration config, 
+            EntityDereferencer dereferencer, EntitySearcher searcher,
+            Cache cache, NamespacePrefixService nsPrefixService) {
+        if(config == null){
+            throw new IllegalArgumentException("The parsed SiteConfiguration MUST NOT be NULL!");
+        }
+        if(config.getId() == null || config.getId().isEmpty()){
+            throw new IllegalArgumentException("The ReferencedSite ID (config#getId()) MUST NOT "
+                + "NULL nor empty!");
+        }
+        if(config.getCacheStrategy() != CacheStrategy.all &&
+                dereferencer == null){
+            throw new IllegalArgumentException("The EntityDerefernencer MUST NOT be NULL if "
+                + "CacheStrategy is NOT FULL (all entities in local Cache)!");
+        }
+        if(config.getCacheStrategy() != CacheStrategy.none && cache == null){
+            throw new IllegalArgumentException("The Cache MUST NOT be NULL if the "
+                + "CacheStrategy is set to an other value as NONE!");
+        }
+        this.siteConfiguration = config;
+        this.cache = cache;
+        this.dereferencer = dereferencer;
+        this.entitySearcher = searcher;
+        // init the fieldMapper based on the configuration
+        fieldMappings = new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
+        if (siteConfiguration.getFieldMappings() != null) {
+            log.debug(" > Initialise configured field mappings");
+            for (String configuredMapping : siteConfiguration.getFieldMappings()) {
+                FieldMapping mapping =
+                        FieldMappingUtils.parseFieldMapping(configuredMapping, nsPrefixService);
+                if (mapping != null) {
+                    log.debug("   - add FieldMapping {}", mapping);
+                    fieldMappings.addMapping(mapping);
+                }
+            }
+        }
+
     }
 
     public String getId() {
@@ -268,53 +146,35 @@ public class ReferencedSiteImpl implemen
     public QueryResultList<Entity> findEntities(FieldQuery query) throws SiteException {
         List<Entity> results;
         if (siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
-            // TODO: check if query can be executed based on the base
-            // configuration of the Cache
-            Cache cache = getCache();
-            if (cache != null) {
-                try {
-                    // When using the Cache, directly get the representations!
-                    QueryResultList<Representation> representations = cache.findRepresentation((query));
-                    results = new ArrayList<Entity>(representations.size());
-                    for (Representation result : representations) {
-                        Entity entity = new EntityImpl(getId(), result, null);
-                        results.add(entity);
-                        initEntityMetadata(entity, siteMetadata,
-                            singletonMap(RdfResourceEnum.isChached.getUri(), (Object) Boolean.TRUE));
-                    }
-                    return new QueryResultListImpl<Entity>(query, results, Entity.class);
-                } catch (YardException e) {
-                    if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                        throw new SiteException("Unable to execute query on Cache "
-                                + siteConfiguration.getCacheId(), e);
-                    } else {
-                        log.warn(
-                            String.format(
-                                "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
-                                siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
-                    }
+            try {
+                // When using the Cache, directly get the representations!
+                QueryResultList<Representation> representations = cache.findRepresentation((query));
+                results = new ArrayList<Entity>(representations.size());
+                for (Representation result : representations) {
+                    Entity entity = new EntityImpl(getId(), result, null);
+                    results.add(entity);
+                    initEntityMetadata(entity, siteMetadata,
+                        singletonMap(RdfResourceEnum.isChached.getUri(), (Object) Boolean.TRUE));
                 }
-            } else {
-                if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                    throw new SiteException(String.format(
-                        "Unable to execute query on Cache %s because it is currently not active",
-                        siteConfiguration.getCacheId()));
+                return new QueryResultListImpl<Entity>(query, results, Entity.class);
+            } catch (YardException e) {
+                if (entitySearcher == null) {
+                    throw new SiteException("Unable to execute query on Cache "
+                            + siteConfiguration.getCacheId(), e);
                 } else {
-                    log.warn(String.format(
-                        "Cache %s currently not active will query remote Site %s as fallback",
-                        siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()));
+                    log.warn(
+                        String.format(
+                            "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
+                            siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
                 }
             }
         }
         QueryResultList<String> entityIds;
         if (entitySearcher == null) {
-            throw new SiteException(String.format("EntitySearcher %s not available for remote site %s!",
-                siteConfiguration.getEntitySearcherType(), siteConfiguration.getQueryUri()));
+            throw new SiteException(String.format("The ReferencedSite %s does not support queries!",
+                getId()));
         }
-        ensureOnline(siteConfiguration.getQueryUri(), entitySearcher.getClass());
         try {
-            log.trace("Will use an entity-searcher [type :: {}][query-uri :: {}].", entitySearcher.getClass()
-                    .toString(), EntitySearcher.QUERY_URI);
             entityIds = entitySearcher.findEntities(query);
         } catch (IOException e) {
             throw new SiteException(String.format(
@@ -340,10 +200,9 @@ public class ReferencedSiteImpl implemen
             } catch (SiteException e) {
                 lastError = e;
                 errors++;
-                log.warn(String
-                        .format(
-                            "Unable to get Representation for Entity %s. -> %d Error%s for %d Entities in QueryResult (Reason:%s)",
-                            id, errors, errors > 1 ? "s" : "", entityIds.size(), e.getMessage()));
+                log.warn(String.format("Unable to get Representation for Entity "
+                    + "%s. -> %d Error%s for %d Entities in QueryResult (Reason:%s)",
+                    id, errors, errors > 1 ? "s" : "", entityIds.size(), e.getMessage()));
             }
             // decrease numResults because it is used as resultScore for
             // entities
@@ -351,9 +210,9 @@ public class ReferencedSiteImpl implemen
         }
         if (lastError != null) {
             if (entities.isEmpty()) {
-                throw new SiteException(
-                        "Unable to get anly Representations for Entities selected by the parsed Query (Root-Cause is the last Exception trown)",
-                        lastError);
+                throw new SiteException("Unable to get anly Representations for "
+                    + "Entities selected by the parsed Query (Root-Cause is the "
+                    + "last Exception trown)", lastError);
             } else {
                 log.warn(String.format("Unable to get %d/%d Represetnations for selected Entities.", errors,
                     entityIds.size()));
@@ -366,40 +225,25 @@ public class ReferencedSiteImpl implemen
     @Override
     public QueryResultList<Representation> find(FieldQuery query) throws SiteException {
         if (siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
-            // TODO: check if query can be executed based on the base
-            // configuration of the Cache
-            Cache cache = getCache();
-            if (cache != null) {
-                try {
-                    return cache.find(query);
-                } catch (YardException e) {
-                    if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                        throw new SiteException("Unable to execute query on Cache "
-                                + siteConfiguration.getCacheId(), e);
-                    } else {
-                        log.warn(
-                            String.format(
-                                "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
-                                siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
-                    }
-                }
-            } else {
-                if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                    throw new SiteException(String.format(
-                        "Unable to execute query because Cache %s is currently not active",
-                        siteConfiguration.getCacheId()));
+            try {
+                return cache.find(query);
+            } catch (YardException e) {
+                if (entitySearcher == null) {
+                    throw new SiteException("Unable to execute query on Cache "
+                            + siteConfiguration.getCacheId(), e);
                 } else {
-                    log.warn(String.format(
-                        "Cache %s currently not active will query remote Site %s as fallback",
-                        siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()));
+                    log.warn(
+                        String.format(
+                            "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
+                            siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
                 }
             }
         }
+        
         if (entitySearcher == null) {
-            throw new SiteException(String.format("EntitySearcher %s not available for remote site %s!",
-                siteConfiguration.getEntitySearcherType(), siteConfiguration.getQueryUri()));
+            throw new SiteException(String.format("ReferencedSite %s does not support queries!",
+                getId()));
         }
-        ensureOnline(siteConfiguration.getQueryUri(), entitySearcher.getClass());
         try {
             return entitySearcher.find(query);
         } catch (IOException e) {
@@ -411,40 +255,24 @@ public class ReferencedSiteImpl implemen
     @Override
     public QueryResultList<String> findReferences(FieldQuery query) throws SiteException {
         if (siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
-            // TODO: check if query can be executed based on the base
-            // configuration of the Cache
-            Cache cache = getCache();
-            if (cache != null) {
-                try {
-                    return cache.findReferences(query);
-                } catch (YardException e) {
-                    if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                        throw new SiteException("Unable to execute query on Cache "
-                                + siteConfiguration.getCacheId(), e);
-                    } else {
-                        log.warn(
-                            String.format(
-                                "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
-                                siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
-                    }
-                }
-            } else {
-                if (siteConfiguration.getEntitySearcherType() == null || isOfflineMode()) {
-                    throw new SiteException(String.format(
-                        "Unable to execute query on Cache %s because it is currently not active",
-                        siteConfiguration.getCacheId()));
+            try {
+                return cache.findReferences(query);
+            } catch (YardException e) {
+                if (entitySearcher == null) {
+                    throw new SiteException("Unable to execute query on Cache "
+                            + siteConfiguration.getCacheId(), e);
                 } else {
-                    log.warn(String.format(
-                        "Cache %s currently not active will query remote Site %s as fallback",
-                        siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()));
+                    log.warn(
+                        String.format(
+                            "Error while performing query on Cache %s! Try to use remote site %s as fallback!",
+                            siteConfiguration.getCacheId(), siteConfiguration.getQueryUri()), e);
                 }
             }
         }
         if (entitySearcher == null) {
-            throw new SiteException(String.format("EntitySearcher %s not available for remote site %s!",
-                siteConfiguration.getEntitySearcherType(), siteConfiguration.getQueryUri()));
+            throw new SiteException(String.format("The referencedSite %s dose not support queries!",
+                getId()));
         }
-        ensureOnline(siteConfiguration.getQueryUri(), entitySearcher.getClass());
         try {
             return entitySearcher.findEntities(query);
         } catch (IOException e) {
@@ -465,7 +293,6 @@ public class ReferencedSiteImpl implemen
             throw new SiteException(String.format("Dereferencer %s for remote site %s is not available",
                 siteConfiguration.getEntityDereferencerType(), siteConfiguration.getAccessUri()));
         }
-        ensureOnline(siteConfiguration.getAccessUri(), dereferencer.getClass());
         try {
             return dereferencer.dereference(id, contentType);
         } catch (IOException e) {
@@ -479,21 +306,21 @@ public class ReferencedSiteImpl implemen
 
     @Override
     public Entity getEntity(String id) throws SiteException {
-        Cache cache = getCache();
-        Entity entity = null;
+        Representation rep = null;
+        Boolean cachedVersion = Boolean.FALSE;
         long start = System.currentTimeMillis();
         if (cache != null) {
             try {
-                Representation rep = cache.getRepresentation(id);
-                if (rep != null) {
-                    entity = new EntityImpl(getId(), rep, null);
-                    initEntityMetadata(entity, siteMetadata,
-                        singletonMap(RdfResourceEnum.isChached.getUri(), (Object) Boolean.TRUE));
-                } else if (siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
-                    return null; // do no remote lokkups on CacheStrategy.all!!
+                rep = cache.getRepresentation(id);
+                if (rep == null){
+                    if(siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
+                        return null; // do no remote lookups on CacheStrategy.all!!
+                    }
+                } else {
+                    cachedVersion = Boolean.TRUE;
                 }
             } catch (YardException e) {
-                if (siteConfiguration.getEntityDereferencerType() == null || isOfflineMode()) {
+                if (dereferencer == null) {
                     throw new SiteException(String.format("Unable to get Represetnation %s form Cache %s",
                         id, siteConfiguration.getCacheId()), e);
                 } else {
@@ -503,25 +330,8 @@ public class ReferencedSiteImpl implemen
                             id, siteConfiguration.getCacheId(), siteConfiguration.getAccessUri()), e);
                 }
             }
-        } else {
-            if (siteConfiguration.getEntityDereferencerType() == null || isOfflineMode()) {
-                throw new SiteException(String.format(
-                    "Unable to get Represetnation %s because configured Cache %s is currently not available",
-                    id, siteConfiguration.getCacheId()));
-            } else {
-                log.warn(String.format(
-                    "Cache %s is currently not available. Will use remote site %s to load Representation %s",
-                    siteConfiguration.getCacheId(), siteConfiguration.getEntityDereferencerType(), id));
-            }
         }
-        if (entity == null) { // no cache or not found in cache
-            if (dereferencer == null) {
-                throw new SiteException(String.format(
-                    "Entity Dereferencer %s for accessing remote site %s is not available",
-                    siteConfiguration.getEntityDereferencerType(), siteConfiguration.getAccessUri()));
-            }
-            ensureOnline(siteConfiguration.getAccessUri(), dereferencer.getClass());
-            Representation rep = null;
+        if (rep == null && dereferencer != null) {
             try {
                 rep = dereferencer.dereference(id);
             } catch (IOException e) {
@@ -530,31 +340,29 @@ public class ReferencedSiteImpl implemen
                     id, siteConfiguration.getAccessUri(), siteConfiguration.getEntityDereferencerType()), e);
             }
             // representation loaded from remote site and cache is available
-            if (rep != null) {
-                Boolean cachedVersion = Boolean.FALSE;
-                if (cache != null) {// -> cache the representation
-                    try {
-                        start = System.currentTimeMillis();
-                        // return the the cached version
-                        rep = cache.store(rep);
-                        cachedVersion = Boolean.TRUE;
-                        log.debug("  - cached Representation {} in {} ms", id,
-                            (System.currentTimeMillis() - start));
-                    } catch (YardException e) {
-                        log.warn(String.format(
-                            "Unable to cache Represetnation %s in Cache %s! Representation not cached!", id,
-                            siteConfiguration.getCacheId()), e);
-                    }
+            if (rep != null && cache != null) {// -> cache the representation
+                try {
+                    start = System.currentTimeMillis();
+                    // return the the cached version
+                    rep = cache.store(rep);
+                    cachedVersion = Boolean.TRUE;
+                    log.debug("  - cached Representation {} in {} ms", id,
+                        (System.currentTimeMillis() - start));
+                } catch (YardException e) {
+                    log.warn(String.format(
+                        "Unable to cache Represetnation %s in Cache %s! Representation not cached!", id,
+                        siteConfiguration.getCacheId()), e);
                 }
-                entity = new EntityImpl(getId(), rep, null);
-                initEntityMetadata(entity, siteMetadata,
-                    singletonMap(RdfResourceEnum.isChached.getUri(), (Object) cachedVersion));
             }
+        }
+        if(rep != null){
+            Entity entity = new EntityImpl(getId(), rep, null);
+            initEntityMetadata(entity, siteMetadata,
+                singletonMap(RdfResourceEnum.isChached.getUri(), (Object) cachedVersion));
+            return entity;
         } else {
-            log.debug("  - loaded Representation {} from Cache in {} ms", id,
-                (System.currentTimeMillis() - start));
+            return null;
         }
-        return entity;
     }
 
     @Override
@@ -597,7 +405,6 @@ public class ReferencedSiteImpl implemen
     public FieldQueryFactory getQueryFactory() {
         FieldQueryFactory factory = null;
         if (siteConfiguration.getCacheStrategy() == CacheStrategy.all) {
-            Cache cache = getCache();
             if (cache != null) {
                 factory = cache.getQueryFactory();
             }
@@ -609,341 +416,11 @@ public class ReferencedSiteImpl implemen
     }
 
     public boolean supportsLocalMode() {
-        return siteConfiguration.getCacheStrategy() == CacheStrategy.all && getCache() != null;
+        return siteConfiguration.getCacheStrategy() == CacheStrategy.all && cache != null;
     }
 
     public boolean supportsSearch() {
         return supportsLocalMode() || entitySearcher != null;
     }
 
-    /**
-     * Internally used to get the Cache for this site. If {@link CacheStrategy#none}, this methods always
-     * returns <code>null</code> , otherwise it returns the Cache for the configured Yard or <code>null</code>
-     * if no such Cache is available.
-     * 
-     * @return the cache or <code>null</code> if {@link CacheStrategy#none} or the configured cache instance
-     *         is not available.
-     */
-    protected Cache getCache() {
-        if (siteConfiguration.getCacheStrategy() == CacheStrategy.none) {
-            return null;
-        } else {
-            Cache cache = (Cache) cacheTracker.getService();
-            if (cache != null && cache.isAvailable()) {
-                return cache;
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /*--------------------------------------------------------------------------
-     *  OSGI LIFECYCLE and LISTENER METHODS
-     *--------------------------------------------------------------------------
-     */
-
-    @SuppressWarnings("unchecked")
-    @Activate
-    protected void activate(final ComponentContext context) throws ConfigurationException, YardException,
-            InvalidSyntaxException {
-        log.debug("in {} activate with properties {}", ReferencedSiteImpl.class.getSimpleName(),
-            context.getProperties());
-        if (context == null || context.getProperties() == null) {
-            throw new IllegalStateException(
-                    "No Component Context and/or Dictionary properties object parsed to the acticate methode");
-        }
-        this.context = context;
-        // create the SiteConfiguration based on the parsed properties
-        // NOTE that the constructor also validation of the parsed configuration
-        siteConfiguration = new ReferencedSiteConfigurationImpl(context.getProperties());
-        if (PROHIBITED_SITE_IDS.contains(siteConfiguration.getId().toLowerCase())) {
-            throw new ConfigurationException(SiteConfiguration.ID, String.format(
-                "The ID '%s' of this Referenced Site is one of the following "
-                        + "prohibited IDs: {} (case insensitive)", siteConfiguration.getId(),
-                PROHIBITED_SITE_IDS));
-        }
-        log.info(" > initialise Referenced Site {}", siteConfiguration.getName());
-        this.siteMetadata = extractSiteMetadata(siteConfiguration, InMemoryValueFactory.getInstance());
-
-        // if the accessUri is the same as the queryUri and both the
-        // dereferencer and
-        // the entitySearcher uses the same component, than we need only one
-        // component
-        // for both dependencies.
-        this.dereferencerEqualsEntitySearcherComponent =
-        // (1) accessURI == queryURI
-                siteConfiguration.getAccessUri() != null
-                        && siteConfiguration.getAccessUri().equals(siteConfiguration.getQueryUri())
-                        &&
-                        // (2) entity dereferencer == entity searcher
-                        siteConfiguration.getEntityDereferencerType() != null
-                        && siteConfiguration.getEntityDereferencerType().equals(
-                            siteConfiguration.getEntitySearcherType());
-
-        // init the fieldMapper based on the configuration
-        fieldMappings = new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
-        if (siteConfiguration.getFieldMappings() != null) {
-            log.debug(" > Initialise configured field mappings");
-            for (String configuredMapping : siteConfiguration.getFieldMappings()) {
-                FieldMapping mapping =
-                        FieldMappingUtils.parseFieldMapping(configuredMapping, nsPrefixService);
-                if (mapping != null) {
-                    log.debug("   - add FieldMapping {}", mapping);
-                    fieldMappings.addMapping(mapping);
-                }
-            }
-        }
-        // now init the referenced Services
-        initDereferencerAndEntitySearcher();
-
-        // If a cache is configured init the ServiceTracker used to manage the
-        // Reference to the cache!
-        if (siteConfiguration.getCacheId() != null) {
-            String cacheFilter =
-                    String.format("(&(%s=%s)(%s=%s))", Constants.OBJECTCLASS, Cache.class.getName(),
-                        Cache.CACHE_YARD, siteConfiguration.getCacheId());
-            cacheTracker =
-                    new ServiceTracker(context.getBundleContext(), context.getBundleContext().createFilter(
-                        cacheFilter), null);
-            cacheTracker.open();
-        }
-    }
-
-    /**
-     * Initialise the dereferencer and searcher component as soon as the according {@link ComponentFactory}
-     * gets registered.
-     * <p>
-     * First this Methods tries to find the according {@link ServiceReference}s directly. If they are not
-     * available (e.g. because the component factories are not yet started) than it adds a
-     * {@link ServiceListener} for the missing {@link ComponentFactory} that calls the
-     * {@link #createDereferencerComponent(ComponentFactory)} and
-     * {@link #createEntitySearcherComponent(ComponentFactory)} as soon as the factory gets registered.
-     * 
-     * @throws InvalidSyntaxException
-     *             if the #entitySearcherComponentName or the {@link #dereferencerComponentName} somehow cause
-     *             an invalid formated string that can not be used to parse a {@link Filter}.
-     */
-    private void initDereferencerAndEntitySearcher() throws InvalidSyntaxException {
-        if (siteConfiguration.getAccessUri() != null && // initialise only if a
-                                                        // accessUri
-                !siteConfiguration.getAccessUri().isEmpty() && // is configured
-                siteConfiguration.getEntitySearcherType() != null) {
-            String componentNameFilterString =
-                    String.format("(%s=%s)", "component.name", siteConfiguration.getEntitySearcherType());
-            String filterString =
-                    String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, ComponentFactory.class.getName(),
-                        componentNameFilterString);
-            ServiceReference[] refs =
-                    context.getBundleContext().getServiceReferences(ComponentFactory.class.getName(),
-                        componentNameFilterString);
-            if (refs != null && refs.length > 0) {
-                createEntitySearcherComponent((ComponentFactory) context.getBundleContext().getService(
-                    refs[0]));
-            } else { // service factory not yet available -> add servicelistener
-                this.searcherComponentFactoryListener =
-                        new ComponentFactoryListener(context.getBundleContext());
-                // NOTE: here the filter MUST include also the objectClass!
-                context.getBundleContext().addServiceListener(this.searcherComponentFactoryListener,
-                    filterString);
-            }
-            // context.getComponentInstance().dispose();
-            // throw an exception to avoid an successful activation
-        }
-        if (siteConfiguration.getQueryUri() != null
-                && // initialise only if a query URI
-                !siteConfiguration.getQueryUri().isEmpty()
-                && // is configured
-                siteConfiguration.getEntityDereferencerType() != null
-                && !this.dereferencerEqualsEntitySearcherComponent) {
-            String componentNameFilterString =
-                    String.format("(%s=%s)", "component.name", siteConfiguration.getEntityDereferencerType());
-            String filterString =
-                    String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, ComponentFactory.class.getName(),
-                        componentNameFilterString);
-            ServiceReference[] refs =
-                    context.getBundleContext().getServiceReferences(ComponentFactory.class.getName(),
-                        componentNameFilterString);
-            if (refs != null && refs.length > 0) {
-                createDereferencerComponent((ComponentFactory) context.getBundleContext().getService(refs[0]));
-            } else { // service factory not yet available -> add servicelistener
-                this.dereferencerComponentFactoryListener =
-                        new ComponentFactoryListener(context.getBundleContext());
-                this.context.getBundleContext().addServiceListener(this.dereferencerComponentFactoryListener,
-                    filterString); // NOTE: here the filter MUST
-                                   // include also the objectClass!
-            }
-        }
-    }
-
-    /**
-     * Creates the entity searcher component used by this {@link Site} (and configured via the
-     * {@link SiteConfiguration#ENTITY_SEARCHER_TYPE} property).
-     * <p>
-     * If the {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} is set to the same vale and the
-     * {@link #accessUri} also equals the {@link #queryUri}, than the component created for the entity
-     * searcher is also used as dereferencer.
-     * 
-     * @param factory
-     *            The component factory used to create the {@link #entitySearcherComponentInstance}
-     */
-    @SuppressWarnings("unchecked")
-    protected void createEntitySearcherComponent(ComponentFactory factory) {
-        // both create*** methods sync on the searcherAndDereferencerLock to
-        // avoid
-        // multiple component instances because of concurrent calls
-        synchronized (this.searcherAndDereferencerLock) {
-            if (entitySearcherComponentInstance == null) {
-                this.entitySearcherComponentInstance =
-                        factory.newInstance(OsgiUtils.copyConfig(context.getProperties()));
-                this.entitySearcher = (EntitySearcher) entitySearcherComponentInstance.getInstance();
-            }
-            if (dereferencerEqualsEntitySearcherComponent) {
-                this.dereferencer = (EntityDereferencer) entitySearcher;
-            }
-        }
-    }
-
-    /**
-     * Creates the entity dereferencer component used by this {@link Site}. The implementation used as the
-     * dereferencer is configured by the {@link SiteConfiguration#ENTITY_DEREFERENCER_TYPE} property.
-     * 
-     * @param factory
-     *            the component factory used to create the {@link #dereferencer}
-     */
-    @SuppressWarnings("unchecked")
-    protected void createDereferencerComponent(ComponentFactory factory) {
-        // both create*** methods sync on searcherAndDereferencerLock to avoid
-        // multiple component instances because of concurrent calls
-        synchronized (this.searcherAndDereferencerLock) {
-            if (dereferencerComponentInstance == null) {
-                dereferencerComponentInstance =
-                        factory.newInstance(OsgiUtils.copyConfig(context.getProperties()));
-                this.dereferencer = (EntityDereferencer) dereferencerComponentInstance.getInstance();
-            }
-        }
-    }
-
-    /**
-     * Simple {@link ServiceListener} implementation that is used to get notified if one of the
-     * {@link ComponentFactory component factories} for the configured implementation of the
-     * {@link EntityDereferencer} or {@link EntitySearcher} interfaces get registered.
-     * 
-     * @author Rupert Westenthaler
-     * 
-     */
-    private class ComponentFactoryListener implements ServiceListener {
-        private BundleContext bundleContext;
-
-        protected ComponentFactoryListener(BundleContext bundleContext) {
-            if (bundleContext == null) {
-                throw new IllegalArgumentException("The BundleContext MUST NOT be NULL!");
-            }
-            this.bundleContext = bundleContext;
-        }
-
-        @Override
-        public void serviceChanged(ServiceEvent event) {
-            Object eventComponentName = event.getServiceReference().getProperty("component.name");
-            if (event.getType() == ServiceEvent.REGISTERED) {
-                log.info("Process ServiceEvent for ComponentFactory {} and State REGISTERED",
-                    eventComponentName);
-                ComponentFactory factory =
-                        (ComponentFactory) bundleContext.getService(event.getServiceReference());
-                if (siteConfiguration.getEntityDereferencerType() != null
-                        && siteConfiguration.getEntityDereferencerType().equals(eventComponentName)) {
-                    createDereferencerComponent(factory);
-                }
-                if (siteConfiguration.getEntitySearcherType() != null
-                        && siteConfiguration.getEntitySearcherType().equals(eventComponentName)) {
-                    createEntitySearcherComponent(factory);
-                }
-            } else {
-                log.info("Ignore ServiceEvent for ComponentFactory {} and state {}", eventComponentName,
-                    event.getType() == ServiceEvent.MODIFIED ? "MODIFIED"
-                            : event.getType() == ServiceEvent.UNREGISTERING ? "UNREGISTERING"
-                                    : "MODIFIED_ENDMATCH");
-            }
-        }
-
-    }
-
-    @Deactivate
-    protected void deactivate(ComponentContext context) {
-        log.info("deactivate Referenced Site {}", siteConfiguration.getName());
-        this.dereferencer = null;
-        if (this.dereferencerComponentInstance != null) {
-            this.dereferencerComponentInstance.dispose();
-            this.dereferencerComponentInstance = null;
-        }
-        this.entitySearcher = null;
-        if (this.entitySearcherComponentInstance != null) {
-            this.entitySearcherComponentInstance.dispose();
-            this.entitySearcherComponentInstance = null;
-        }
-        if (searcherComponentFactoryListener != null) {
-            context.getBundleContext().removeServiceListener(searcherComponentFactoryListener);
-            searcherComponentFactoryListener = null;
-        }
-        if (dereferencerComponentFactoryListener != null) {
-            context.getBundleContext().removeServiceListener(dereferencerComponentFactoryListener);
-            dereferencerComponentFactoryListener = null;
-        }
-        if (cacheTracker != null) {
-            cacheTracker.close();
-            cacheTracker = null;
-        }
-        this.fieldMappings = null;
-        this.context = null;
-        this.siteConfiguration = null;
-    }
-
-    /*
-     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Method for handling the
-     * OfflineMode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-     */
-
-    /**
-     * Called by the ConfigurationAdmin to bind the {@link #offlineMode} if the service becomes available
-     * 
-     * @param mode
-     */
-    protected final void enableOfflineMode(OfflineMode mode) {
-        this.offlineMode = mode;
-    }
-
-    /**
-     * Called by the ConfigurationAdmin to unbind the {@link #offlineMode} if the service becomes unavailable
-     * 
-     * @param mode
-     */
-    protected final void disableOfflineMode(OfflineMode mode) {
-        this.offlineMode = null;
-    }
-
-    /**
-     * Returns <code>true</code> only if Stanbol operates in {@link OfflineMode} .
-     * 
-     * @return the offline state
-     */
-    protected final boolean isOfflineMode() {
-        return offlineMode != null;
-    }
-
-    /**
-     * Basically this Method throws an {@link SiteException} in case Stanbol operates in offline mode
-     * 
-     * @param uri
-     *            the URI of the remote service
-     * @param clazz
-     *            the clazz of the service that would like to refer the remote service
-     * @throws SiteException
-     *             in case {@link #isOfflineMode()} returns <code>true</code>
-     */
-    private void ensureOnline(String uri, Class<?> clazz) throws SiteException {
-        if (isOfflineMode()) {
-            throw new SiteException(String.format(
-                "Unable to access remote Service %s by using %s because Stanbol runs in OfflineMode", uri,
-                clazz.getSimpleName()));
-        }
-    }
 }