Class SpringMappings

java.lang.Object
org.openehealth.ipf.commons.map.DefaultMappings
org.openehealth.ipf.commons.spring.map.SpringMappings
All Implemented Interfaces:
Mappings, MappingResourceTarget, Aware, BeanFactoryAware, SmartInitializingSingleton

public class SpringMappings extends DefaultMappings implements MappingResourceTarget, BeanFactoryAware, SmartInitializingSingleton
Mappings configured with Spring resources, and the bean to wire into a Spring application.
<bean id="mappings" class="org.openehealth.ipf.commons.spring.map.SpringMappings">
    <property name="mappingResources">
        <list>
            <value>classpath:gender.mapping.xml</value>
            <value>classpath:encounter.mapping.yaml</value>
        </list>
    </property>
</bean>
A resource is dispatched to a loader by its file extension, so the formats may be mixed freely - whichever modules are on the classpath decide which ones can be read. Where a name does not identify a format - a location without a file extension, a file called gender.xml - set mappingFormat to name one for this bean's resources, or pass it per resource to setMappingResource(Resource, String). Applications add further mappings on top with CustomMappings: this bean collects the MappingResourceHolder beans of the application context itself, so no configurer and no post processor is needed.

Collecting happens in afterSingletonsInstantiated(), i.e. once all singletons have been instantiated and before the ContextRefreshedEvent that starts e.g. the Camel context, so the mappings are complete when routes are built. They are not complete yet while singletons are being initialized: a @PostConstruct method sees only the resources set on this bean directly. Contributions can be ordered relative to each other with Spring's @Order / Ordered on the MappingResourceHolder bean.

Functions that a computed fallback names are a property of this bean, so they are registered while it is created - before any configurer adds a resource that refers to one. A module that ships both a mapping file and the functions it names should contribute a MappingFunctionProvider service instead, and needs no configuration at all.

This holds the model's constraints - and so does SpringBidiMappingService, which reads into one: a duplicate mapping name is an error unless the later declaration says override, and a value with two inverses is an error rather than a reverse lookup that silently answers whichever key was written last. Both can be relaxed with DefaultMappings.setAllowOverride(boolean) and DefaultMappings.setAllowReverseCollisions(boolean) for a source that cannot express the intent.

Since:
6.0
  • Constructor Details

    • SpringMappings

      public SpringMappings()
  • Method Details

    • setBeanFactory

      public void setBeanFactory(@NonNull @NonNull BeanFactory beanFactory)
      Specified by:
      setBeanFactory in interface BeanFactoryAware
      See Also:
    • afterSingletonsInstantiated

      public void afterSingletonsInstantiated()
      Collects the mapping resources of all MappingResourceHolder beans of the application context and its ancestors, honouring their @Order and the format each of them names.
      Specified by:
      afterSingletonsInstantiated in interface SmartInitializingSingleton
    • getMappingResources

      public Collection<? extends Resource> getMappingResources()
      Returns:
      the resources read so far, in the order they were read
    • setMappingResources

      public void setMappingResources(Collection<? extends Resource> resources)
      Description copied from interface: MappingResourceTarget
      Reads every resource and registers the mappings it contains. Which format a resource is in is decided by its file extension.
      Specified by:
      setMappingResources in interface MappingResourceTarget
      Parameters:
      resources - mapping resources
    • setMappingResources

      public void setMappingResources(Collection<? extends Resource> resources, String format)
      Description copied from interface: MappingResourceTarget
      Reads every resource in a format named explicitly, for resources whose name does not identify one - a location without a file extension, or a file called gender.xml.
      Specified by:
      setMappingResources in interface MappingResourceTarget
      Parameters:
      resources - mapping resources
      format - a format id such as xml or conceptmap-r4-json, or null to dispatch by file extension
    • setMappingResource

      public void setMappingResource(Resource resource)
      Reads one resource and registers the mappings it contains.
      Parameters:
      resource - a mapping resource, in any format a loader on the classpath claims
      Throws:
      IllegalArgumentException - if the resource does not exist or cannot be read, and isIgnoreResourceNotFound() is false
      MappingException - if the resource is not valid for its format
    • setMappingResource

      public void setMappingResource(Resource resource, String format)
      Reads one resource in a format named explicitly rather than left to its file extension.

      A resource that has been read before is skipped, which keeps this bean idempotent so that a contribution reaching it both directly and through a deprecated CustomMappingsConfigurer is only evaluated once.

      Parameters:
      resource - a mapping resource
      format - a format id such as xml or conceptmap-r4-json, or null to fall back to setMappingFormat(String) and then to the file extension
      See Also:
    • setMappingFunctions

      public void setMappingFunctions(Map<String, Function<String,String>> functions)
      Registers the functions that a mapping's computed fallback refers to by name, i.e. what <unmatched mode="function" ref="..."/> resolves against. A function receives the key that had no entry and returns the value for it, so a mapping can derive its answer from its input rather than list it.

      A mapping source naming a function that is not registered is rejected as it is read, so register them first. As a property of this bean that happens before any configurer adds a mapping resource - but a resource set on this bean itself is read as soon as it is set, so in a bean definition declare this property before mappingResources.

      Parameters:
      functions - functions by name, replacing any registered under the same name before
    • registerMappingFunction

      public void registerMappingFunction(String name, Function<String,String> function)
      See Also:
    • clear

      public void clear()
      Forgets every mapping and the resources read, so that they can be read again. The functions this bean was configured with stay registered.
      Overrides:
      clear in class DefaultMappings
    • setIgnoreResourceNotFound

      public void setIgnoreResourceNotFound(boolean ignoreResourceNotFound)
      whether a resource that does not exist or cannot be read is skipped instead of failing the context. A resource that exists but is not valid for its format always fails
    • isIgnoreResourceNotFound

      public boolean isIgnoreResourceNotFound()
      whether a resource that does not exist or cannot be read is skipped instead of failing the context. A resource that exists but is not valid for its format always fails
    • setMappingFormat

      public void setMappingFormat(String mappingFormat)
      Names the format of every resource of this bean that is not given one of its own, for resources whose name does not identify a format:
       <bean id="mappings" class="org.openehealth.ipf.commons.spring.map.SpringMappings">
           <property name="mappingFormat" value="conceptmap-r4-json"/>
           <property name="mappingResources">
               <list><value>https://tx.example.org/ConceptMap/gender</value></list>
           </property>
       </bean>
      Set it before the resources, which for a bean definition means declaring the property first. format id, or null to dispatch by file extension
    • getMappingFormat

      public String getMappingFormat()
      Names the format of every resource of this bean that is not given one of its own, for resources whose name does not identify a format:
       <bean id="mappings" class="org.openehealth.ipf.commons.spring.map.SpringMappings">
           <property name="mappingFormat" value="conceptmap-r4-json"/>
           <property name="mappingResources">
               <list><value>https://tx.example.org/ConceptMap/gender</value></list>
           </property>
       </bean>
      Set it before the resources, which for a bean definition means declaring the property first. format id, or null to dispatch by file extension