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 2014/02/24 06:23:28 UTC

svn commit: r1571150 - in /stanbol/branches/release-0.12/enhancement-engines/dereference: core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/ entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/

Author: rwesten
Date: Mon Feb 24 05:23:28 2014
New Revision: 1571150

URL: http://svn.apache.org/r1571150
Log:
Implementation of STANBOL-1287 for 0.12.1. NOTE: This is also a first test case for EnhancementProperties in 0.12 (STANBOL-1280) what turned out to be much easier to implement as for 1.0.0 (STANBOL-488).

Added:
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConfigurationException.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContextFactory.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceContext.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/ParseBackend.java
Modified:
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConstants.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContext.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceEngineConfig.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/EntityDereferenceEngine.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceEngine.java
    stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/TrackingDereferencerBase.java

Added: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConfigurationException.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConfigurationException.java?rev=1571150&view=auto
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConfigurationException.java (added)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConfigurationException.java Mon Feb 24 05:23:28 2014
@@ -0,0 +1,45 @@
+package org.apache.stanbol.enhancer.engines.dereference;
+
+/**
+ * Exception thrown if the parsed dereference configuration is not valid.
+ * Messages should indicate the {@link DereferenceContext} field as well as
+ * the Dereferencer implementation
+ * @author Rupert Westenthaler
+ *
+ */
+public class DereferenceConfigurationException extends IllegalArgumentException {
+
+    private static final long serialVersionUID = 1431844013656980310L;
+    private final Class<? extends EntityDereferencer> dereferencer;
+    private final String property;
+
+    
+    public DereferenceConfigurationException(String reason, 
+            Class<? extends EntityDereferencer> dereferencer, String property){
+        this(reason, null, dereferencer, property);
+    }
+    
+    public DereferenceConfigurationException(Throwable cause, 
+            Class<? extends EntityDereferencer> dereferencer, String property){
+        this(null, cause, dereferencer, property);
+    }
+    
+    public DereferenceConfigurationException(String reason, Throwable cause, 
+            Class<? extends EntityDereferencer> dereferencer, String property){
+        super(new StringBuilder("IllegalConfiguration for ")
+        .append(dereferencer == null ? "Dereferencer <unkown>" : dereferencer.getClass().getSimpleName())
+        .append(" and property '").append(property == null ? "<unknwon>" : property)
+        .append("': ").append(reason != null ? reason : "").toString(), cause);
+        this.dereferencer = dereferencer;
+        this.property = property;
+    }
+    
+    public Class<? extends EntityDereferencer> getDereferencer() {
+        return dereferencer;
+    }
+    
+    public String getProperty() {
+        return property;
+    }
+    
+}

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConstants.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConstants.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConstants.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceConstants.java Mon Feb 24 05:23:28 2014
@@ -107,7 +107,20 @@ public interface DereferenceConstants {
      * enhancement results.
      */
     String FALLBACK_MODE = "enhancer.engines.dereference.fallback";
-    
+    /**
+     * By default {@link #FALLBACK_MODE} is enabled
+     */
     boolean DEFAULT_FALLBACK_MODE = true;
     
+    /**
+     * Parameter allowing users to define a list of languages to be dereferenced.
+     * An empty string is used for literals that do not have an language tag.
+     */
+    String DEREFERENCE_ENTITIES_LANGUAGES = "enhancer.engines.dereference.languages";
+    
+    /**
+     * Language key used for configuring literals without language tag
+     */
+    String NO_LANGUAGE_KEY = "none";
+    
 }

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContext.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContext.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContext.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContext.java Mon Feb 24 05:23:28 2014
@@ -16,56 +16,295 @@
  */
 package org.apache.stanbol.enhancer.engines.dereference;
 
+import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.DEREFERENCE_ENTITIES_LANGUAGES;
+import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.NO_LANGUAGE_KEY;
+
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
 
