Shadow Assets

Advanced-UI

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


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

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

<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