---
title: 'Shadow Assets'
url: 'https://doc.brix.ch/celum_extensions/shadow_assets'
markdown: 'https://doc.brix.ch/celum_extensions/shadow_assets.md'
lang: en
date: '2026-10-26'
description: 'Technical documentation for the CELUM Extension "Shadow Assets" – Software developed by brix'
taxonomy:
  category:
    - docs
---

[](#) 

  [ Welcome ](https://doc.brix.ch/)     [ CELUM Extensions ](https://doc.brix.ch/celum_extensions)      Shadow Assets    

# Shadow Assets

![Advanced-UI](https://img.shields.io/static/v1?label=UI&message=Advanced&color=lightgrey)

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.

#### Table of Contents

- [Provider Configuration](#provider-configuration)
- [Shadow Asset](#shadow-asset)
- [A note on shading](#a-note-on-shading)
- [Compatibility Matrix](#compatibility-matrix)
- [Release Notes](#release-notes)

## Provider Configuration

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

```java
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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation=  "http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/util
                            http://www.springframework.org/schema/util/spring-util-4.0.xsd">

  <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">
      <list>
        <value>114</value>
        <value>115</value>
        <value>116</value>
        <value>118</value>
        <value>119</value>
      </list>
    </property>
  </bean>

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

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
                value="size"/>
      <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>
      </property>
    </bean>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
                value="modifiedTime"/>
      <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>
      </property>
    </bean>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
                value="description"/>
      <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>
      </property>
    </bean>

    <bean class="ch.brix.shadowAssets.ShadowAssetsMapping">
      <property name="field"
                value="author"/>
      <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"/>
        </bean>
      </property>
    </bean>

  </util:list>

</beans>
```

##### providerName

> type: String, **required: yes**, default: -

Used for logging and for public url.

##### providerDescription

> type: String, **required: yes**, default: -

Used for public url.

##### infoFieldExternalId

> type: InformationFieldId, **required: yes**, default: -

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

##### guessFileCategory

> type: boolean, required: no, default: false

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

##### shadowAssetsMappings

> 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.

```xml

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

```

##### infofieldsToLoad

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

External id and all mapping infofields

##### complexMappings

> type: Bean, required: no, default: -

Implement the ShadowAssetsComplexMapping interface for complex mapping, see [Shadow Assets Vimeo](https://docs.brix.ch/celum_extensions/shadow_assets/shadow_assets_vimeo#Example) for an example.

```java
public interface ShadowAssetsComplexMapping {

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

### Provider Implementation

The following providers are currently available:

- Shadow Assets Vimeo Provider ([Documentation](https://docs.brix.ch/celum_extensions/shadow_assets/shadow_assets_vimeo))

## Shadow Asset

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

##### assetTypeId

> 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) |

##### targetNodeId

> 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 |

##### externalID

> 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

##### name

> 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) |

##### originalFilename

> type: String, required: no, default: -

Used for originalFilename in Celum.

##### thumbURL

> 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 |

##### originalURL

> 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

##### metadata

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

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

##### filetypeMapping

> 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)

##### version

> 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.ARTIFACT*ID.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.

```xml
<relocations>
    <relocation>
        <pattern>ch.brix.lib</pattern>
        <shadedPattern>ch.brix.shadowAssets.lib</shadedPattern> <!--  instead of ch.brix.${project.artifactId}.lib  -->
    </relocation>
</relocations>
```

## Compatibility Matrix

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

## Release Notes

#### 1.2.2

> Release: 2022-12-01

Initial Version

 [ ](https://doc.brix.ch/celum_extensions/carbon_copy_plus) [](https://doc.brix.ch/celum_extensions/shadow_assets/shadow_assets_vimeo)

---

## Navigation

- Parent: [CELUM Extensions](https://doc.brix.ch/celum_extensions.md)
- Previous: [Carbon Copy Plus (Premium)](https://doc.brix.ch/celum_extensions/carbon_copy_plus.md)
- Next: [Batch Search And Apply Metadata](https://doc.brix.ch/celum_extensions/batch_search_and_apply_metadata.md)
- Children:
  - [Shadow Assets Vimeo Provider](https://doc.brix.ch/celum_extensions/shadow_assets/shadow_assets_vimeo.md)
