There are assets that are located in other systems (e.g. Vimeo), but should still be findable in the Celum. For this purpose, the plugin creates a "shadow asset", which only stores metadata and a thumbnail - the rest is in the third-party system. To download the asset, a public URL is created.

Provider Configuration

The plugin supports two possible implementation - push and pull. To create a new provider, implement the following interface.

public interface ShadowAssetsProvider {

    String getProviderName();

    String getProviderDescription();

    default List<ShadowAssetsMapping> getShadowAssetsMappings(){
        return null;
    InformationFieldId getInfofieldExternalId();

    Set<InformationFieldId<?>> getInfofieldsToLoad();

    default boolean guessFileCategory() {
        return false;

Additionally, create a Spring Bean located in {home}/appserver/spring/shadowAssetsMapping.xml.

Below you will find an example.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""
       xsi:schemaLocation=  "

  <bean id="googleTestPullShadowAssetsProvider" class="ch.brix.googleTestPullShadowAssetsProvider.GoogleProvider">
    <property name="providerName" value="Pull Test Provider"/>
    <property name="providerDescription" value="Pull Test Provider Description"/>
    <property name="infoFieldExternalId" value="114"/>
    <property name="guessFileCategory" value="true"/>
    <property name="shadowAssetsMappings" ref="testPullShadowAssetsMappings"/>
    <property name="infofieldsToLoad">

  <util:list id="testPullShadowAssetsMappings" value-type="ch.brix.shadowAssets.ShadowAssetsMapping">

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
      <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
          <property name="infofieldId" value="115"/>
          <property name="doUpdateCheck" value="true"/>
          <property name="clearOnEmptyValue" value="true"/>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
      <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
          <property name="infofieldId" value="116"/>
          <property name="doUpdateCheck" value="true"/>
          <property name="clearOnEmptyValue" value="true"/>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
      <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.TextInfofieldMapping">
          <property name="infofieldId" value="119"/>
          <property name="doUpdateCheck" value="true"/>
          <property name="clearOnEmptyValue" value="true"/>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
      <property name="mapping">
        <bean class="ch.brix.shadowAssets.lib.mappingTypes.infofield.NodeReferencingInfofieldMultiMapping">
          <property name="infofieldId" value="118"/>
          <property name="clearOnEmptyValue" value="true"/>
          <property name="exclusive" value="true"/>
          <property name="doUpdateCheck" value="true"/>
          <property name="stringToIdValueTransformer" ref="pullAuthorNodeFinder"/>



type: String, required: yes, default: -

Used for logging and for public url.


type: String, required: yes, default: -

Used for public url.


type: InformationFieldId, required: yes, default: -

Asset infofield to identify shadow assets. Has to be unique for each provider. Only of type Text oder Number.


type: boolean, required: no, default: false

If set to true, the file category of the thumbnail will be overwritten.


type: List of ShadowAssetsMapping, required: no, default: null

For asset metadata mapping.

For noderefs use a NodeFinder. In this case a InfofieldNodeFinder is used to create keyword if it does not exist. The InfofieldNodeFinder searchs by value in the specified infofield, only Text and Number Infofields are supported.

<bean id="pullAuthorNodeFinder" class="ch.brix.lib.nodeFinder.InfofieldNodeFinder">
  <property name="informationFieldId" value="206"/>
  <property name="rootNodeId" value="6"/>

type: Set of InformationFieldId, required: yes, default: -

External id and all mapping infofields


type: Bean, required: no, default: -

Implement the ShadowAssetsComplexMapping interface for complex mapping, see Shadow Assets Vimeo for an example.

public interface ShadowAssetsComplexMapping {

    void doComplexMapping(ShadowAsset shadowAsset, Map<String, Object> details);

Provider Implementation

The following providers are currently available:

Shadow Asset

As a provider you are supposed to provide shadow asset(s). These are defined as follows:


type: AssetTypeId, required: yes (for create), default: -

Defines the asset type of the shadow assets.

Create Update
required assetTypeId not specified: nothing happens
assetTypeId specified: overwrites assettype (with update check)

type: NodeId, required: yes (for create), default: -

Defines in which node the shadow assets are uploaded to.

Create Update
required targetNode not specified: nothing happens
targetNode specified:
- move, if asset has only one permission defining node parent
- link, if asset has multiple permission defining nodes parents

type: String/Number, required: yes, default: -

Id of the shadow asset in the source system. Only String and Number are supported. Required for all CRUD operations


type: String, required: yes (for create), default: -

Used for name in celum and for original filename, if originalFilename is not specified.

Create Update
required name not specified: nothing happens
name specified: overwrites name (with update check)

type: String, required: no, default: -

Used for originalFilename in Celum.


type: String, required: no, default: placeholder file png

Url to download the asset for create / update in Celum.

Create Update (controlled via version)
thumb url not blank: thumb file thumb url not blank: thumb file
thumb url == null: placeholder file thumb url == null: placeholder file
thumb url == "": excption thumb url == "": excption

type: String, required: no, default: -

If available, the original url is used to create a public url.

Create Update
orignalUrl not specified: nothing happens orignalUrl not specified: nothing happens
orignalUrl specified: creates public url orignalUrl specified: overwrites public url (with update check)

[//]: # (todo) additional public url

[//]: # (todo) complex mapping


type: Map of String:List, required: no, default: -

Key and values for ShadowAssetMapping, setting are defined in the provider bean.


type: FiletypeMapping, required: yes (if guessFileCategory = true), default: -

Based on filetypeMapping, file category is set. There are three mapper: by fileExtension, byMimetype or default (png)


type: ShadwoAssetVersion, required: no, default: -

Version defines if a new version is uploaded in Celum. Date, String and Number are supported. Version info is stored in global storage. If the current version in the storage is not the same as in the shadow asset, a new version is uploaded. If no version is defined, no new version will be created.

A note on shading

All mappers, value transformers and node finders are located in the generic package ch.brix.lib. These however get shaded when included in any project to _ch.brix.ARTIFACTID.lib (so ch.brix.shadowAssets.lib in this case) in order to avoid conflicts with other plugins that may use the same libs at different version levels.

When creating a new provider overwrite following shadedPattern in the shade plugin config.

        <shadedPattern>ch.brix.shadowAssets.lib</shadedPattern> <!--  instead of ch.brix.${project.artifactId}.lib  -->

Compatibility Matrix

Shadow Assets CELUM (min. version)
1.2.2 6.4 (tested with 6.13)

Release Notes


Release: 2022-12-01

Initial Version