You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by sf...@apache.org on 2010/12/12 16:02:37 UTC

svn commit: r1044829 [3/12] - in /incubator/stanbol/trunk/rick/generic: core/src/main/java/eu/iksproject/rick/core/impl/ core/src/main/java/eu/iksproject/rick/core/mapping/ core/src/main/java/eu/iksproject/rick/core/model/ core/src/main/java/eu/iksproj...

Modified: incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/RickImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/RickImpl.java?rev=1044829&r1=1044828&r2=1044829&view=diff
==============================================================================
--- incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/RickImpl.java (original)
+++ incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/RickImpl.java Sun Dec 12 15:02:34 2010
@@ -55,461 +55,461 @@ import eu.iksproject.rick.servicesapi.ya
 @Component()
 @Service
 public final class RickImpl implements Rick, ServiceListener {
-	
-	private final Logger log = LoggerFactory.getLogger(RickImpl.class);
 
-	/**
-	 * The OSGI component context of the Rick
-	 */
-	private ComponentContext context;
-	/**
-	 * The field mapper holding global mappings that are used for mapping 
-	 * representations of entities for any referenced sites
-	 */
-	protected FieldMapper fieldMapper;
-	
-	/**
-	 * The yard where this Rick instance stores its data
-	 * TODO: this reference is currently initialised in the activate method.
-	 * however there are some issues with that.
-	 * <ul>
-	 * <li> If this Component is activated, before this yard is active, the
-	 *      activate method throws an Exception and is therefore in the 
-	 *      "unsatisfied" state.
-	 * <li> If now the needed Yard is configured this component gets not notified
-	 * <li> However defining a Reference is also not possible, because it would
-	 *      be nice to be able to change the Rick-Yard (e.g. to change the data
-	 *      set of the Rick at runtime)
-	 * <li> I could register a {@link ServiceListener} in the activate method.
-	 *      But I am not sure if it is allowed to have an active Service Listener 
-	 *      on an component that is in the "unsatisfied" state.
-	 * </ul>
-	 */
-	protected Yard rickYard; //reference initialised in the activate method
-	/*
-	 * TODO: The YardManager is currently not used. 
-	 */
-	@Reference // 1..1, static
-	protected YardManager yardManager;
-	/**
-	 * The Configuration of the Rick
-	 * TODO: Maybe refactor this implementation to implement this interface or
-	 * to extend the {@link RickConfigurationImpl}.
-	 */
-	@Reference // 1..1, static
-	protected RickConfiguration config;	
-	/**
-	 * The site manager is used to search for entities within the Rick framework
-	 */
-	@Reference // 1..1, static
-	protected ReferencedSiteManager siteManager;
-	
-	private String DEFAULT_SYMBOL_PREFIX = "symbol";
-	private String DEFAULT_MAPPING_PREFIX = "mapping";
-	/**
-	 * Activates the Rick (OSGI Lifecycle method)
-	 * @param context the OSGI component context (stored in {@link #context})
-	 * @throws ConfigurationException On any error during the activation of
-	 * the Rick
-	 */
-	@Activate
-	protected void activate(ComponentContext context) throws ConfigurationException {
-		log.info("activating Rick ...");
-		if(context == null){
-			throw new IllegalStateException("Unable to activate if parsed ComponentContext is NULL");
-		} else {
-			this.context = context;
-		}
-		//First check the RICK ID and
-		log.info(" ... init Basic Properties");
-		if(config.getID() == null || config.getID().isEmpty()){
-			throw new ConfigurationException(RickConfiguration.ID, "The Rick Configuration does not define a ID for the Rick");
-		} else {
-			log.info("   + id: "+config.getID());
-		}
-		if(config.getName() == null || config.getName().isEmpty()){
-			throw new ConfigurationException(RickConfiguration.NAME, "The Rick Configuration does not define a name for the Rick");
-		} else {
-			log.info("   + id: "+config.getName());
-		}
-		if(config.getDescription() != null){
-			log.info("   + id: "+config.getDescription());
-		}
-		if(config.getRickPrefix() == null){
-			throw new ConfigurationException(RickConfiguration.PREFIX, "The Rick Configuration does not define a Prefix for the Rick");
-		}
-		try {
-			new URI(config.getRickPrefix());
-			log.info("   + prefix: "+config.getRickPrefix());
-		} catch (URISyntaxException e1) {
-			throw new ConfigurationException(RickConfiguration.PREFIX, "The Prefix configured for the RICK is not an valied URI (prefix="+config.getRickPrefix()+")");
-		}
-		//next get the reference to the configured RickYard
-		log.info(" ... init RickYard");
-//		final ServiceReference[] refs;
-//		log.info("   - search for services for "+Yard.class+" with Filter "+rickYardFilterString);
-//		try {
-//			refs = context.getBundleContext().getServiceReferences(
-//					Yard.class.getName(), 
-//					rickYardFilterString);
-//			
-//		} catch (InvalidSyntaxException e) {
-//			throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to create Filter for the RickYard based on the parsed vlaue "+config.getRickYardId(),e);
-//		}
-//		if(refs != null && refs.length>0){
-//			log.debug("   - found "+refs.length+" Services");
-//			Yard rickYard = null;
-//			ServiceReference rickYardReference = null;
-//			for(int i=0;i<refs.length && rickYard == null;i++){
-//				rickYardReference =  refs[i];
-//				// I trust the OSGI framework, that the returned service implements the requested Interface
-//				rickYard = (Yard)context.getBundleContext().getService(rickYardReference);
-//				log.info("   + RickYard "+rickYard.getName()+" (id: "+rickYard.getId()+")");
-//			}
-//			//configured Yard not present -> unable to activate!
-//			if(rickYard == null){
-//				throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to get Yard Service for the parsed value "+config.getRickYardId());
-//			}
-		if(yardManager.isYard(config.getRickYardId())){
-			this.rickYard = yardManager.getYard(config.getRickYardId());
-			String rickYardFilterString = '('+Yard.ID+'='+config.getRickYardId()+')';
-			try {
-				context.getBundleContext().addServiceListener(this,rickYardFilterString);
-			} catch (InvalidSyntaxException e) {
-				log.warn(String.format("Unable to set Filter %s to ServiceListener for RickYard! -> add ServiceListener without Filter",
-						rickYardFilterString),e);
-				context.getBundleContext().addServiceListener(this);
-			}
-		} else {
-			throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to get Yard for parsed value "+config.getRickYardId());
-		}
-		//at last get the FieldMappingConfig and create the FieldMappings instance
-		// -> we need to do that after the init of the Rick-yard, because than we
-		//    can use the valueFactory of the configured Yard to create instances
-		//    of converted values!
-		log.info(" ... init FieldMappings");
-		fieldMapper = new DefaultFieldMapperImpl(ValueConverterFactory.getInstance(rickYard.getValueFactory()));
-		for(String mappingString : config.getFieldMappingConfig()){
-			FieldMapping mapping = FieldMappingUtils.parseFieldMapping(mappingString);
-			if(mapping != null){
-				log.info("   + mapping: "+mapping);
-				fieldMapper.addMapping(mapping);
-			}
-		}
-	}
-	/**
-	 * TODO: currently only for debugging. Intended to be used for tracking
-	 * the state of dependencies
-	 */
-	@Override
-	public void serviceChanged(ServiceEvent event) {
-		log.info("Print Service Event for "+event.getSource());
-		for(String key : event.getServiceReference().getPropertyKeys()){
-			log.info("  > "+key+"="+event.getServiceReference().getProperty(key));
-		}
-	}
-
-	@Deactivate
-	protected void deactivate(ComponentContext context) {
-		log.info("!!deactivate");
-		if(this.rickYard != null){
-			//unregister the serviceListener
-			this.context.getBundleContext().removeServiceListener(this);
-		}
-		this.fieldMapper = null;
-		this.rickYard = null;
-		this.context = null;
-	}
-
-//	@Override
-//	public RickConfiguration getRickConfiguration() {
-//		return config;
-//	}
-	@Override
-	public Yard getRickYard() {
-		return rickYard;
-	}
-	
-	@Override
-	public Symbol lookupSymbol(String entity) throws YardException{
-		return lookupSymbol(entity,false);
-	}
-
-	@Override
-	public Symbol lookupSymbol(String entity, boolean create) throws YardException {
-		Symbol symbol = getSymbol(entity);
-		if(symbol != null){
-			return symbol;
-		} else {
-			//parsed reference was not a symbol. search for an mapped Entity
-			EntityMapping entityMapping = getMappingByEntity(entity);
-			if(entityMapping != null){
-				symbol = getSymbol(entityMapping.getSymbolId());
-				if(symbol != null){
-					return symbol;
-				} else {
-					log.warn("Unable to find Symbol for Entity Mapping "+entityMapping+"!");
-					return recoverSymbol(entityMapping.getSymbolId());
-				}
-			} else if(create){
-				//search if the parsed reference is known by any referenced site
-			    // and if YES, create a new Symbol
-				Sign sign = siteManager.getSign(entity);
-				 if(sign == null){ //id not found by any referred site
-					 return null;
-				 } else {
-					 return createSymbol(sign);
-				 }
-			} else {
-				return null;
-			}
-		}
-	}
-	@Override
-	public Symbol createSymbol(String reference) throws IllegalStateException, IllegalArgumentException, YardException {
-		Symbol symbol = getSymbol(reference);
-		if(symbol == null){
-			EntityMapping entityMapping = getMappingByEntity(reference);
-			if(entityMapping == null){
-				Sign sign = siteManager.getSign(reference);
-				if(sign == null){
-					return null;
-				} else {
-					return createSymbol(sign);
-				}
-			} else {
-				throw new IllegalStateException("There exists already an EntityMappting for the parsed reference (mapping="+entityMapping+")");
-			}
-		} else {
-			throw new IllegalStateException("The parsed reference is an Symbol (symbol="+symbol+")!");
-		}
-	}
-	/**
-	 * Recovers an symbol based on the available {@link EntityMapping}s
-	 * @param symbolId the id of the Symbol
-	 * @return the Symbol or <code>null</code> if the recovering is unsucessfull.
-	 */
-	private Symbol recoverSymbol(String symbolId) {
-		/*
-		 * TODO: recover the Symbol by recreating it based on the available
-		 *       mapped Entities
-		 * 1) search for all EntityMappings with this SymbolId
-		 * 2) get all mapped Entities
-		 * 3) apply the FieldMappings
-		 * 4) store the Symbol
-		 * 5) return the recovered Symbol
-		 */
-		return null;
-	}
-	/*
-	 * @throws IllegalArgumentException if a {@link Representation} for the parsed ID is present in the
-	 *  {@link #rickYard}, but the representation can not be wrapped by an {@link Symbol}.
-	 */
-	@Override
-	public Symbol getSymbol(String symbolId) throws IllegalArgumentException,IllegalStateException, YardException {
-		if(symbolId == null || symbolId.isEmpty()){
-			throw new IllegalArgumentException("The parsed symbolID MUST NOT be NULL nor empty!");
-		}
-		Representation rep = rickYard.getRepresentation(symbolId);
-		if(rep != null){
-			try {
-				return new DefaultSymbolImpl(config.getRickPrefix(),rep);
-			} catch(IllegalArgumentException e){
-				String msg = "Unable to create Symbol based on the representation as stored in the Rick";
-				log.warn(msg);
-				if(log.isWarnEnabled()){
-					log.warn(ModelUtils.getRepresentationInfo(rep));
-				}
-				throw new IllegalStateException(msg,e); //re-throw for now
-			}
-		} else {
-			return null;
-		}
-	}
-	protected Symbol createSymbol(Sign sign) throws YardException{
-		if(sign == null){
-			return null;
-		}
-		ReferencedSite signSite = siteManager.getReferencedSite(sign.getSignSite());
-		if(signSite == null){
-			log.warn("Unable to create Symbol because the ReferencedSite "+sign.getSignSite()+" for sign "+sign.getId()+" is currently not active in the RICK -> return null");
-			return null;
-		}
-		Representation symbolRep = rickYard.create(constructResourceId(DEFAULT_SYMBOL_PREFIX));
-		//and set the initial state
-		symbolRep.addReference(Symbol.STATE, config.getDefaultSymbolState().getUri());
-		//create a FieldMapper containing the Rick Mappings and the Site specific mappings
-		//TODO: one could cache such instances
-		FieldMapper siteMapper = signSite.getFieldMapper();
-		FieldMapper mapper = this.fieldMapper.clone();
-		for(FieldMapping siteMapping : siteMapper.getMappings()){
-			mapper.addMapping(siteMapping);
-		}
-		Representation signRep = sign.getRepresentation();
-		//TODO: As soon as MappingActivities are implemented we need to add such
-		//      information to the EntityMapping instance!
-		mapper.applyMappings(signRep, symbolRep);
-		//Second create the symbol and init the data
-		Symbol symbol;
-		try {
-			symbol = new DefaultSymbolImpl(config.getRickPrefix(),symbolRep);
-		} catch (IllegalArgumentException e){
-			//unable to create Symbol based on available Information
-			// -> clean up and return null;
-			log.warn("Unable to create Symbol for Representation "+symbolRep.getId()+
-					", because of missing required fields! -> return null (see more Infos after Stack Trace)",e);
-			if(log.isWarnEnabled()){
-				log.warn(ModelUtils.getRepresentationInfo(symbolRep));
-			}
-			try { //try to remove the created representation in the store
-				rickYard.remove(symbolRep.getId());
-			} catch (YardException e1) {
-				log.warn("Unable to remove Representation "+symbolRep.getId(),e1);
-			}
-			return null;
-		}
-		//Third create and init the mapped Entity
-		EntityMapping entityMapping = new DefaultEntityMappingImpl(
-				config.getRickPrefix(), symbolRep.getId(), signRep.getId(), 
-				config.getDefaultMappingState(), 
-				rickYard.create(constructResourceId(DEFAULT_MAPPING_PREFIX)));
-		//Store the symbol and the mappedEntity in the rickYard
-		rickYard.store(symbol.getRepresentation());
-		rickYard.store(entityMapping.getRepresentation());
-		return symbol;
-		
-		//we need to set the label and the description!
-	}
-	/**
-	 * Uses the Prefix as configured by the {@link #config} and the parsed
-	 * prefix for the type to create an unique ID for a resource.
-	 * @param typePrefix the prefix of the type
-	 * @return An id in the form <code> {@link RickConfiguration#getRickPrefix()}
-	 *  + typePrefix + '.' + {@link ModelUtils#randomUUID()}</code>. Note that between
-	 *  the rick prefix and the type prefix a separation chars are added 
-	 *  if it is not already defined by the {@link RickConfiguration#getRickPrefix()}
-	 *  value.
-	 */
-	private String constructResourceId(String typePrefix) {
-		StringBuilder id = new StringBuilder();
-		String prefix = config.getRickPrefix();
-		if(prefix == null || prefix.isEmpty()){
-			prefix = Rick.DEFAUTL_RICK_PREFIX;
-		}
-		id.append(prefix);
-		switch(prefix.charAt(prefix.length()-1)){
-		case '#':
-		case ':':
-			break;
-		default: //add a separator
-			if(prefix.startsWith("urn:")){
-				id.append(':'); //use a point for now
-			} else {
-				id.append('/'); //use '/' instead of '#' because one needs not to escape it in GET requests
-			}
-		}
-		if(typePrefix != null && !typePrefix.isEmpty()){
-			id.append(typePrefix);
-			id.append('.');
-		}
-		id.append(ModelUtils.randomUUID());
-		return id.toString();
-	}
-
-
-	@Override
-	public EntityMapping getMappingByEntity(String reference) throws YardException{
-		if(reference == null){
-			log.warn("NULL parsed as Reference -> call to getMappingByEntity ignored (return null)");
-			return null;
-		}
-		FieldQuery fieldQuery = getQueryFavtory().createFieldQuery();
-		fieldQuery.setConstraint(RdfResourceEnum.mappedEntity.getUri(), new ReferenceConstraint(reference));
-		QueryResultList<String> resultList = rickYard.findReferences(fieldQuery);
-		if(!resultList.isEmpty()){
-			Iterator<String> resultIterator = resultList.iterator();
-			EntityMapping entityMapping = getEntityMappingFromRickYard(resultIterator.next());
-			if(resultIterator.hasNext()){
-				log.warn("Multiple Mappings found for Entity "+reference+"!");
-				log.warn("  > "+entityMapping.getId()+" -> returned instance");
-				while(resultIterator.hasNext()){
-					log.warn("  > "+resultIterator.next()+" -> ignored");
-				}
-			}
-			return entityMapping;
-		} else {
-			log.debug("No Mapping found for Entity "+reference);
-			return null;
-		}
-	}
-	@Override
-	public Collection<EntityMapping> getMappingsBySymbol(String symbol) throws YardException{
-		if(symbol == null){
-			log.warn("NULL parsed as Reference -> call to getMappingsBySymbol ignored (return null)");
-			return null;
-		}
-		FieldQuery fieldQuery = getQueryFavtory().createFieldQuery();
-		fieldQuery.setConstraint(RdfResourceEnum.mappedSymbol.getUri(), new ReferenceConstraint(symbol));
-		QueryResultList<String> resultList = rickYard.findReferences(fieldQuery);
-		Collection<EntityMapping> mappings = new HashSet<EntityMapping>();
-		for(String mappingId : resultList){
-			EntityMapping entityMapping = getEntityMappingFromRickYard(mappingId);
-			if(entityMapping != null){
-				mappings.add(entityMapping);
-			} else {
-				log.info("Unable to getEntityMapping for "+mappingId+" (id was returned as result for a query for EntityMappings -> so that should only happen if the Mapping was deleted in the meantime)");
-			}
-		}
-		return mappings;
-	}
-	/**
-	 * Getter for the EntityMapping by ID
-	 * @param id the ID
-	 * @return the EntityMapping or <code>null</code> if no Sign is present within the RickYard for the parsed ID
-	 * @throws IllegalArgumentException if the Sign referenced by the parsed ID is not an valid {@link EntityMapping}.
-	 */
-	protected EntityMapping getEntityMappingFromRickYard(String id) throws IllegalArgumentException,YardException {
-		Representation rep = rickYard.getRepresentation(id);
-		if(rep != null){
-			return new DefaultEntityMappingImpl(config.getRickPrefix(),rep);
-		} else {
-			return null;
-		}
-	}
-
-	@Override
-	public EntityMapping getMappingById(String id) throws RickException{
-		return getEntityMappingFromRickYard(id);
-	}
-	@Override
-	public FieldQueryFactory getQueryFavtory() {
-		return rickYard.getQueryFactory();
-	}
-	@Override
-	public FieldMapper getFieldMappings() {
-		return fieldMapper;
-	}
-	@Override
-	public QueryResultList<Representation> find(FieldQuery query) throws YardException{
-		return rickYard.find(query);
-	}
-	@Override
-	public QueryResultList<String> findSymbolReferences(FieldQuery query) throws YardException{
-		return rickYard.findReferences(query);
-	}
-	@Override
-	public QueryResultList<Symbol> findSymbols(FieldQuery query) throws YardException{
-		QueryResultList<String> references = rickYard.findReferences(query);
-		List<Symbol> symbols = new ArrayList<Symbol>(references.size());
-		for(String reference : references){
-			Symbol symbol = lookupSymbol(reference);
-			if(symbol != null){
-				symbols.add(symbol);
-			} else {
-				log.warn("Unable to create Symbol for Reference "+reference+" on RickYard[id="+rickYard.getId()+"] -> ignore reference");
-			}
-		}
-		return new QueryResultListImpl<Symbol>(references.getQuery(), symbols, Symbol.class);
-	}
+    private final Logger log = LoggerFactory.getLogger(RickImpl.class);
+
+    /**
+     * The OSGI component context of the Rick
+     */
+    private ComponentContext context;
+    /**
+     * The field mapper holding global mappings that are used for mapping
+     * representations of entities for any referenced sites
+     */
+    protected FieldMapper fieldMapper;
+
+    /**
+     * The yard where this Rick instance stores its data
+     * TODO: this reference is currently initialised in the activate method.
+     * however there are some issues with that.
+     * <ul>
+     * <li> If this Component is activated, before this yard is active, the
+     *      activate method throws an Exception and is therefore in the
+     *      "unsatisfied" state.
+     * <li> If now the needed Yard is configured this component gets not notified
+     * <li> However defining a Reference is also not possible, because it would
+     *      be nice to be able to change the Rick-Yard (e.g. to change the data
+     *      set of the Rick at runtime)
+     * <li> I could register a {@link ServiceListener} in the activate method.
+     *      But I am not sure if it is allowed to have an active Service Listener
+     *      on an component that is in the "unsatisfied" state.
+     * </ul>
+     */
+    protected Yard rickYard; //reference initialised in the activate method
+    /*
+     * TODO: The YardManager is currently not used.
+     */
+    @Reference // 1..1, static
+    protected YardManager yardManager;
+    /**
+     * The Configuration of the Rick
+     * TODO: Maybe refactor this implementation to implement this interface or
+     * to extend the {@link RickConfigurationImpl}.
+     */
+    @Reference // 1..1, static
+    protected RickConfiguration config;
+    /**
+     * The site manager is used to search for entities within the Rick framework
+     */
+    @Reference // 1..1, static
+    protected ReferencedSiteManager siteManager;
+
+    private String DEFAULT_SYMBOL_PREFIX = "symbol";
+    private String DEFAULT_MAPPING_PREFIX = "mapping";
+    /**
+     * Activates the Rick (OSGI Lifecycle method)
+     * @param context the OSGI component context (stored in {@link #context})
+     * @throws ConfigurationException On any error during the activation of
+     * the Rick
+     */
+    @Activate
+    protected void activate(ComponentContext context) throws ConfigurationException {
+        log.info("activating Rick ...");
+        if(context == null){
+            throw new IllegalStateException("Unable to activate if parsed ComponentContext is NULL");
+        } else {
+            this.context = context;
+        }
+        //First check the RICK ID and
+        log.info(" ... init Basic Properties");
+        if(config.getID() == null || config.getID().isEmpty()){
+            throw new ConfigurationException(RickConfiguration.ID, "The Rick Configuration does not define a ID for the Rick");
+        } else {
+            log.info("   + id: "+config.getID());
+        }
+        if(config.getName() == null || config.getName().isEmpty()){
+            throw new ConfigurationException(RickConfiguration.NAME, "The Rick Configuration does not define a name for the Rick");
+        } else {
+            log.info("   + id: "+config.getName());
+        }
+        if(config.getDescription() != null){
+            log.info("   + id: "+config.getDescription());
+        }
+        if(config.getRickPrefix() == null){
+            throw new ConfigurationException(RickConfiguration.PREFIX, "The Rick Configuration does not define a Prefix for the Rick");
+        }
+        try {
+            new URI(config.getRickPrefix());
+            log.info("   + prefix: "+config.getRickPrefix());
+        } catch (URISyntaxException e1) {
+            throw new ConfigurationException(RickConfiguration.PREFIX, "The Prefix configured for the RICK is not an valied URI (prefix="+config.getRickPrefix()+")");
+        }
+        //next get the reference to the configured RickYard
+        log.info(" ... init RickYard");
+//        final ServiceReference[] refs;
+//        log.info("   - search for services for "+Yard.class+" with Filter "+rickYardFilterString);
+//        try {
+//            refs = context.getBundleContext().getServiceReferences(
+//                    Yard.class.getName(),
+//                    rickYardFilterString);
+//
+//        } catch (InvalidSyntaxException e) {
+//            throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to create Filter for the RickYard based on the parsed vlaue "+config.getRickYardId(),e);
+//        }
+//        if(refs != null && refs.length>0){
+//            log.debug("   - found "+refs.length+" Services");
+//            Yard rickYard = null;
+//            ServiceReference rickYardReference = null;
+//            for(int i=0;i<refs.length && rickYard == null;i++){
+//                rickYardReference =  refs[i];
+//                // I trust the OSGI framework, that the returned service implements the requested Interface
+//                rickYard = (Yard)context.getBundleContext().getService(rickYardReference);
+//                log.info("   + RickYard "+rickYard.getName()+" (id: "+rickYard.getId()+")");
+//            }
+//            //configured Yard not present -> unable to activate!
+//            if(rickYard == null){
+//                throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to get Yard Service for the parsed value "+config.getRickYardId());
+//            }
+        if(yardManager.isYard(config.getRickYardId())){
+            this.rickYard = yardManager.getYard(config.getRickYardId());
+            String rickYardFilterString = '('+Yard.ID+'='+config.getRickYardId()+')';
+            try {
+                context.getBundleContext().addServiceListener(this,rickYardFilterString);
+            } catch (InvalidSyntaxException e) {
+                log.warn(String.format("Unable to set Filter %s to ServiceListener for RickYard! -> add ServiceListener without Filter",
+                        rickYardFilterString),e);
+                context.getBundleContext().addServiceListener(this);
+            }
+        } else {
+            throw new ConfigurationException(RickConfiguration.RICK_YARD_ID, "Unable to get Yard for parsed value "+config.getRickYardId());
+        }
+        //at last get the FieldMappingConfig and create the FieldMappings instance
+        // -> we need to do that after the init of the Rick-yard, because than we
+        //    can use the valueFactory of the configured Yard to create instances
+        //    of converted values!
+        log.info(" ... init FieldMappings");
+        fieldMapper = new DefaultFieldMapperImpl(ValueConverterFactory.getInstance(rickYard.getValueFactory()));
+        for(String mappingString : config.getFieldMappingConfig()){
+            FieldMapping mapping = FieldMappingUtils.parseFieldMapping(mappingString);
+            if(mapping != null){
+                log.info("   + mapping: "+mapping);
+                fieldMapper.addMapping(mapping);
+            }
+        }
+    }
+    /**
+     * TODO: currently only for debugging. Intended to be used for tracking
+     * the state of dependencies
+     */
+    @Override
+    public void serviceChanged(ServiceEvent event) {
+        log.info("Print Service Event for "+event.getSource());
+        for(String key : event.getServiceReference().getPropertyKeys()){
+            log.info("  > "+key+"="+event.getServiceReference().getProperty(key));
+        }
+    }
+
+    @Deactivate
+    protected void deactivate(ComponentContext context) {
+        log.info("!!deactivate");
+        if(this.rickYard != null){
+            //unregister the serviceListener
+            this.context.getBundleContext().removeServiceListener(this);
+        }
+        this.fieldMapper = null;
+        this.rickYard = null;
+        this.context = null;
+    }
+
+//    @Override
+//    public RickConfiguration getRickConfiguration() {
+//        return config;
+//    }
+    @Override
+    public Yard getRickYard() {
+        return rickYard;
+    }
+
+    @Override
+    public Symbol lookupSymbol(String entity) throws YardException{
+        return lookupSymbol(entity,false);
+    }
+
+    @Override
+    public Symbol lookupSymbol(String entity, boolean create) throws YardException {
+        Symbol symbol = getSymbol(entity);
+        if(symbol != null){
+            return symbol;
+        } else {
+            //parsed reference was not a symbol. search for an mapped Entity
+            EntityMapping entityMapping = getMappingByEntity(entity);
+            if(entityMapping != null){
+                symbol = getSymbol(entityMapping.getSymbolId());
+                if(symbol != null){
+                    return symbol;
+                } else {
+                    log.warn("Unable to find Symbol for Entity Mapping "+entityMapping+"!");
+                    return recoverSymbol(entityMapping.getSymbolId());
+                }
+            } else if(create){
+                //search if the parsed reference is known by any referenced site
+                // and if YES, create a new Symbol
+                Sign sign = siteManager.getSign(entity);
+                 if(sign == null){ //id not found by any referred site
+                     return null;
+                 } else {
+                     return createSymbol(sign);
+                 }
+            } else {
+                return null;
+            }
+        }
+    }
+    @Override
+    public Symbol createSymbol(String reference) throws IllegalStateException, IllegalArgumentException, YardException {
+        Symbol symbol = getSymbol(reference);
+        if(symbol == null){
+            EntityMapping entityMapping = getMappingByEntity(reference);
+            if(entityMapping == null){
+                Sign sign = siteManager.getSign(reference);
+                if(sign == null){
+                    return null;
+                } else {
+                    return createSymbol(sign);
+                }
+            } else {
+                throw new IllegalStateException("There exists already an EntityMappting for the parsed reference (mapping="+entityMapping+")");
+            }
+        } else {
+            throw new IllegalStateException("The parsed reference is an Symbol (symbol="+symbol+")!");
+        }
+    }
+    /**
+     * Recovers an symbol based on the available {@link EntityMapping}s
+     * @param symbolId the id of the Symbol
+     * @return the Symbol or <code>null</code> if the recovering is unsucessfull.
+     */
+    private Symbol recoverSymbol(String symbolId) {
+        /*
+         * TODO: recover the Symbol by recreating it based on the available
+         *       mapped Entities
+         * 1) search for all EntityMappings with this SymbolId
+         * 2) get all mapped Entities
+         * 3) apply the FieldMappings
+         * 4) store the Symbol
+         * 5) return the recovered Symbol
+         */
+        return null;
+    }
+    /*
+     * @throws IllegalArgumentException if a {@link Representation} for the parsed ID is present in the
+     *  {@link #rickYard}, but the representation can not be wrapped by an {@link Symbol}.
+     */
+    @Override
+    public Symbol getSymbol(String symbolId) throws IllegalArgumentException,IllegalStateException, YardException {
+        if(symbolId == null || symbolId.isEmpty()){
+            throw new IllegalArgumentException("The parsed symbolID MUST NOT be NULL nor empty!");
+        }
+        Representation rep = rickYard.getRepresentation(symbolId);
+        if(rep != null){
+            try {
+                return new DefaultSymbolImpl(config.getRickPrefix(),rep);
+            } catch(IllegalArgumentException e){
+                String msg = "Unable to create Symbol based on the representation as stored in the Rick";
+                log.warn(msg);
+                if(log.isWarnEnabled()){
+                    log.warn(ModelUtils.getRepresentationInfo(rep));
+                }
+                throw new IllegalStateException(msg,e); //re-throw for now
+            }
+        } else {
+            return null;
+        }
+    }
+    protected Symbol createSymbol(Sign sign) throws YardException{
+        if(sign == null){
+            return null;
+        }
+        ReferencedSite signSite = siteManager.getReferencedSite(sign.getSignSite());
+        if(signSite == null){
+            log.warn("Unable to create Symbol because the ReferencedSite "+sign.getSignSite()+" for sign "+sign.getId()+" is currently not active in the RICK -> return null");
+            return null;
+        }
+        Representation symbolRep = rickYard.create(constructResourceId(DEFAULT_SYMBOL_PREFIX));
+        //and set the initial state
+        symbolRep.addReference(Symbol.STATE, config.getDefaultSymbolState().getUri());
+        //create a FieldMapper containing the Rick Mappings and the Site specific mappings
+        //TODO: one could cache such instances
+        FieldMapper siteMapper = signSite.getFieldMapper();
+        FieldMapper mapper = this.fieldMapper.clone();
+        for(FieldMapping siteMapping : siteMapper.getMappings()){
+            mapper.addMapping(siteMapping);
+        }
+        Representation signRep = sign.getRepresentation();
+        //TODO: As soon as MappingActivities are implemented we need to add such
+        //      information to the EntityMapping instance!
+        mapper.applyMappings(signRep, symbolRep);
+        //Second create the symbol and init the data
+        Symbol symbol;
+        try {
+            symbol = new DefaultSymbolImpl(config.getRickPrefix(),symbolRep);
+        } catch (IllegalArgumentException e){
+            //unable to create Symbol based on available Information
+            // -> clean up and return null;
+            log.warn("Unable to create Symbol for Representation "+symbolRep.getId()+
+                    ", because of missing required fields! -> return null (see more Infos after Stack Trace)",e);
+            if(log.isWarnEnabled()){
+                log.warn(ModelUtils.getRepresentationInfo(symbolRep));
+            }
+            try { //try to remove the created representation in the store
+                rickYard.remove(symbolRep.getId());
+            } catch (YardException e1) {
+                log.warn("Unable to remove Representation "+symbolRep.getId(),e1);
+            }
+            return null;
+        }
+        //Third create and init the mapped Entity
+        EntityMapping entityMapping = new DefaultEntityMappingImpl(
+                config.getRickPrefix(), symbolRep.getId(), signRep.getId(),
+                config.getDefaultMappingState(),
+                rickYard.create(constructResourceId(DEFAULT_MAPPING_PREFIX)));
+        //Store the symbol and the mappedEntity in the rickYard
+        rickYard.store(symbol.getRepresentation());
+        rickYard.store(entityMapping.getRepresentation());
+        return symbol;
+
+        //we need to set the label and the description!
+    }
+    /**
+     * Uses the Prefix as configured by the {@link #config} and the parsed
+     * prefix for the type to create an unique ID for a resource.
+     * @param typePrefix the prefix of the type
+     * @return An id in the form <code> {@link RickConfiguration#getRickPrefix()}
+     *  + typePrefix + '.' + {@link ModelUtils#randomUUID()}</code>. Note that between
+     *  the rick prefix and the type prefix a separation chars are added
+     *  if it is not already defined by the {@link RickConfiguration#getRickPrefix()}
+     *  value.
+     */
+    private String constructResourceId(String typePrefix) {
+        StringBuilder id = new StringBuilder();
+        String prefix = config.getRickPrefix();
+        if(prefix == null || prefix.isEmpty()){
+            prefix = Rick.DEFAUTL_RICK_PREFIX;
+        }
+        id.append(prefix);
+        switch(prefix.charAt(prefix.length()-1)){
+        case '#':
+        case ':':
+            break;
+        default: //add a separator
+            if(prefix.startsWith("urn:")){
+                id.append(':'); //use a point for now
+            } else {
+                id.append('/'); //use '/' instead of '#' because one needs not to escape it in GET requests
+            }
+        }
+        if(typePrefix != null && !typePrefix.isEmpty()){
+            id.append(typePrefix);
+            id.append('.');
+        }
+        id.append(ModelUtils.randomUUID());
+        return id.toString();
+    }
+
+
+    @Override
+    public EntityMapping getMappingByEntity(String reference) throws YardException{
+        if(reference == null){
+            log.warn("NULL parsed as Reference -> call to getMappingByEntity ignored (return null)");
+            return null;
+        }
+        FieldQuery fieldQuery = getQueryFavtory().createFieldQuery();
+        fieldQuery.setConstraint(RdfResourceEnum.mappedEntity.getUri(), new ReferenceConstraint(reference));
+        QueryResultList<String> resultList = rickYard.findReferences(fieldQuery);
+        if(!resultList.isEmpty()){
+            Iterator<String> resultIterator = resultList.iterator();
+            EntityMapping entityMapping = getEntityMappingFromRickYard(resultIterator.next());
+            if(resultIterator.hasNext()){
+                log.warn("Multiple Mappings found for Entity "+reference+"!");
+                log.warn("  > "+entityMapping.getId()+" -> returned instance");
+                while(resultIterator.hasNext()){
+                    log.warn("  > "+resultIterator.next()+" -> ignored");
+                }
+            }
+            return entityMapping;
+        } else {
+            log.debug("No Mapping found for Entity "+reference);
+            return null;
+        }
+    }
+    @Override
+    public Collection<EntityMapping> getMappingsBySymbol(String symbol) throws YardException{
+        if(symbol == null){
+            log.warn("NULL parsed as Reference -> call to getMappingsBySymbol ignored (return null)");
+            return null;
+        }
+        FieldQuery fieldQuery = getQueryFavtory().createFieldQuery();
+        fieldQuery.setConstraint(RdfResourceEnum.mappedSymbol.getUri(), new ReferenceConstraint(symbol));
+        QueryResultList<String> resultList = rickYard.findReferences(fieldQuery);
+        Collection<EntityMapping> mappings = new HashSet<EntityMapping>();
+        for(String mappingId : resultList){
+            EntityMapping entityMapping = getEntityMappingFromRickYard(mappingId);
+            if(entityMapping != null){
+                mappings.add(entityMapping);
+            } else {
+                log.info("Unable to getEntityMapping for "+mappingId+" (id was returned as result for a query for EntityMappings -> so that should only happen if the Mapping was deleted in the meantime)");
+            }
+        }
+        return mappings;
+    }
+    /**
+     * Getter for the EntityMapping by ID
+     * @param id the ID
+     * @return the EntityMapping or <code>null</code> if no Sign is present within the RickYard for the parsed ID
+     * @throws IllegalArgumentException if the Sign referenced by the parsed ID is not an valid {@link EntityMapping}.
+     */
+    protected EntityMapping getEntityMappingFromRickYard(String id) throws IllegalArgumentException,YardException {
+        Representation rep = rickYard.getRepresentation(id);
+        if(rep != null){
+            return new DefaultEntityMappingImpl(config.getRickPrefix(),rep);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public EntityMapping getMappingById(String id) throws RickException{
+        return getEntityMappingFromRickYard(id);
+    }
+    @Override
+    public FieldQueryFactory getQueryFavtory() {
+        return rickYard.getQueryFactory();
+    }
+    @Override
+    public FieldMapper getFieldMappings() {
+        return fieldMapper;
+    }
+    @Override
+    public QueryResultList<Representation> find(FieldQuery query) throws YardException{
+        return rickYard.find(query);
+    }
+    @Override
+    public QueryResultList<String> findSymbolReferences(FieldQuery query) throws YardException{
+        return rickYard.findReferences(query);
+    }
+    @Override
+    public QueryResultList<Symbol> findSymbols(FieldQuery query) throws YardException{
+        QueryResultList<String> references = rickYard.findReferences(query);
+        List<Symbol> symbols = new ArrayList<Symbol>(references.size());
+        for(String reference : references){
+            Symbol symbol = lookupSymbol(reference);
+            if(symbol != null){
+                symbols.add(symbol);
+            } else {
+                log.warn("Unable to create Symbol for Reference "+reference+" on RickYard[id="+rickYard.getId()+"] -> ignore reference");
+            }
+        }
+        return new QueryResultListImpl<Symbol>(references.getQuery(), symbols, Symbol.class);
+    }
 
 }

Modified: incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/YardManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/YardManagerImpl.java?rev=1044829&r1=1044828&r2=1044829&view=diff
==============================================================================
--- incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/YardManagerImpl.java (original)
+++ incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/impl/YardManagerImpl.java Sun Dec 12 15:02:34 2010
@@ -21,92 +21,92 @@ import eu.iksproject.rick.servicesapi.ya
 @Component(immediate = true)
 @Service
 public class YardManagerImpl implements YardManager {
-	
-	Logger log = LoggerFactory.getLogger(YardManagerImpl.class);
-	@Reference(
-			cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
-			referenceInterface=Yard.class,
-			strategy=ReferenceStrategy.EVENT,
-			policy=ReferencePolicy.DYNAMIC,
-			bind="bindYard",
-			unbind="unbindYard")
-	private Map<String,Yard> yards = Collections.emptyMap();
-
-
-	@Reference(
-			cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
-			referenceInterface=Cache.class,
-			strategy=ReferenceStrategy.EVENT,
-			policy=ReferencePolicy.DYNAMIC,
-			bind="bindCache",
-			unbind="unbindCache")
-	private Map<String,Cache> caches = Collections.emptyMap();// stat with a empty map!
-
-//	private ComponentContext context;
-//	@Activate
-//	protected void activate(ComponentContext context){
-//		log.debug("activating "+getClass()+" with "+context);
-//		//nothing to do for now!
-//		this.context = context;
-//	}
-//	@Deactivate
-//	protected void deactivate(ComponentContext context){
-//		context = null;
-//	}
-	protected void bindYard(Yard yard){
-		if(yard != null){
-			Map<String, Yard> tmp = new HashMap<String, Yard>(yards);
-			tmp.put(yard.getId(),yard);
-			this.yards = Collections.unmodifiableMap(tmp);
-		}
-	}
-	protected void unbindYard(Yard yard){
-		if(yard != null && yards.containsKey(yard.getId())){
-			Map<String, Yard> tmp = new HashMap<String, Yard>(yards);
-			tmp.remove(yard.getId());
-			this.yards = Collections.unmodifiableMap(tmp);
-		}
-	}
-	protected void bindCache(Cache cache){
-		if(cache != null){
-			Map<String, Cache> tmp = new HashMap<String, Cache>(caches);
-			tmp.put(cache.getId(),cache);
-			this.caches = Collections.unmodifiableMap(tmp);
-		}
-	}
-	protected void unbindCache(Cache cache){
-		if(cache != null && caches.containsKey(cache.getId())){
-			Map<String, Cache> tmp = new HashMap<String, Cache>(caches);
-			tmp.remove(cache.getId());
-			this.caches = Collections.unmodifiableMap(tmp);
-		}
-	}
-
-	@Override
-	public Yard getYard(String id) {
-		return yards.get(id);
-	}
-
-	@Override
-	public Collection<String> getYardIDs() {
-		return yards.keySet();
-	}
-
-	@Override
-	public boolean isYard(String id) {
-		return yards.containsKey(id);
-	}
-	@Override
-	public Cache getCache(String id) {
-		Cache cache = caches.get(id);
-		return cache;
-	}
-	@Override
-	public Collection<String> getCacheIDs() {
-		return caches.keySet();
-	}
-	@Override
-	public boolean isCache(String id) {
-		return caches.containsKey(id);
-	}
+
+    Logger log = LoggerFactory.getLogger(YardManagerImpl.class);
+    @Reference(
+            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
+            referenceInterface=Yard.class,
+            strategy=ReferenceStrategy.EVENT,
+            policy=ReferencePolicy.DYNAMIC,
+            bind="bindYard",
+            unbind="unbindYard")
+    private Map<String,Yard> yards = Collections.emptyMap();
+
+
+    @Reference(
+            cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE,
+            referenceInterface=Cache.class,
+            strategy=ReferenceStrategy.EVENT,
+            policy=ReferencePolicy.DYNAMIC,
+            bind="bindCache",
+            unbind="unbindCache")
+    private Map<String,Cache> caches = Collections.emptyMap();// stat with a empty map!
+
+//    private ComponentContext context;
+//    @Activate
+//    protected void activate(ComponentContext context){
+//        log.debug("activating "+getClass()+" with "+context);
+//        //nothing to do for now!
+//        this.context = context;
+//    }
+//    @Deactivate
+//    protected void deactivate(ComponentContext context){
+//        context = null;
+//    }
+    protected void bindYard(Yard yard){
+        if(yard != null){
+            Map<String, Yard> tmp = new HashMap<String, Yard>(yards);
+            tmp.put(yard.getId(),yard);
+            this.yards = Collections.unmodifiableMap(tmp);
+        }
+    }
+    protected void unbindYard(Yard yard){
+        if(yard != null && yards.containsKey(yard.getId())){
+            Map<String, Yard> tmp = new HashMap<String, Yard>(yards);
+            tmp.remove(yard.getId());
+            this.yards = Collections.unmodifiableMap(tmp);
+        }
+    }
+    protected void bindCache(Cache cache){
+        if(cache != null){
+            Map<String, Cache> tmp = new HashMap<String, Cache>(caches);
+            tmp.put(cache.getId(),cache);
+            this.caches = Collections.unmodifiableMap(tmp);
+        }
+    }
+    protected void unbindCache(Cache cache){
+        if(cache != null && caches.containsKey(cache.getId())){
+            Map<String, Cache> tmp = new HashMap<String, Cache>(caches);
+            tmp.remove(cache.getId());
+            this.caches = Collections.unmodifiableMap(tmp);
+        }
+    }
+
+    @Override
+    public Yard getYard(String id) {
+        return yards.get(id);
+    }
+
+    @Override
+    public Collection<String> getYardIDs() {
+        return yards.keySet();
+    }
+
+    @Override
+    public boolean isYard(String id) {
+        return yards.containsKey(id);
+    }
+    @Override
+    public Cache getCache(String id) {
+        Cache cache = caches.get(id);
+        return cache;
+    }
+    @Override
+    public Collection<String> getCacheIDs() {
+        return caches.keySet();
+    }
+    @Override
+    public boolean isCache(String id) {
+        return caches.containsKey(id);
+    }
 }

Modified: incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/mapping/DefaultFieldMapperImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/mapping/DefaultFieldMapperImpl.java?rev=1044829&r1=1044828&r2=1044829&view=diff
==============================================================================
--- incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/mapping/DefaultFieldMapperImpl.java (original)
+++ incubator/stanbol/trunk/rick/generic/core/src/main/java/eu/iksproject/rick/core/mapping/DefaultFieldMapperImpl.java Sun Dec 12 15:02:34 2010
@@ -40,431 +40,431 @@ import eu.iksproject.rick.servicesapi.ut
  *
  */
 public class DefaultFieldMapperImpl implements FieldMapper {
-	private final Logger log = LoggerFactory.getLogger(DefaultFieldMapperImpl.class);
-	private final Set<FieldMapping> mappings;
-//	private final Map<String,Collection<FieldMapping>> ignoreFieldMap;
-//	private final Map<Pattern,Collection<FieldMapping>> ignoreWildcardMap;
-	private final Map<String,Set<FieldMapping>> fieldMap;
-	private final Map<Pattern,Set<FieldMapping>> wildcardMap;
-	private Collection<FieldMapping> unmodMappings;
-	ValueConverterFactory valueConverter;
-	//private Map<String,FieldMapping> mappings = Collections.synchronizedMap(new HashMap<String, FieldMapping>());
-	public DefaultFieldMapperImpl(ValueConverterFactory valueConverter) {
-		super();
-		mappings = new HashSet<FieldMapping>();
-		unmodMappings = Collections.unmodifiableCollection(mappings);
-		fieldMap = new HashMap<String, Set<FieldMapping>>();
-		wildcardMap = new HashMap<Pattern, Set<FieldMapping>>();
-		if(valueConverter == null){
-			throw new IllegalArgumentException("The parsed ValueConverterFactory MUST NOT be NULL");
-		}
-		this.valueConverter = valueConverter;
-//		ignoreFieldMap = new HashMap<String, Collection<FieldMapping>>();
-//		ignoreWildcardMap = new HashMap<Pattern, Collection<FieldMapping>>();
-	}
-	/**
-	 * Internally used by clone
-	 * @param fieldMap
-	 * @param wildcardMap
-	 */
-	private DefaultFieldMapperImpl(ValueConverterFactory valueConverter,Set<FieldMapping> mappings,Map<String,Set<FieldMapping>> fieldMap, Map<Pattern,Set<FieldMapping>> wildcardMap){
-		this(valueConverter);
-		this.mappings.addAll(mappings);
-		this.fieldMap.putAll(fieldMap);
-		this.wildcardMap.putAll(wildcardMap);
-	}
-	/**
-	 * Getter for all the defined Mappings for a given field name
-	 * @param field the name of the field
-	 * @return all the active Mappings
-	 */
-	protected List<FieldMapping> getMappings(String field){
-		final List<FieldMapping> mappings = new ArrayList<FieldMapping>();
-		//first search the fieldMappings
-		Collection<FieldMapping> tmp = fieldMap.get(field);
-		if(tmp != null){
-			mappings.addAll(tmp);
-		}
-		//now iterate over the Wildcard Mappings
-		for(Entry<Pattern,Set<FieldMapping>> entry : wildcardMap.entrySet()){
-			if(entry.getKey().matcher(field).find()){
-				mappings.addAll(entry.getValue());
-			}
-		}
-		Collections.sort(mappings, FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
-		return mappings;
-	}
-	/* (non-Javadoc)
-	 * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#addMapping(eu.iksproject.rick.servicesapi.mapping.FieldMapping)
-	 */
-	public void addMapping(FieldMapping mapping){
-		if(mapping == null){
-			return;
-		}
-		if(mappings.add(mapping)){
-			if(mapping.usesWildcard()){
-				Pattern fieldPattern = mapping.getRegexPattern();
-				synchronized (wildcardMap) {
-					Set<FieldMapping> fieldPatternMappings = wildcardMap.get(fieldPattern);
-					if(fieldPatternMappings == null){
-						fieldPatternMappings = new HashSet<FieldMapping>();//new TreeSet<FieldMapping>(FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
-						wildcardMap.put(fieldPattern, fieldPatternMappings);
-					}
-					fieldPatternMappings.add(mapping);
-				}
-			} else {
-				String fieldName = mapping.getFieldPattern();
-				synchronized (fieldMap) {
-					Set<FieldMapping> fieldPatternMappings = fieldMap.get(fieldName);
-					if(fieldPatternMappings == null){
-						fieldPatternMappings = new HashSet<FieldMapping>();//new TreeSet<FieldMapping>(FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
-						fieldMap.put(fieldName, fieldPatternMappings);
-					}
-					fieldPatternMappings.add(mapping);
-				}
-			}
-		} //else already present -> nothing todo
-	}
-	public Collection<FieldMapping> getMappings(){
-		return unmodMappings;
-	}
-//	private static String getPrefix(String fieldPattern){
-//		return fieldPattern.split("[\\?\\*]")[0];
-//	}
-	/* (non-Javadoc)
-	 * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#removeFieldMapping(eu.iksproject.rick.servicesapi.mapping.FieldMapping)
-	 */
-	public void removeFieldMapping(FieldMapping mapping){
-		if(mapping == null){
-			return;
-		}
-		if(mappings.remove(mapping)){
-			if(mapping.usesWildcard()){
-				Pattern fieldPattern = mapping.getRegexPattern();
-				synchronized (wildcardMap) {
-					Collection<FieldMapping> fieldPatternMappings = wildcardMap.get(fieldPattern);
-					if(fieldPatternMappings != null){
-						if(fieldPatternMappings.remove(mapping) && fieldPatternMappings.isEmpty()){
-							//clean up the prefix if last value is removed
-							wildcardMap.remove(fieldPattern);
-						}
-					}
-				}
-			} else {
-				String fieldPattern = mapping.getFieldPattern();
-				synchronized (fieldMap) {
-					Collection<FieldMapping> fieldPatternMappings = fieldMap.get(fieldPattern);
-					if(fieldPatternMappings != null){
-						if(fieldPatternMappings.remove(mapping) && fieldPatternMappings.isEmpty()){
-							//clean up the prefix if last value is removed
-							fieldMap.remove(fieldPattern);
-						}
-					}
-				}
-			}
-		} //else nothing todo
-	}
-	/**
-	 * Removes the FieldMapping based on the fieldPattern
-	 * @param fieldPattern the field pattern
-	 */
-	public void removeFieldMapping(String fieldPattern){
-		if(fieldPattern == null || fieldPattern.length()<1){
-			return;
-		}
-		if(PatternUtils.usesWildCard(fieldPattern)){
-			Pattern pattern = Pattern.compile(PatternUtils.wildcardToRegex(fieldPattern,true));
-			synchronized (wildcardMap) {
-				wildcardMap.remove(pattern);
-			}		
-		} else {
-			synchronized (fieldMap) {
-				fieldMap.remove(fieldPattern);
-			}		
-		}
-	}
-	/* (non-Javadoc)
-	 * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#applyMappings(eu.iksproject.rick.servicesapi.model.Representation, eu.iksproject.rick.servicesapi.model.Representation)
-	 */
-	public Representation applyMappings(Representation source, Representation target) {
-		Collection<String> fields = new HashSet<String>();
-		for(Iterator<String> fieldIt = source.getFieldNames();fieldIt.hasNext();){
-			fields.add(fieldIt.next());
-		}
-		for(String field : fields){
-//			log.info("  > process field: "+field);
-			//get the active Mappings
-			List<FieldMapping> activeMappings = getMappings(field);
-			if(!activeMappings.isEmpty()){
-				//get all the values (store them in an Collection, because we need them more than once)
-				Collection<Object> values = new ArrayList<Object>();
-				for(Iterator<Object> valueIt = source.get(field);valueIt.hasNext();){
-					values.add(valueIt.next());
-				}
-				//only to be sure, that this is not changed by Filters!
-				values = Collections.unmodifiableCollection(values);
-				/*
-				 * (1) Before working with the values first analyse the active 
-				 * mappings and filters. Two things
-				 * a) Init Wildcard Filters:
-				 *    Language filters set on namespaces are executed on all field
-				 *    mappings that define no language filter
-				 * b) calculate the mapped fields. Possible there are no mappings
-				 *    left. Than we need not to process all the values
-				 */
-				Set<String> targetFields = new HashSet<String>();
-				TextConstraint globalFilter = null;
-				Collection<Object> globalFiltered = null;
-				/*
-				 * NOTE: the mappings are sorted in the way, that the most
-				 *   prominent one will be at index 0. The wildcard "*" will
-				 *   be always the last.
-				 *   So we need to parse backwards because than more prominent
-				 *   things will overwrite and win!
-				 */
-				for(int i=activeMappings.size()-1;i>=0;i--){
-					FieldMapping mapping = activeMappings.get(i);
-					if(mapping.usesWildcard() //if wildcard
-							&& !mapping.ignoreField() && //and not ignore
-							mapping.getFilter() != null && //and a filter is present 
-							mapping.getFilter().getType() == ConstraintType.text){ //and of type text 
-						//set the global text filter.
-						//NOTE: the active mappings are sorted in that way, that
-						//      the most specific one is set last
-						globalFilter = (TextConstraint)mapping.getFilter();
-					}
-					for(String targetField : mapping.getMappings()){
-						if(mapping.ignoreField()){
-							targetFields.remove(targetField);
-						} else {
-							targetFields.add(targetField);
-						}						
-					}
-				}
-//				log.info("    o targets: "+targetFields);
-//				log.info("    o global text filter: "+globalFilter);
-				if(globalFilter != null){
-					globalFiltered = new HashSet<Object>(values);
-					//parse false ass third argument, because we need not to filter
-					//non-Text values for wildcard filter!
-					processFilter(globalFilter, globalFiltered,false);
-				}
-				//now process the mappings
-				for(FieldMapping mapping : activeMappings){
-					if(!mapping.ignoreField() && 
-							!Collections.disjoint(targetFields, mapping.getMappings())){
-						processMapping(mapping, field,  values,globalFiltered, targetFields, target);
-//					} else if(!mapping.ignoreField()) {
-//						log.info(String.format("  << ignore mapping %s ",mapping));
-//					} else {
-//						log.info(String.format("  << %s ",mapping));
-					}
-				}
-			}
-		}
-		/*
-		 * TODO: return a "MappingReport"
-		 * All mapping activities should be documented and stored with the
-		 * MappedEntity as MappingActivity!
-		 */
-		return target;
-	}
-	/**
-	 * 
-	 * @param mapping
-	 * @param field
-	 * @param values
-	 * @param globalFiltered
-	 * @param targets
-	 */
-	private void processMapping(FieldMapping mapping, String field,  Collection<Object> values, Collection<Object> globalFiltered, Set<String> activeTargets,Representation targetRepresentation) {
-		//parsed mappings are all !ignore and some mappings are active
-		Collection<Object> filtered; //this collection will be modified by the filters later on
-		if(globalFiltered == null || //if no global filter is present and therefore globalFiltered == null or
-				//there is a more special text filter defined in this mapping
-				mapping.getFilter() != null && mapping.getFilter().getType() == ConstraintType.text){
-			filtered = new HashSet<Object>(values);//start with all values
-		} else { //start with the values filtered by the global filter
-			filtered = new HashSet<Object>(globalFiltered);
-		}
-		if(mapping.getFilter()!=null){
-			switch (mapping.getFilter().getType()) {
-			case value:
-				ValueConstraint valueConstraint = (ValueConstraint)mapping.getFilter();
-				processFilter(valueConstraint,filtered);
-				break;
-			case text:
-				TextConstraint textConstraint = (TextConstraint)mapping.getFilter();
-				//for wildcard mappings only filter TextValues. if the mapping is
-				//for a specific field filter also non text values.
-				processFilter(textConstraint,filtered,!mapping.usesWildcard());
-				break;
-			default:
-				log.warn(String.format("Filter of type %s are not supported -> select all values! (Constraint=%s)",
-						mapping.getFilter().getType(),mapping.getFilter()));
-				break;
-			}
-			/*
-			 * TODO: add general purpose functionality to apply Constraints.
-			 * Currently this is done by the specific Query Implementations :(
-			 *  - use the constraint to filter the values collection!
-			 */
-			
-		} //nothing to do
-		for(String mappedField : mapping.getMappings()){
-			//activeTargets still uses null for the current field
-			// -> this is because wildcard filters can not know the actual field name
-			if(activeTargets.contains(mappedField)){ //so use null to match
-				if(mappedField == null){ //and than replace null with the field name
-					mappedField = field;
-				}
-//				log.info(String.format("  >> copy%s to %s &d values",
-//						mappedField.equals(field)?"":" from "+field,mappedField,filtered.size()));
-				targetRepresentation.add(mappedField, filtered);
-//			} else {
-//				log.info(String.format("  << ignore%s %s",
-//						mappedField.equals(field)?"":"mapping from "+field+"to",mappedField));
-			}
-		}
+    private final Logger log = LoggerFactory.getLogger(DefaultFieldMapperImpl.class);
+    private final Set<FieldMapping> mappings;
+//    private final Map<String,Collection<FieldMapping>> ignoreFieldMap;
+//    private final Map<Pattern,Collection<FieldMapping>> ignoreWildcardMap;
+    private final Map<String,Set<FieldMapping>> fieldMap;
+    private final Map<Pattern,Set<FieldMapping>> wildcardMap;
+    private Collection<FieldMapping> unmodMappings;
+    ValueConverterFactory valueConverter;
+    //private Map<String,FieldMapping> mappings = Collections.synchronizedMap(new HashMap<String, FieldMapping>());
+    public DefaultFieldMapperImpl(ValueConverterFactory valueConverter) {
+        super();
+        mappings = new HashSet<FieldMapping>();
+        unmodMappings = Collections.unmodifiableCollection(mappings);
+        fieldMap = new HashMap<String, Set<FieldMapping>>();
+        wildcardMap = new HashMap<Pattern, Set<FieldMapping>>();
+        if(valueConverter == null){
+            throw new IllegalArgumentException("The parsed ValueConverterFactory MUST NOT be NULL");
+        }
+        this.valueConverter = valueConverter;
+//        ignoreFieldMap = new HashMap<String, Collection<FieldMapping>>();
+//        ignoreWildcardMap = new HashMap<Pattern, Collection<FieldMapping>>();
+    }
+    /**
+     * Internally used by clone
+     * @param fieldMap
+     * @param wildcardMap
+     */
+    private DefaultFieldMapperImpl(ValueConverterFactory valueConverter,Set<FieldMapping> mappings,Map<String,Set<FieldMapping>> fieldMap, Map<Pattern,Set<FieldMapping>> wildcardMap){
+        this(valueConverter);
+        this.mappings.addAll(mappings);
+        this.fieldMap.putAll(fieldMap);
+        this.wildcardMap.putAll(wildcardMap);
+    }
+    /**
+     * Getter for all the defined Mappings for a given field name
+     * @param field the name of the field
+     * @return all the active Mappings
+     */
+    protected List<FieldMapping> getMappings(String field){
+        final List<FieldMapping> mappings = new ArrayList<FieldMapping>();
+        //first search the fieldMappings
+        Collection<FieldMapping> tmp = fieldMap.get(field);
+        if(tmp != null){
+            mappings.addAll(tmp);
+        }
+        //now iterate over the Wildcard Mappings
+        for(Entry<Pattern,Set<FieldMapping>> entry : wildcardMap.entrySet()){
+            if(entry.getKey().matcher(field).find()){
+                mappings.addAll(entry.getValue());
+            }
+        }
+        Collections.sort(mappings, FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
+        return mappings;
+    }
+    /* (non-Javadoc)
+     * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#addMapping(eu.iksproject.rick.servicesapi.mapping.FieldMapping)
+     */
+    public void addMapping(FieldMapping mapping){
+        if(mapping == null){
+            return;
+        }
+        if(mappings.add(mapping)){
+            if(mapping.usesWildcard()){
+                Pattern fieldPattern = mapping.getRegexPattern();
+                synchronized (wildcardMap) {
+                    Set<FieldMapping> fieldPatternMappings = wildcardMap.get(fieldPattern);
+                    if(fieldPatternMappings == null){
+                        fieldPatternMappings = new HashSet<FieldMapping>();//new TreeSet<FieldMapping>(FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
+                        wildcardMap.put(fieldPattern, fieldPatternMappings);
+                    }
+                    fieldPatternMappings.add(mapping);
+                }
+            } else {
+                String fieldName = mapping.getFieldPattern();
+                synchronized (fieldMap) {
+                    Set<FieldMapping> fieldPatternMappings = fieldMap.get(fieldName);
+                    if(fieldPatternMappings == null){
+                        fieldPatternMappings = new HashSet<FieldMapping>();//new TreeSet<FieldMapping>(FieldMappingUtils.FIELD_MAPPING_COMPARATOR);
+                        fieldMap.put(fieldName, fieldPatternMappings);
+                    }
+                    fieldPatternMappings.add(mapping);
+                }
+            }
+        } //else already present -> nothing todo
+    }
+    public Collection<FieldMapping> getMappings(){
+        return unmodMappings;
+    }
+//    private static String getPrefix(String fieldPattern){
+//        return fieldPattern.split("[\\?\\*]")[0];
+//    }
+    /* (non-Javadoc)
+     * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#removeFieldMapping(eu.iksproject.rick.servicesapi.mapping.FieldMapping)
+     */
+    public void removeFieldMapping(FieldMapping mapping){
+        if(mapping == null){
+            return;
+        }
+        if(mappings.remove(mapping)){
+            if(mapping.usesWildcard()){
+                Pattern fieldPattern = mapping.getRegexPattern();
+                synchronized (wildcardMap) {
+                    Collection<FieldMapping> fieldPatternMappings = wildcardMap.get(fieldPattern);
+                    if(fieldPatternMappings != null){
+                        if(fieldPatternMappings.remove(mapping) && fieldPatternMappings.isEmpty()){
+                            //clean up the prefix if last value is removed
+                            wildcardMap.remove(fieldPattern);
+                        }
+                    }
+                }
+            } else {
+                String fieldPattern = mapping.getFieldPattern();
+                synchronized (fieldMap) {
+                    Collection<FieldMapping> fieldPatternMappings = fieldMap.get(fieldPattern);
+                    if(fieldPatternMappings != null){
+                        if(fieldPatternMappings.remove(mapping) && fieldPatternMappings.isEmpty()){
+                            //clean up the prefix if last value is removed
+                            fieldMap.remove(fieldPattern);
+                        }
+                    }
+                }
+            }
+        } //else nothing todo
+    }
+    /**
+     * Removes the FieldMapping based on the fieldPattern
+     * @param fieldPattern the field pattern
+     */
+    public void removeFieldMapping(String fieldPattern){
+        if(fieldPattern == null || fieldPattern.length()<1){
+            return;
+        }
+        if(PatternUtils.usesWildCard(fieldPattern)){
+            Pattern pattern = Pattern.compile(PatternUtils.wildcardToRegex(fieldPattern,true));
+            synchronized (wildcardMap) {
+                wildcardMap.remove(pattern);
+            }
+        } else {
+            synchronized (fieldMap) {
+                fieldMap.remove(fieldPattern);
+            }
+        }
+    }
+    /* (non-Javadoc)
+     * @see eu.iksproject.rick.servicesapi.mapping.FieldMapper#applyMappings(eu.iksproject.rick.servicesapi.model.Representation, eu.iksproject.rick.servicesapi.model.Representation)
+     */
+    public Representation applyMappings(Representation source, Representation target) {
+        Collection<String> fields = new HashSet<String>();
+        for(Iterator<String> fieldIt = source.getFieldNames();fieldIt.hasNext();){
+            fields.add(fieldIt.next());
+        }
+        for(String field : fields){
+//            log.info("  > process field: "+field);
+            //get the active Mappings
+            List<FieldMapping> activeMappings = getMappings(field);
+            if(!activeMappings.isEmpty()){
+                //get all the values (store them in an Collection, because we need them more than once)
+                Collection<Object> values = new ArrayList<Object>();
+                for(Iterator<Object> valueIt = source.get(field);valueIt.hasNext();){
+                    values.add(valueIt.next());
+                }
+                //only to be sure, that this is not changed by Filters!
+                values = Collections.unmodifiableCollection(values);
+                /*
+                 * (1) Before working with the values first analyse the active
+                 * mappings and filters. Two things
+                 * a) Init Wildcard Filters:
+                 *    Language filters set on namespaces are executed on all field
+                 *    mappings that define no language filter
+                 * b) calculate the mapped fields. Possible there are no mappings
+                 *    left. Than we need not to process all the values
+                 */
+                Set<String> targetFields = new HashSet<String>();
+                TextConstraint globalFilter = null;
+                Collection<Object> globalFiltered = null;
+                /*
+                 * NOTE: the mappings are sorted in the way, that the most
+                 *   prominent one will be at index 0. The wildcard "*" will
+                 *   be always the last.
+                 *   So we need to parse backwards because than more prominent
+                 *   things will overwrite and win!
+                 */
+                for(int i=activeMappings.size()-1;i>=0;i--){
+                    FieldMapping mapping = activeMappings.get(i);
+                    if(mapping.usesWildcard() //if wildcard
+                            && !mapping.ignoreField() && //and not ignore
+                            mapping.getFilter() != null && //and a filter is present
+                            mapping.getFilter().getType() == ConstraintType.text){ //and of type text
+                        //set the global text filter.
+                        //NOTE: the active mappings are sorted in that way, that
+                        //      the most specific one is set last
+                        globalFilter = (TextConstraint)mapping.getFilter();
+                    }
+                    for(String targetField : mapping.getMappings()){
+                        if(mapping.ignoreField()){
+                            targetFields.remove(targetField);
+                        } else {
+                            targetFields.add(targetField);
+                        }
+                    }
+                }
+//                log.info("    o targets: "+targetFields);
+//                log.info("    o global text filter: "+globalFilter);
+                if(globalFilter != null){
+                    globalFiltered = new HashSet<Object>(values);
+                    //parse false ass third argument, because we need not to filter
+                    //non-Text values for wildcard filter!
+                    processFilter(globalFilter, globalFiltered,false);
+                }
+                //now process the mappings
+                for(FieldMapping mapping : activeMappings){
+                    if(!mapping.ignoreField() &&
+                            !Collections.disjoint(targetFields, mapping.getMappings())){
+                        processMapping(mapping, field,  values,globalFiltered, targetFields, target);
+//                    } else if(!mapping.ignoreField()) {
+//                        log.info(String.format("  << ignore mapping %s ",mapping));
+//                    } else {
+//                        log.info(String.format("  << %s ",mapping));
+                    }
+                }
+            }
+        }
+        /*
+         * TODO: return a "MappingReport"
+         * All mapping activities should be documented and stored with the
+         * MappedEntity as MappingActivity!
+         */
+        return target;
+    }
+    /**
+     *
+     * @param mapping
+     * @param field
+     * @param values
+     * @param globalFiltered
+     * @param targets
+     */
+    private void processMapping(FieldMapping mapping, String field,  Collection<Object> values, Collection<Object> globalFiltered, Set<String> activeTargets,Representation targetRepresentation) {
+        //parsed mappings are all !ignore and some mappings are active
+        Collection<Object> filtered; //this collection will be modified by the filters later on
+        if(globalFiltered == null || //if no global filter is present and therefore globalFiltered == null or
+                //there is a more special text filter defined in this mapping
+                mapping.getFilter() != null && mapping.getFilter().getType() == ConstraintType.text){
+            filtered = new HashSet<Object>(values);//start with all values
+        } else { //start with the values filtered by the global filter
+            filtered = new HashSet<Object>(globalFiltered);
+        }
+        if(mapping.getFilter()!=null){
+            switch (mapping.getFilter().getType()) {
+            case value:
+                ValueConstraint valueConstraint = (ValueConstraint)mapping.getFilter();
+                processFilter(valueConstraint,filtered);
+                break;
+            case text:
+                TextConstraint textConstraint = (TextConstraint)mapping.getFilter();
+                //for wildcard mappings only filter TextValues. if the mapping is
+                //for a specific field filter also non text values.
+                processFilter(textConstraint,filtered,!mapping.usesWildcard());
+                break;
+            default:
+                log.warn(String.format("Filter of type %s are not supported -> select all values! (Constraint=%s)",
+                        mapping.getFilter().getType(),mapping.getFilter()));
+                break;
+            }
+            /*
+             * TODO: add general purpose functionality to apply Constraints.
+             * Currently this is done by the specific Query Implementations :(
+             *  - use the constraint to filter the values collection!
+             */
 
-	}
-	/**
-	 * This method filters the parsed {@link Text} values based on the languages
-	 * parsed in the {@link TextConstraint}.
-	 * This method modifies the parsed collection by using the 
-	 * {@link Iterator#remove()} method.
-	 * @param textConstraint the text constraint containing the active languages
-	 * @param values the values to filter. This method modifies this collection
-	 * @return the modified collection to allow nested calls
-	 */
-	private Collection<Object> processFilter(TextConstraint textConstraint, Collection<Object> values,boolean filterNonTextValues) {
-		if(textConstraint.getText() != null){
-			log.warn("Filtering based on values is not implemented"); 
-		}
-		/*
-		 * TODO: If filterNonTextValues=true and acceptDefaultLanguate=true 
-		 *       we could also try to convert non-Text values to Text (by using
-		 *       the valueConverter.
-		 */
-		Set<String> langs = textConstraint.getLanguages();
-		boolean acceptDefaultLanguage = textConstraint.getLanguages().contains(null);
-		for(Iterator<Object> it = values.iterator();it.hasNext();){
-			Object value = it.next();
-			if(value instanceof Text){
-				if(!langs.contains(((Text)value).getLanguage())){
-					it.remove();
-//					log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
-//				} else {
-//					log.info(String.format("   + value %s(type:%s) accepted by text filter",value,value.getClass()));
-				}
-			} else if(filterNonTextValues && value instanceof String){
-				//Strings only if the default language is enabled
-				if(!acceptDefaultLanguage){
-					it.remove();
-//					log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
-//				} else {
-//					log.info(String.format("   + value %s(type:%s) accepted by text filter",value,value.getClass()));
-				}
-			} else if(filterNonTextValues){
-				it.remove();
-//				log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
-			} //else non text value and filterNonTextValues=false -> nothing to do
-		}
-		return values;
-	}
-	/**
-	 * This method converts - or if not possible filters the parsed values based
-	 * on the parsed constraint
-	 * @param valueConstraint
-	 * @param values
-	 * @return
-	 */
-	private Collection<Object> processFilter(ValueConstraint valueConstraint, Collection<Object> values) {
-		if(valueConstraint.getValue() != null){
-			log.warn("Filtering based on values is not yet implemented");
-		}
-		//1) collect all active dataTypes
-		//first a EnumSet for really fast containsAll ... operations
-		Set<DataTypeEnum> activeDataTypes = EnumSet.noneOf(DataTypeEnum.class);
-		//second a List to keep track of the ordering of the dataTypes in the
-		//constraint for later conversions!
-		List<DataTypeEnum> sortedActiveDataTypes = new ArrayList<DataTypeEnum>(valueConstraint.getDataTypes().size());
-		//NOTE: using a LinkedHashSet would slow down this code, because EnumSet
-		//  gives constant processing time even for bulk operations!
-		for(String dataTypeUri : valueConstraint.getDataTypes()){
-			DataTypeEnum dataType = DataTypeEnum.getDataType(dataTypeUri);
-			if(dataType == null){
-				log.warn(String.format("DataType %s not supported"));
-			} else {
-				if(activeDataTypes.add(dataType)){
-					//only of set has changed to avoid duplicates in the list
-					sortedActiveDataTypes.add(dataType);
-				}
-			}
-		}
-		//2) now process the values 
-//		log.info(" --- Filter values ---");
-		//calculating acceptable and not acceptable types needs some processing time
-		//and usually values will be only of very less different types.
-		//Therefore it makes sense to cache accepted and rejected types!
-		Set<Class<?>> accepted = new HashSet<Class<?>>();
-		Set<Class<?>> rejected = new HashSet<Class<?>>();
-		//Set that stores rejected values. Such will be converted later on!
-		Set<Object> needConversion = new HashSet<Object>();
-		for(Iterator<Object> it = values.iterator();it.hasNext();){
-			Object value = it.next();
-			if(accepted.contains(value.getClass())){
-//				log.info(String.format("   + value %s(type:%s) accepted by value filter",value,value.getClass()));
-				//nothing to do
-			} else if(rejected.contains(value.getClass())){
-				it.remove(); //remove also the current value of that type
-				needConversion.add(value); //save as value that need to be converted
-//				log.info(String.format("   - value %s(type:%s) rejected by value filter",value,value.getClass()));
-			} else { //new class ... calculate
-				Set<DataTypeEnum> valueTypes = DataTypeEnum.getAllDataTypes(value.getClass());
-				if(valueTypes.removeAll(activeDataTypes)){
-					accepted.add(value.getClass());
-//					log.info(String.format("   + value %s(type:%s) accepted by value filter",value,value.getClass()));
-				} else {
-					rejected.add(getClass());
-					it.remove(); //remove the Item
-					needConversion.add(value); //save as value that need to be converted
-//					log.info(String.format("   - value %s(type:%s) rejected by value filter",value,value.getClass()));
-				}
-			}
-		}
-		//3) try to convert values to the active dataTypes
-//		log.info(" --- Try to Convert rejected values ---");
-		for(Object value : needConversion){
-			Object converted = null;
-			DataTypeEnum convertedTo = null;
-			for(Iterator<DataTypeEnum> dataTypes = sortedActiveDataTypes.iterator(); //iterate over all active dataTypes
-				converted == null && dataTypes.hasNext();){ //while converted still null and more dataTypes to try
-				convertedTo = dataTypes.next();
-				converted = valueConverter.convert(value, convertedTo.getUri()); //try the conversion
-			}
-			if(converted != null){
-//				log.info(String.format("   + value %s(javaType=%s) successfully converted to %s(datatype=%s)",
-//						value,value.getClass().getSimpleName(),converted,convertedTo.getShortName())); 
-				values.add(converted);
-//			} else {
-//				log.info(String.format("   - value %s(javaType=%s) could not be converted"),
-//						value,value.getClass().getSimpleName()); 
-			}
-		}
-		return values;
-	}
-	@Override
-	public DefaultFieldMapperImpl clone() {
-		return new DefaultFieldMapperImpl(this.valueConverter,this.mappings,this.fieldMap, this.wildcardMap);
-	}
-	@Override
-	public int hashCode() {
-		return mappings.hashCode();
-	}
-	@Override
-	public boolean equals(Object o) {
-		return o != null && o instanceof DefaultFieldMapperImpl &&
-			((DefaultFieldMapperImpl)o).mappings.equals(mappings);
-	}
+        } //nothing to do
+        for(String mappedField : mapping.getMappings()){
+            //activeTargets still uses null for the current field
+            // -> this is because wildcard filters can not know the actual field name
+            if(activeTargets.contains(mappedField)){ //so use null to match
+                if(mappedField == null){ //and than replace null with the field name
+                    mappedField = field;
+                }
+//                log.info(String.format("  >> copy%s to %s &d values",
+//                        mappedField.equals(field)?"":" from "+field,mappedField,filtered.size()));
+                targetRepresentation.add(mappedField, filtered);
+//            } else {
+//                log.info(String.format("  << ignore%s %s",
+//                        mappedField.equals(field)?"":"mapping from "+field+"to",mappedField));
+            }
+        }
+
+    }
+    /**
+     * This method filters the parsed {@link Text} values based on the languages
+     * parsed in the {@link TextConstraint}.
+     * This method modifies the parsed collection by using the
+     * {@link Iterator#remove()} method.
+     * @param textConstraint the text constraint containing the active languages
+     * @param values the values to filter. This method modifies this collection
+     * @return the modified collection to allow nested calls
+     */
+    private Collection<Object> processFilter(TextConstraint textConstraint, Collection<Object> values,boolean filterNonTextValues) {
+        if(textConstraint.getText() != null){
+            log.warn("Filtering based on values is not implemented");
+        }
+        /*
+         * TODO: If filterNonTextValues=true and acceptDefaultLanguate=true
+         *       we could also try to convert non-Text values to Text (by using
+         *       the valueConverter.
+         */
+        Set<String> langs = textConstraint.getLanguages();
+        boolean acceptDefaultLanguage = textConstraint.getLanguages().contains(null);
+        for(Iterator<Object> it = values.iterator();it.hasNext();){
+            Object value = it.next();
+            if(value instanceof Text){
+                if(!langs.contains(((Text)value).getLanguage())){
+                    it.remove();
+//                    log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
+//                } else {
+//                    log.info(String.format("   + value %s(type:%s) accepted by text filter",value,value.getClass()));
+                }
+            } else if(filterNonTextValues && value instanceof String){
+                //Strings only if the default language is enabled
+                if(!acceptDefaultLanguage){
+                    it.remove();
+//                    log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
+//                } else {
+//                    log.info(String.format("   + value %s(type:%s) accepted by text filter",value,value.getClass()));
+                }
+            } else if(filterNonTextValues){
+                it.remove();
+//                log.info(String.format("   - value %s(type:%s) rejected by text filter",value,value.getClass()));
+            } //else non text value and filterNonTextValues=false -> nothing to do
+        }
+        return values;
+    }
+    /**
+     * This method converts - or if not possible filters the parsed values based
+     * on the parsed constraint
+     * @param valueConstraint
+     * @param values
+     * @return
+     */
+    private Collection<Object> processFilter(ValueConstraint valueConstraint, Collection<Object> values) {
+        if(valueConstraint.getValue() != null){
+            log.warn("Filtering based on values is not yet implemented");
+        }
+        //1) collect all active dataTypes
+        //first a EnumSet for really fast containsAll ... operations
+        Set<DataTypeEnum> activeDataTypes = EnumSet.noneOf(DataTypeEnum.class);
+        //second a List to keep track of the ordering of the dataTypes in the
+        //constraint for later conversions!
+        List<DataTypeEnum> sortedActiveDataTypes = new ArrayList<DataTypeEnum>(valueConstraint.getDataTypes().size());
+        //NOTE: using a LinkedHashSet would slow down this code, because EnumSet
+        //  gives constant processing time even for bulk operations!
+        for(String dataTypeUri : valueConstraint.getDataTypes()){
+            DataTypeEnum dataType = DataTypeEnum.getDataType(dataTypeUri);
+            if(dataType == null){
+                log.warn(String.format("DataType %s not supported"));
+            } else {
+                if(activeDataTypes.add(dataType)){
+                    //only of set has changed to avoid duplicates in the list
+                    sortedActiveDataTypes.add(dataType);
+                }
+            }
+        }
+        //2) now process the values
+//        log.info(" --- Filter values ---");
+        //calculating acceptable and not acceptable types needs some processing time
+        //and usually values will be only of very less different types.
+        //Therefore it makes sense to cache accepted and rejected types!
+        Set<Class<?>> accepted = new HashSet<Class<?>>();
+        Set<Class<?>> rejected = new HashSet<Class<?>>();
+        //Set that stores rejected values. Such will be converted later on!
+        Set<Object> needConversion = new HashSet<Object>();
+        for(Iterator<Object> it = values.iterator();it.hasNext();){
+            Object value = it.next();
+            if(accepted.contains(value.getClass())){
+//                log.info(String.format("   + value %s(type:%s) accepted by value filter",value,value.getClass()));
+                //nothing to do
+            } else if(rejected.contains(value.getClass())){
+                it.remove(); //remove also the current value of that type
+                needConversion.add(value); //save as value that need to be converted
+//                log.info(String.format("   - value %s(type:%s) rejected by value filter",value,value.getClass()));
+            } else { //new class ... calculate
+                Set<DataTypeEnum> valueTypes = DataTypeEnum.getAllDataTypes(value.getClass());
+                if(valueTypes.removeAll(activeDataTypes)){
+                    accepted.add(value.getClass());
+//                    log.info(String.format("   + value %s(type:%s) accepted by value filter",value,value.getClass()));
+                } else {
+                    rejected.add(getClass());
+                    it.remove(); //remove the Item
+                    needConversion.add(value); //save as value that need to be converted
+//                    log.info(String.format("   - value %s(type:%s) rejected by value filter",value,value.getClass()));
+                }
+            }
+        }
+        //3) try to convert values to the active dataTypes
+//        log.info(" --- Try to Convert rejected values ---");
+        for(Object value : needConversion){
+            Object converted = null;
+            DataTypeEnum convertedTo = null;
+            for(Iterator<DataTypeEnum> dataTypes = sortedActiveDataTypes.iterator(); //iterate over all active dataTypes
+                converted == null && dataTypes.hasNext();){ //while converted still null and more dataTypes to try
+                convertedTo = dataTypes.next();
+                converted = valueConverter.convert(value, convertedTo.getUri()); //try the conversion
+            }
+            if(converted != null){
+//                log.info(String.format("   + value %s(javaType=%s) successfully converted to %s(datatype=%s)",
+//                        value,value.getClass().getSimpleName(),converted,convertedTo.getShortName()));
+                values.add(converted);
+//            } else {
+//                log.info(String.format("   - value %s(javaType=%s) could not be converted"),
+//                        value,value.getClass().getSimpleName());
+            }
+        }
+        return values;
+    }
+    @Override
+    public DefaultFieldMapperImpl clone() {
+        return new DefaultFieldMapperImpl(this.valueConverter,this.mappings,this.fieldMap, this.wildcardMap);
+    }
+    @Override
+    public int hashCode() {
+        return mappings.hashCode();
+    }
+    @Override
+    public boolean equals(Object o) {
+        return o != null && o instanceof DefaultFieldMapperImpl &&
+            ((DefaultFieldMapperImpl)o).mappings.equals(mappings);
+    }
 }