-import org.apache.clerezza.rdf.core.Language;
+import org.apache.commons.lang.StringUtils;
 import org.apache.stanbol.commons.stanboltools.offline.OfflineMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DereferenceContext {
 
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    
+    protected final static String INTERNAL_CONTENT_LANGUAGES = "internal.dereference.contentlanguages";
+    protected final static String INTERNAL_ACCEPT_LANGUAGES = "internal.dereference.acceptlanguages";
+    
+    protected final EntityDereferenceEngine engine;
+    
+    protected final Map<String,Object> enhancementProps;
     /**
      * The {@link OfflineMode} status
      */
-    protected final boolean offlineMode;
+    private boolean offlineMode;
     /** 
-     * Read-only set with languages that need to be dereferenced.
+     * Read-only set with literal languages defined in the context.
      */
-    private Set<String> languages = new HashSet<String>();
+    private Set<String> contextLanguages;
+    /**
+     * Read-only set with literal languages to be dereferenced. This is the
+     * union over {@link #contextLanguages} and {@link #getConfig()}.
+     * {@link DereferenceEngineConfig#getLanaguages() getLanaguages()}
+     */
+    private Set<String> languages;
+    private List<String> fields;
+    private String program;
+    
+    
     
     /**
      * Create a new DereferenceContext.
      * @param offlineMode the {@link OfflineMode} state
+     * @param ep The enhancement properties
+     * @throws DereferenceConfigurationException if the parsed enhancement
+     * propertied contain an invalid configuration
      */
-    protected DereferenceContext(boolean offlineMode){
-        this.offlineMode = offlineMode;
+    @SuppressWarnings("unchecked")
+    protected DereferenceContext(EntityDereferenceEngine engine, Map<String,Object> ep)
+            throws DereferenceConfigurationException {
+        this.engine = engine;
+        this.enhancementProps = ep;
+        parseLanguages(ep == null ? null : ep.get(DEREFERENCE_ENTITIES_LANGUAGES),
+            ep == null ? null : (Collection<String>)ep.get(INTERNAL_CONTENT_LANGUAGES),
+            ep == null ? null : (Collection<String>)ep.get(INTERNAL_ACCEPT_LANGUAGES));
+        parseFields(ep == null ? null : ep.get(DereferenceConstants.DEREFERENCE_ENTITIES_FIELDS));
+        parseLDPath(ep == null ? null : ep.get(DereferenceConstants.DEREFERENCE_ENTITIES_LDPATH));
+        //call the initialisation callback
+        initialise();
     }
+    /**
+     * Parses the {@link DereferenceConstants#DEREFERENCE_ENTITIES_LANGUAGES}
+     * from the parsed value, merges content- and accept-languages and finally 
+     * calls {@link #initLiteralLanguages(Set)} with the resulting set
+     * @param value the value of the 
+     * {@link DereferenceConstants#DEREFERENCE_ENTITIES_LANGUAGES} key
+     * @param the content languages or <code>null</code> if 
+     * {@link DereferenceConstants#FILTER_CONTENT_LANGUAGES} is deactivated
+     * @param the accept languages or <code>null</code> if
+     * {@link DereferenceConstants#FILTER_ACCEPT_LANGUAGES} is deactivated
+     * @throws DereferenceConfigurationException if the parsed value is not a
+     * valid configuration
+     */
+    private void parseLanguages(Object value, Collection<String> contentLanguages, 
+            Collection<String> acceptLanguages) throws DereferenceConfigurationException {
+        Set<String> languages;
+        if(value == null){
+            languages = null;
+        } else {
+            languages = new HashSet<String>();
+            if(value instanceof String){
+                String lang = (String) value;
+                addLanguage(languages, lang);
+            } else if(value instanceof Collection<?>){
+                for(Object lang : (Collection<?>)value){
+                    if(lang instanceof String){
+                        addLanguage(languages, (String)lang);
+                    }
+                }           
+            }
+            if(languages.isEmpty()){
+                languages = null;
+            }
+        }
+        if(contentLanguages != null && !contentLanguages.isEmpty()){
+            if(languages == null){
+                languages = new HashSet<String>();
+            }
+            languages.addAll(contentLanguages);
+        }
+        if(acceptLanguages != null && !acceptLanguages.isEmpty()){
+            if(languages == null){
+                languages = new HashSet<String>();
+            }
+            languages.addAll(acceptLanguages);
+        }
+        //set the contextLanguages field
+        if(languages == null){
+            this.contextLanguages = Collections.emptySet();
+        } else {
+            this.contextLanguages = Collections.unmodifiableSet(languages);
+        }
+        //merge the languages with those of the config and set the languages field
+        Set<String> merged;
+        Collection<String> configLangs = getConfig().getLanaguages();
+        if(languages == null && configLangs == null){
+            merged = null;
+        } else if(configLangs == null){
+            merged = languages;
+        } else {
+            merged = new HashSet<String>(configLangs);
+            if(languages != null){
+                merged.addAll(languages);
+            }
+        }
+        this.languages = merged;
 
+    }
     /**
-     * If the {@link OfflineMode} is active
-     * @return the offline mode status
+     * Parsed the language from the language string and adds it to the languages
+     * set. This will convert languages to lower case and also converts empty
+     * values as well as the {@link DereferenceConstants#NO_LANGUAGE_KEY} to 
+     * <code>null</code> (indicating labels without any language) 
+     * @param languages
+     * @param lang
      */
-    public boolean isOfflineMode() {
-        return offlineMode;
+    private void addLanguage(Set<String> languages, String lang) {
+        if(StringUtils.isBlank(lang) || NO_LANGUAGE_KEY.equalsIgnoreCase(lang)){
+            languages.add(null);
+        } else {
+            languages.add(lang.toLowerCase(Locale.ROOT));
+        }
     }
+
     /**
-     * Setter for the languages of literals that should be dereferenced
-     * @param languages the ContentLanguages
+     * Parsed the {@link DereferenceConstants#DEREFERENCE_ENTITIES_FIELDS}
+     * from the parsed value and calls {@link #initDereferencedFields(List)} with 
+     * the parsed value
+     * @param value the value
+     * @throws DereferenceConfigurationException if the parsed value is not a
+     * valid configuration
      */
-    protected void setLanguages(Set<String> languages) {
-        if(languages == null){
-            this.languages = Collections.emptySet();
+    private void parseFields(Object value) throws DereferenceConfigurationException{
+        List<String> fields;
+        if(value instanceof String && !StringUtils.isBlank((String)value)){
+            fields = Collections.singletonList((String)value);
+        } else if(value instanceof Collection<?>){
+            fields = new ArrayList<String>(((Collection<?>)value).size());
+            for(Object field : (Collection<?>)value){
+                if(field != null && field instanceof String && 
+                        !StringUtils.isBlank((String)field)){
+                    fields.add((String)field);
+                } // else ignore
+            }           
         } else {
-            this.languages = Collections.unmodifiableSet(languages);
+            fields = null;
         }
+        this.fields  = fields;
+    }
+    
+    /**
+     * Parsed the {@link DereferenceConstants#DEREFERENCE_ENTITIES_LDPATH}
+     * from the parsed value and calls {@link #initLdPathProgram(String)} with 
+     * the parsed value
+     * @param value the value
+     * @throws DereferenceConfigurationException if the parsed value is not a
+     * valid configuration
+     */
+    private void parseLDPath(Object value) throws DereferenceConfigurationException {
+        String program;
+        if(value instanceof String && !StringUtils.isBlank((String)value)){
+            program = (String)value;
+        } else if(value instanceof Collection<?>){
+            StringBuilder sb = new StringBuilder();
+            for(Object field : (Collection<?>)value){
+                if(field != null && field instanceof String && 
+                        !StringUtils.isBlank((String)field)){
+                    sb.append((String)field).append('\n');
+                } // else ignore
+            }
+            program = sb.length() > 0 ? sb.toString() : null;
+        } else {
+            program = null;
+        }
+        this.program = program;
+    }
+    
+    /**
+     * Allows to set the offline mode state
+     */
+    protected final void setOfflineMode(boolean state){
+        this.offlineMode = state;
+    }
+    
+    /**
+     * If the {@link OfflineMode} is active. If active Dereferencers are not
+     * allowed access remote resources for dereferencing Entities.
+     * @return the offline mode status
+     */
+    public final boolean isOfflineMode() {
+        return offlineMode;
+    }
+            
+    /**
+     * Context specific DerefernecedField configuration
+     * @return the context specific DereferencedField configuration or
+     * <code>null</code> if none
+     */
+    public final List<String> getFields() {
+        return fields;
+    }
+    
+    /**
+     * Initialisation callback for the DereferenceContext. This is called by
+     * the constructor after the {@link #enhancementProps} are set and
+     * {@link #getLanguages()}, {@link #getFields()} and 
+     * {@link #getLdPathProgram()} are initialised.<p>
+     * The default implementation is empty.
+     */
+    protected void initialise(){
+        
     }
     /**
+     * Context specific LDPath program
+     * @return the context specific LDPath program or <code>null</code> if none
+     */
+    public final String getLdPathProgram() {
+        return program;
+    }
+    
+    /**
      * Getter for the languages that should be dereferenced. If 
-     * empty all languages should be included.
+     * empty all languages should be included. This is the union over
+     * Languages enabled in the context and 
+     * {@link #getConfig()}.{@link DereferenceEngineConfig#getLanaguages()
+     * getLanaguages()}
      * @return the languages for literals that should be dereferenced.
      */
-    public Set<String> getLanguages() {
+    public final Set<String> getLanguages() {
         return languages;
     }
+    
+    /**
+     * Set of languages enabled via the context. This does not include languages
+     * enabled in the {@link DereferenceEngineConfig}
+     * @return the set of languages enabled via the context. 
+     */
+    protected final Set<String> getContextLanguages(){
+        return contextLanguages;
+    }
+    
+    /**
+     * Getter for the Enhancement Properties for this Context.
+     * @return the Enhancement Properties
+     */
+    protected final Map<String,Object> getEnhancementProps() {
+        return enhancementProps;
+    }
+    
+    /**
+     * Getter for the Dereference Engine Configuration
+     * @return the dereference configuration
+     */
+    public final DereferenceEngineConfig getConfig() {
+        return engine.getConfig();
+    }
+    
+    /**
+     * The EntityDereferencer this context is built for
+     * @return the entity dereferencer
+     */
+    public final EntityDereferencer getDereferencer(){
+        return engine.getDereferencer();
+    }
+    
 }

Added: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContextFactory.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContextFactory.java?rev=1571150&view=auto
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContextFactory.java (added)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceContextFactory.java Mon Feb 24 05:23:28 2014
@@ -0,0 +1,26 @@
+package org.apache.stanbol.enhancer.engines.dereference;
+
+import java.util.Map;
+
+/**
+ * Factory used by the {@link EntityDereferenceEngine} to create
+ * {@link DereferenceContext} instances for enhancement requests.
+ * @author Rupert Westenthaler
+ *
+ */
+public interface DereferenceContextFactory {
+
+    /**
+     * Creates a Dereference Context for the given DereferenceEngine configuration
+     * and the request specific enhancement properties
+     * @param engine the engine the context is built for
+     * @param enhancementProperties the request specific enhancement properties
+     * @return the dereference context
+     * @throws DereferenceConfigurationException if the request specific configuration
+     * is invalid or not supported.
+     */
+    DereferenceContext createContext(EntityDereferenceEngine engine, 
+            Map<String,Object> enhancementProperties) 
+                    throws DereferenceConfigurationException;
+    
+}

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceEngineConfig.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceEngineConfig.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceEngineConfig.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/DereferenceEngineConfig.java Mon Feb 24 05:23:28 2014
@@ -16,16 +16,18 @@
  */
 package org.apache.stanbol.enhancer.engines.dereference;
 
-import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.DEREFERENCE_ENTITIES_FIELDS;
-import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.DEREFERENCE_ENTITIES_LDPATH;
+import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.NO_LANGUAGE_KEY;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Locale;
+import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementEngine;
@@ -269,4 +271,51 @@ public class DereferenceEngineConfig imp
     	}
     	return values;
 	}
+	/**
+	 * Getter for Literal languages that should be dereferenced.
+	 * @return
+	 */
+	public Collection<String> getLanaguages(){
+	    Object value = config.get(DEREFERENCE_ENTITIES_LANGUAGES);
+	    if(value == null){
+	        return null;
+	    } else {
+            Set<String> languages = new HashSet<String>();
+            if(value instanceof String){
+                addLanguage(languages, (String)value);
+            } else if(value instanceof String[]){
+                for(String lang : (String[])value){
+                    addLanguage(languages, lang);
+                }
+            } else if(value instanceof Collection<?>){
+                for(Object lang : (Collection<?>)value){
+                    if(lang instanceof String){
+                        addLanguage(languages, (String)lang);
+                    }
+                }           
+            }
+            if(languages.isEmpty()){
+                return null;
+            } else {
+                return languages;
+            }
+	    }
+	}
+	
+    /**
+     * Parses a language from the parsed languate string and adds it to the
+     * parsed languages set. This converts languages to lower case and also
+     * checks for the {@link DereferenceConstants#NO_LANGUAGE_KEY} value.
+     * @param languages the set holding the languages
+     * @param lang the language
+     */
+    private void addLanguage(Set<String> languages, String lang) {
+        if(!StringUtils.isBlank(lang)){
+            if(NO_LANGUAGE_KEY.equalsIgnoreCase(lang)){
+                languages.add(null);
+            } else {
+                languages.add(lang.toLowerCase(Locale.ROOT));
+            }
+        }
+    }
 }

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/EntityDereferenceEngine.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/EntityDereferenceEngine.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/EntityDereferenceEngine.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/core/src/main/java/org/apache/stanbol/enhancer/engines/dereference/EntityDereferenceEngine.java Mon Feb 24 05:23:28 2014
@@ -16,7 +16,6 @@
  */
 package org.apache.stanbol.enhancer.engines.dereference;
 
-import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.URI_PATTERN;
 import static org.apache.stanbol.enhancer.servicesapi.rdf.Properties.DC_LANGUAGE;
 import static org.apache.stanbol.enhancer.servicesapi.rdf.Properties.ENHANCER_ENTITY_REFERENCE;
 
@@ -37,20 +36,18 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-import org.apache.clerezza.rdf.core.Language;
 import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.NonLiteral;
 import org.apache.clerezza.rdf.core.Resource;
 import org.apache.clerezza.rdf.core.Triple;
 import org.apache.clerezza.rdf.core.UriRef;
-import org.apache.commons.lang.StringUtils;
 import org.apache.stanbol.commons.stanboltools.offline.OfflineMode;
 import org.apache.stanbol.enhancer.servicesapi.ContentItem;
 import org.apache.stanbol.enhancer.servicesapi.EngineException;
 import org.apache.stanbol.enhancer.servicesapi.EnhancementEngine;
+import org.apache.stanbol.enhancer.servicesapi.EnhancementPropertyException;
 import org.apache.stanbol.enhancer.servicesapi.ServiceProperties;
 import org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper;
-import org.apache.stanbol.enhancer.servicesapi.rdf.Properties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,6 +69,8 @@ public class EntityDereferenceEngine imp
     
     protected final DereferenceEngineConfig config;
     
+    protected final DereferenceContextFactory contextFactory;
+    
     protected final String name;
     
     protected final boolean filterContentLanguages;
@@ -96,6 +95,10 @@ public class EntityDereferenceEngine imp
     private final Map<String,Object> unmodServiceProperties = Collections.unmodifiableMap(serviceProperties);
     
     public EntityDereferenceEngine(EntityDereferencer dereferencer, DereferenceEngineConfig config){
+        this(dereferencer,config,null);
+    }
+    public EntityDereferenceEngine(EntityDereferencer dereferencer, DereferenceEngineConfig config,
+            DereferenceContextFactory contextFactory){
         if(config == null){
             throw new IllegalArgumentException("The parsed DereferenceEngineConfig MUST NOT be NULL!");
         }
@@ -110,6 +113,7 @@ public class EntityDereferenceEngine imp
             throw new IllegalArgumentException("The parsed EntityDereferencer MUST NOT be NULL!");
         }
         this.dereferencer = dereferencer;
+        this.contextFactory = contextFactory != null ? contextFactory : new ContextFactory();
         log.debug(" - dereferenced {} (type: {})", dereferencer, dereferencer.getClass().getName());
         //init the default ordering
         this.fallbackMode = config.isFallbackMode();
@@ -156,11 +160,11 @@ public class EntityDereferenceEngine imp
      * of this Engine implementation
      * @param mode the offline mode
      */
-    public void setOfflineMode(boolean mode){
+    public final void setOfflineMode(boolean mode){
         this.offline = mode;
     }
     
-    public boolean isOfflineMode(){
+    public final boolean isOfflineMode(){
         return offline;
     }
     /**
@@ -169,12 +173,12 @@ public class EntityDereferenceEngine imp
      * @param ordering The ordering or <code>null</code> to set the 
      * {@value #DEFAULT_ENGINE_ORDERING default} for this engine.
      */
-    public void setEngineOrdering(Integer ordering){
+    public final void setEngineOrdering(Integer ordering){
         serviceProperties.put(ServiceProperties.ENHANCEMENT_ENGINE_ORDERING, 
             ordering == null ? DEFAULT_ENGINE_ORDERING : ordering);
     }
     
-    public Integer getEngineOrdering(){
+    public final Integer getEngineOrdering(){
         return (Integer)serviceProperties.get(ENHANCEMENT_ENGINE_ORDERING);
     }
 
@@ -182,17 +186,21 @@ public class EntityDereferenceEngine imp
      * Getter for the config of this engine
      * @return the Dereference Engine Configuration
      */
-    public DereferenceEngineConfig getConfig() {
+    public final DereferenceEngineConfig getConfig() {
         return config;
     }
     
+    public final EntityDereferencer getDereferencer(){
+        return dereferencer;
+    }
+    
     @Override
-    public Map<String,Object> getServiceProperties() {
+    public final Map<String,Object> getServiceProperties() {
         return unmodServiceProperties;
     }
 
     @Override
-    public int canEnhance(ContentItem ci) throws EngineException {
+    public final int canEnhance(ContentItem ci) throws EngineException {
         if(offline && !dereferencer.supportsOfflineMode()){
             return CANNOT_ENHANCE;
         } else {
@@ -201,28 +209,47 @@ public class EntityDereferenceEngine imp
     }
 
     @Override
-    public void computeEnhancements(ContentItem ci) throws EngineException {
+    public final void computeEnhancements(ContentItem ci) throws EngineException {
         if(offline && !dereferencer.supportsOfflineMode()){
             //entity dereferencer does no longer support offline mode
             return;
         }
         log.debug("> dereference Entities for ContentItem {}", ci.getUri());
         long start = System.nanoTime();
-        final DereferenceContext derefContext = new DereferenceContext(offline);
-        Set<String> includedLangs = new HashSet<String>();
-        //TODO: parse accept languages as soon as Enhancement properties are implemented
+        Map<String,Object> enhancemntProps = EnhancementEngineHelper.getEnhancementProperties(this, ci);
+        final DereferenceContext derefContext;
         final MGraph metadata = ci.getMetadata();
         Set<UriRef> referencedEntities = new HashSet<UriRef>();
-        //(1) read all Entities we need to dereference from the parsed contentItem
         ci.getLock().readLock().lock();
         try {
-            //parse the languages detected for the content
+            //(1) Create the DereferenceContext
             if(filterContentLanguages){
+                //parse the languages detected for the content
+                Set<String> contentLanguages = new HashSet<String>();
                 for(NonLiteral langAnno : EnhancementEngineHelper.getLanguageAnnotations(metadata)){
-                    includedLangs.add(EnhancementEngineHelper.getString(metadata, langAnno, DC_LANGUAGE));
+                    contentLanguages.add(EnhancementEngineHelper.getString(metadata, langAnno, DC_LANGUAGE));
                 }
+                enhancemntProps.put(DereferenceContext.INTERNAL_CONTENT_LANGUAGES, contentLanguages);
             } //no content language filtering - leave contentLanguages empty
+            
+            //TODO: parse accept languages as soon as Request headers are available
+            //      via Enhancement properties
+            
+            //create the dereference context and handle possible configuration exceptions
+            try {
+                derefContext = contextFactory.createContext(this, enhancemntProps);
+                derefContext.setOfflineMode(offline);
+            } catch (DereferenceConfigurationException e){
+                StringBuilder message = new StringBuilder("Unsupported Derefernece Configuarion ");
+                if(e.getProperty() != null){
+                    message.append("for property '").append(e.getProperty()).append("' ");
+                }
+                message.append(" parsed via the EnhancementProperties of this request!");
+                throw new EnhancementPropertyException(this, ci, e.getProperty(), message.toString(), e);
+            }
+            
             //parse the referenced entities from the graph
+            //(2) read all Entities we need to dereference from the parsed contentItem
             Set<UriRef> checked = new HashSet<UriRef>();
             Iterator<Triple> entityReferences = metadata.filter(null, ENHANCER_ENTITY_REFERENCE, null);
             while(entityReferences.hasNext()){
@@ -244,11 +271,6 @@ public class EntityDereferenceEngine imp
             ci.getLock().readLock().unlock();
         }
         long schedule = System.nanoTime();
-        if(!includedLangs.isEmpty()){
-            includedLangs.add(null); //also include literals without language
-            //and set the list to the dereference context
-            derefContext.setLanguages(includedLangs);
-        } //else no filterLanguages set ... nothing to do
 
         final Lock writeLock = ci.getLock().writeLock();
         log.trace(" - scheduled {} Entities for dereferencing", 
@@ -402,12 +424,28 @@ public class EntityDereferenceEngine imp
     	return false; //no match
     }
     
+    /**
+     * {@link DereferenceContextFactory} implementation used if <code>null</code>
+     * is parsed as factory.
+     * 
+     * @author Rupert Westenthaler
+     */
+    class ContextFactory implements DereferenceContextFactory {
+
+        @Override
+        public DereferenceContext createContext(EntityDereferenceEngine engine, 
+                Map<String,Object> enhancementProperties) {
+            return new DereferenceContext(engine, enhancementProperties);
+        }
+        
+    }
+
     
     /**
      * Used both as {@link Callable} submitted to the {@link ExecutorService}
      * and as object to {@link #await()} the completion of the task.
+     * 
      * @author Rupert Westenthaler
-     *
      */
     class DereferenceJob implements Callable<Boolean> {
         

Added: stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceContext.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceContext.java?rev=1571150&view=auto
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceContext.java (added)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceContext.java Mon Feb 24 05:23:28 2014
@@ -0,0 +1,187 @@
+package org.apache.stanbol.enhancer.engines.dereference.entityhub;
+
+import static org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants.DEREFERENCE_ENTITIES_LDPATH;
+
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceConfigurationException;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceContext;
+import org.apache.stanbol.enhancer.engines.dereference.EntityDereferenceEngine;
+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.ldpath.EntityhubLDPath;
+import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapper;
+import org.apache.stanbol.entityhub.servicesapi.mapping.FieldMapping;
+import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.newmedialab.ldpath.api.backend.RDFBackend;
+import at.newmedialab.ldpath.exception.LDPathParseException;
+import at.newmedialab.ldpath.model.programs.Program;
+
+public class EntityhubDereferenceContext extends DereferenceContext {
+    
+    private FieldMapper fieldMapper;
+    private Program<Object> ldpathProgram;
+    
+    protected EntityhubDereferenceContext(EntityDereferenceEngine engine, 
+            Map<String,Object> enhancementProps) throws DereferenceConfigurationException {
+        super(engine, enhancementProps);
+    }
+
+    @Override
+    protected void initialise() throws DereferenceConfigurationException {
+        initFieldMappings(getFields());
+        initLdPath(getLdPathProgram());
+    }
+
+    protected void initFieldMappings(List<String> fields) throws DereferenceConfigurationException {
+        TrackingDereferencerBase<?> dereferencer = getEntityhubDereferencer();
+        FieldMapper fieldMapper;
+        if(fields != null && !fields.isEmpty()){
+            log.debug("parse FieldMappings from EnhancementProperties");
+            List<FieldMapping> mappings = new ArrayList<FieldMapping>(fields.size());
+            for(String configuredMapping : fields){
+                FieldMapping mapping = FieldMappingUtils.parseFieldMapping(configuredMapping,
+                    dereferencer.getNsPrefixService());
+                if(mapping != null){
+                    log.debug("   - add FieldMapping {}",mapping);
+                    mappings.add(mapping);
+                } else if(configuredMapping != null && !configuredMapping.isEmpty()){
+                    log.warn("   - unable to parse FieldMapping '{}'", configuredMapping);
+                }
+            }
+            if(!mappings.isEmpty()){
+                log.debug(" > apply {} valid mappings",mappings.size());
+                fieldMapper = new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
+                for(FieldMapping mapping : mappings){
+                    fieldMapper.addMapping(mapping);
+                }
+            } else { //no valid mapping parsed
+                log.debug(" > no valid mapping parsed ... will dereference all fields");
+                fieldMapper = null;
+            }
+        } else if(dereferencer.getFieldMapper() != null){
+            fieldMapper = dereferencer.getFieldMapper().clone();
+        } else {
+            fieldMapper = null;
+        }
+        
+        //TODO: uncomment this to merge context with engine mappings. Not sure
+        //      if this is desirable 
+//      if(fieldMapper != null){
+//            if(dereferencer.getFieldMapper() != null){
+//                //add mappings of the engine configuration to the context mappings
+//                for(FieldMapping mapping : dereferencer.getFieldMapper().getMappings()){
+//                    fieldMapper.addMapping(mapping);
+//                }
+//            }
+//        }
+
+        //if a fieldMapper is present and languages are set we will add a language
+        //filter to the fieldMapper. If the fieldmapper is null languages are
+        //filtered separately. 
+        Collection<String> langs = getLanguages();
+        if(langs != null && !langs.isEmpty()){
+            if(fieldMapper == null){ //create a fieldMapper for filtering languages
+                fieldMapper = new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
+            }
+            fieldMapper.addMapping(new FieldMapping(new TextConstraint(
+                (String)null, langs.toArray(new String[langs.size()]))));
+        }
+
+        this.fieldMapper = fieldMapper; //set the field
+    }
+    
+    protected void initLdPath(String program) throws DereferenceConfigurationException {
+        TrackingDereferencerBase<?> dereferencer = getEntityhubDereferencer();
+        ValueFactory valueFactory = dereferencer.getValueFactory();
+        Program<Object> ldpathProgram;
+        if(!StringUtils.isBlank(program)){
+            @SuppressWarnings("rawtypes")
+            RDFBackend<Object> parseBackend = new ParseBackend(valueFactory);
+            EntityhubLDPath parseLdPath = new EntityhubLDPath(parseBackend, valueFactory);
+            try {
+                ldpathProgram = parseLdPath.parseProgram(new StringReader(program));
+            } catch (LDPathParseException e) {
+                log.error("Unable to parse Context LDPath pogram: \n {}", program);
+                throw new DereferenceConfigurationException(
+                    "Unable to parse context LDPath program !",
+                    e,dereferencer.getClass(), DEREFERENCE_ENTITIES_LDPATH);
+            }
+            //finally validate if all mappings of the program do use a URI as key
+            //also store used fieldNames as we need them later
+            Set<String> contextFields = new HashSet<String>();
+            for(at.newmedialab.ldpath.model.fields.FieldMapping<?,Object> mapping : ldpathProgram.getFields()) {
+                try {
+                    new URI(mapping.getFieldName());
+                    contextFields.add(mapping.getFieldName());
+                } catch (URISyntaxException e){
+                    throw new DereferenceConfigurationException( 
+                        "Parsed LDPath MUST use valid URIs as field names (invalid field name: '"
+                        + mapping.getFieldName()+"' | selector: '" 
+                        + mapping.getSelector().getPathExpression(parseBackend)+"')!",
+                        dereferencer.getClass(),DereferenceConstants.DEREFERENCE_ENTITIES_LDPATH);
+                }
+            }
+            //append the mappings configured for the engine
+            if(dereferencer.getLdPathProgram() != null){
+                for(at.newmedialab.ldpath.model.fields.FieldMapping<?,Object> mapping : dereferencer.getLdPathProgram().getFields()) {
+                    if(!contextFields.contains(mapping.getFieldName())){
+                        ldpathProgram.addMapping(mapping);
+                    }//else ignore mappings for fields specified in the context
+                }
+            }
+        } else { //no context specific - use the one of the config
+            ldpathProgram = dereferencer.getLdPathProgram();
+        }
+        if(ldpathProgram != null && !ldpathProgram.getFields().isEmpty()){
+            this.ldpathProgram = ldpathProgram;
+        } else {
+            this.ldpathProgram = null;
+        }
+    }
+
+    /**
+     * Getter for the Entityhub Dereferencer base
+     * @return
+     */
+    protected TrackingDereferencerBase<?> getEntityhubDereferencer(){
+        return (TrackingDereferencerBase<?>)engine.getDereferencer();
+    }
+
+    /**
+     * Getter for the FieldMapper parsed for the {@link #getFields()} parsed
+     * in the context (or the config if no fields where present in the context)
+     * @return the field mapper to be used for dereferencing entities or
+     * <code>null</code> if no field mappings are present
+     */
+    public FieldMapper getFieldMapper() {
+        return fieldMapper;
+    }
+    /**
+     * Getter for the LDPath Program parsed from the {@link #getLdPathProgram()}
+     * parsed in the context and the program set in the configuration. Fields
+     * present in the context will override (replace) those that are also
+     * present in the program set for the engine configuration. 
+     * @return the parsed LDPath {@link Program} or <code>null</code> if none
+     */
+    public Program<Object> getProgram() {
+        return ldpathProgram;
+    }
+    
+}

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceEngine.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceEngine.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceEngine.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/EntityhubDereferenceEngine.java Mon Feb 24 05:23:28 2014
@@ -22,6 +22,7 @@ import static org.apache.stanbol.enhance
 import static org.osgi.framework.Constants.SERVICE_RANKING;
 
 import java.util.Dictionary;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
@@ -35,7 +36,10 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.stanbol.commons.namespaceprefix.NamespacePrefixService;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceConfigurationException;
 import org.apache.stanbol.enhancer.engines.dereference.DereferenceConstants;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceContext;
+import org.apache.stanbol.enhancer.engines.dereference.DereferenceContextFactory;
 import org.apache.stanbol.enhancer.engines.dereference.DereferenceEngineConfig;
 import org.apache.stanbol.enhancer.engines.dereference.EntityDereferenceEngine;
 import org.apache.stanbol.enhancer.engines.dereference.entityhub.shared.SharedDereferenceThreadPool;
@@ -226,7 +230,16 @@ public class EntityhubDereferenceEngine 
         //now parse dereference field config
         entityDereferencer.setDereferencedFields(engineConfig.getDereferenceFields());
         entityDereferencer.setLdPath(engineConfig.getLdPathProgram());
-        entityDereferenceEngine = new EntityDereferenceEngine(entityDereferencer, engineConfig);
+        entityDereferenceEngine = new EntityDereferenceEngine(entityDereferencer, engineConfig,
+            new DereferenceContextFactory() { //we want to use our own DereferenceContext impl
+                
+                @Override
+                public DereferenceContext createContext(EntityDereferenceEngine engine,
+                        Map<String,Object> enhancementProperties) throws DereferenceConfigurationException {
+                    return new EntityhubDereferenceContext(engine, enhancementProperties);
+                }
+            });
+        
         //NOTE: registration of this instance as OSGI service is done as soon as the
         //      entityhub service backing the entityDereferencer is available.
         

Added: stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/ParseBackend.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/ParseBackend.java?rev=1571150&view=auto
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/ParseBackend.java (added)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/ParseBackend.java Mon Feb 24 05:23:28 2014
@@ -0,0 +1,43 @@
+package org.apache.stanbol.enhancer.engines.dereference.entityhub;
+
+import org.apache.stanbol.entityhub.ldpath.backend.AbstractBackend;
+import org.apache.stanbol.entityhub.servicesapi.EntityhubException;
+import org.apache.stanbol.entityhub.servicesapi.model.Representation;
+import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
+import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
+import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
+
+
+final class ParseBackend<T> extends AbstractBackend {
+    /**
+     * 
+     */
+    private final ValueFactory valueFactory;
+
+    /**
+     * @param trackingDereferencerBase
+     */
+    public ParseBackend(ValueFactory vf) {
+        this.valueFactory = vf;
+    }
+
+    @Override
+    protected QueryResultList<String> query(FieldQuery query) throws EntityhubException {
+        throw new UnsupportedOperationException("Not expected to be called");
+    }
+
+    @Override
+    protected ValueFactory getValueFactory() {
+        return valueFactory;
+    }
+
+    @Override
+    protected Representation getRepresentation(String id) throws EntityhubException {
+        throw new UnsupportedOperationException("Not expected to be called");
+    }
+
+    @Override
+    protected FieldQuery createQuery() {
+        throw new UnsupportedOperationException("Not expected to be called");
+    }
+}
\ No newline at end of file

Modified: stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/TrackingDereferencerBase.java
URL: http://svn.apache.org/viewvc/stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/TrackingDereferencerBase.java?rev=1571150&r1=1571149&r2=1571150&view=diff
==============================================================================
--- stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/TrackingDereferencerBase.java (original)
+++ stanbol/branches/release-0.12/enhancement-engines/dereference/entityhub/src/main/java/org/apache/stanbol/enhancer/engines/dereference/entityhub/TrackingDereferencerBase.java Mon Feb 24 05:23:28 2014
@@ -46,7 +46,6 @@ import org.apache.stanbol.entityhub.core
 import org.apache.stanbol.entityhub.core.mapping.FieldMappingUtils;
 import org.apache.stanbol.entityhub.core.mapping.ValueConverterFactory;
 import org.apache.stanbol.entityhub.ldpath.EntityhubLDPath;
-import org.apache.stanbol.entityhub.ldpath.backend.AbstractBackend;
 import org.apache.stanbol.entityhub.model.clerezza.RdfReference;
 import org.apache.stanbol.entityhub.model.clerezza.RdfRepresentation;
 import org.apache.stanbol.entityhub.model.clerezza.RdfValueFactory;
@@ -56,8 +55,6 @@ import org.apache.stanbol.entityhub.serv
 import org.apache.stanbol.entityhub.servicesapi.model.Representation;
 import org.apache.stanbol.entityhub.servicesapi.model.Text;
 import org.apache.stanbol.entityhub.servicesapi.model.ValueFactory;
-import org.apache.stanbol.entityhub.servicesapi.query.FieldQuery;
-import org.apache.stanbol.entityhub.servicesapi.query.QueryResultList;
 import org.apache.stanbol.entityhub.servicesapi.query.TextConstraint;
 import org.apache.stanbol.entityhub.servicesapi.util.ModelUtils;
 import org.osgi.framework.BundleContext;
@@ -204,24 +201,7 @@ public abstract class TrackingDereferenc
             //however we would like to parse/validate the parsed LDPath program
             //So we will create a pseudo RDFBackend sufficient to be used with the
             //parser
-            final RDFBackend<Object> parseBackend = new AbstractBackend() {
-                @Override
-                protected QueryResultList<String> query(FieldQuery query) throws EntityhubException {
-                    throw new UnsupportedOperationException("Not expected to be called");
-                }
-                @Override
-                protected ValueFactory getValueFactory() {
-                    return valueFactory;
-                }
-                @Override
-                protected Representation getRepresentation(String id) throws EntityhubException {
-                    throw new UnsupportedOperationException("Not expected to be called");
-                }
-                @Override
-                protected FieldQuery createQuery() {
-                    throw new UnsupportedOperationException("Not expected to be called");
-                }
-            };
+            final RDFBackend<Object> parseBackend = new ParseBackend<T>(valueFactory);
             //NOTE: calling execute(..) an this parseLdPath or even the 
             //ldpathProgram will result in UnsupportedOperationException
             //but parsing is OK
@@ -254,6 +234,28 @@ public abstract class TrackingDereferenc
     public Set<String> getDereferencedFields() {
         return dereferencedFields;
     }
+        
+    /**
+     * Getter for the FieldMapper used for the {@link #getDereferencedFields()}
+     * @return the fieldMapper or <code>null</code> of the dereferenced fields
+     * are set
+     */
+    public FieldMapper getFieldMapper(){
+        return fieldMapper;
+    }
+    
+    /**
+     * Getter for the LDPath {@link Program} parsed form the
+     * {@link #getLdPath}
+     * @return
+     */
+    public Program<Object> getLdPathProgram(){
+        return ldpathProgram;
+    }
+    
+    public ValueFactory getValueFactory(){
+        return valueFactory;
+    }
     
     /**
      * Starts the tracking by calling {@link ServiceTracker#open()}
@@ -281,12 +283,13 @@ public abstract class TrackingDereferenc
     }
     
     @Override
-    public final boolean dereference(UriRef uri, MGraph graph, Lock writeLock, DereferenceContext derefContext) throws DereferenceException {
+    public final boolean dereference(UriRef uri, MGraph graph, Lock writeLock, DereferenceContext dc) throws DereferenceException {
         T service = getService();
         if(service == null){
             throw new DereferenceException(uri, serviceClass.getClass().getSimpleName() 
                 + "service is currently not available");
         }
+        EntityhubDereferenceContext derefContext = (EntityhubDereferenceContext)dc;
         Representation rep;
         try {
             rep = getRepresentation(service, uri.getUnicodeString(), derefContext.isOfflineMode());
@@ -295,18 +298,20 @@ public abstract class TrackingDereferenc
         }
         //we need the languages as strings
         final Set<String> langs = derefContext.getLanguages();
-        
+        final FieldMapper fieldMapper = derefContext.getFieldMapper();
+        final Program<Object>ldpathProgram = derefContext.getProgram();
         if(rep != null){
-            if(fieldMapper == null && ldpathProgram == null && langs.isEmpty()){
+            if(fieldMapper == null && ldpathProgram == null && 
+                    (langs == null || langs.isEmpty())){
                 copyAll(uri, rep, graph, writeLock);
             } else { //we need to apply some filters while dereferencing
                 if(fieldMapper != null || !langs.isEmpty()){
                     //this considers speficied fields and included languages
-                    copyMapped(uri, rep, langs, graph, writeLock);
+                    copyMapped(uri, rep, fieldMapper, langs, graph, writeLock);
                 }
                 if(ldpathProgram != null){
                     //this executes LDPath statements
-                    copyLdPath(uri, getRdfBackend(service), langs, graph, writeLock);
+                    copyLdPath(uri, getRdfBackend(service), ldpathProgram, langs, graph, writeLock);
                 }
             }
             return true;
@@ -319,13 +324,14 @@ public abstract class TrackingDereferenc
      * writes the the results to the parsed Graph
      * @param uri the context
      * @param rdfBackend the RdfBackend the LDPath program is executed on
+     * @param ldpathProgram The {@link Program} parsed via the dereference context
      * @param langs the set of languages to dereference
      * @param graph the graph to store the results
      * @param writeLock the write lock for the graph
      * @throws DereferenceException on any {@link EntityhubException} while
      * executing the LDPath program
      */
-    private void copyLdPath(UriRef uri, RDFBackend<Object> rdfBackend, 
+    private void copyLdPath(UriRef uri, RDFBackend<Object> rdfBackend, Program<Object> ldpathProgram,
             Set<String> langs, MGraph graph, Lock writeLock) throws DereferenceException {
         //A RdfReference needs to be used as context
         RdfReference context = valueFactory.createReference(uri);
@@ -390,26 +396,25 @@ public abstract class TrackingDereferenc
      * in the graph
      * @param uri the uri of the entity to dereference
      * @param rep the data for the entity as in the entityhub
+     * @param fieldMapper the {@link FieldMapper} parsed from the dereference context
      * @param langs the set of languages to dereference
      * @param graph the graph to store the mapping results
      * @param writeLock the write lock for the graph
      */
-    private void copyMapped(UriRef uri, Representation rep, Set<String> langs, 
+    private void copyMapped(UriRef uri, Representation rep, FieldMapper fieldMapper, Set<String> langs, 
             MGraph graph, Lock writeLock) {
-        //init the fieldMapper
-        FieldMapper fieldMapper;
-        if(!langs.isEmpty()){ //if we need to filter for specific languages
-            //we need to modify the field and add a global filter for the
-            //languages. NOTE that the field might be null. In that case we
-            //need just filter literals by language
-            //TODO: maybe cache fieldMappers for sets of languages
-            fieldMapper = this.fieldMapper != null ? this.fieldMapper.clone() :
-                new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
-            fieldMapper.addMapping(new FieldMapping(new TextConstraint(
-                (String)null, langs.toArray(new String[graph.size()]))));
-        } else { //just use the fieldMapper as parsed in the config
-            fieldMapper = this.fieldMapper;
-        }
+        //NOTE: The fieldMapper parsed via the context does already have a
+        //      filter for the parsed languages. Because of that the old code
+        //      adding such a language filter is no longer needed
+//        FieldMapper fieldMapper;
+//        if(!langs.isEmpty()){ //if we need to filter for specific languages
+//            fieldMapper = this.fieldMapper != null ? this.fieldMapper.clone() :
+//                new DefaultFieldMapperImpl(ValueConverterFactory.getDefaultInstance());
+//            fieldMapper.addMapping(new FieldMapping(new TextConstraint(
+//                (String)null, langs.toArray(new String[langs.size()]))));
+//        } else { //just use the fieldMapper as parsed in the config
+//            fieldMapper = this.fieldMapper;
+//        }
         //execute the field mappings
         writeLock.lock();
         try {
@@ -481,3 +486,4 @@ public abstract class TrackingDereferenc
     }
     
 }
+ 
\ No newline at end of file