Page tree
Skip to end of metadata
Go to start of metadata

Introduction

The DAM API in 5.0 will primarily be used in templating, templates and models. It provides read-only access to assets managed by the DAM-Asset-App.
Assets may be stored internally (into the dam workspace), but eventually could also come from external storage providers.

In the 5.0 version we will only provide support for assets stored in the dam workspace: so called "jcr" assets.

The DAM API in Magnolia 5.0 provides the basic mechanism for an abstraction of the storage location of an Asset. 

DAM Module

Main features provided by the DAM API:

  • Support referring to an asset using a compsite key with two pieces of information: the id of its provider, and the provider-specific asset id. This enables the API to treat all assets the same, independent of the asset storage location.
  • Introduce the concept of an original. When a file is uploaded to the dam we create an asset and an original. The original contains the binary data uploaded and is never changed.
  • Expanding on the Metadata support of the DMS. By default we support the DublinCore specification, and open the API in order to support other Metadata standards (such as IPTC). 

High level architecture

Class Diagram


This class diagram introduces the five main concepts of the DAM-API.

  • DamManager: The main entry point of the API. Its responsibility is to, given an AssetId, find the correct AssetProvider and to provide the specified Asset.
  • AssetProvider: Implemented classes are responsible to populate  Asset  properties based on a specific storage. In Magnolia 5.0 we provide a default JcrAssetProvider that creates Asset based on JCR nodes.
  • Asset: Implemented classes are simple POJOs that contains all the information needed to manipulate and display Asset (including binary content and Metadata access).
  • AssetMetadata:  By requirement, an Asset may be linked with any Metadata standard (An Asset may have DublinCore and Exif Metadata).  This API gives us the possibility to access from an Asset any supported Metadata type.
    (warning) Magnolia 5.0 Only supports DublinCore Metadata.
  •  Rendition: A Rendition is a transformation of an Asset. The Rendition is provided by an AssetRendererRenderer are configured per media type.
Main components
DamManager

This is the entry point for third parties. For example DamManager is used by StkTemplatingFunction to retrieve Assets.

Class Diagram

 

In DamManageran Asset is identified by:

  • compositeKey : This is a composite Identifier. The first part of the identifier refers to the AssetProvider Id and the second part to the Asset Id.
    In this case, the DamManager directly calls the defined AssetProvider to retrieve the Asset.
  • folderIdentifier : In this case, the DamManager will iterate all registered AssetProvider which are active in order to get an Asset or List of Asset .

(warning) In order to manipulate composite Id, we provide the utility class DamIdParser that should be used to create, check, or get assetProviderIdentifier or assetIdentifier from a compositeKey.

Access DamManager from a custom Module:

Add a dependency from your custom Module to DAM (adapt your pom.xml and moduleDescriptor.xml files)
Simply inject or get  the DamManager.

    private DamManager damManager;
    // BY Injection
    @Inject
    public CustomFunction(DamManager damManager) {
        this.damManager = damManager;
    }
    // OR by using Components
    public void myCustomMethod() {
        this.damManager = Components.getComponent(DamManager.class);
    }
AssetProvider

A class that implements AssetProvider is responsible for creating an Asset based on a specific storage or service. For example, JcrAssetProvider provides assets from the "dam" JCR workspace.

Class Diagram


An AssetProvider retrieves an Asset based on either:

  • assetIdentifier : The second part of the compositeKey without the assetProviderIdentifier. In case of JCR strategy, this assetIdentifieris the Node Identifier.
  • folderIdentifier : For example in a JCR context, either an Asset Node Path or an AssetFolder Node Path.

AssetProvider uses AssetBuilder and AssetMetadataBuilder in order to convert a JCR Node to an Asset and AssetMetadata.

Asset

As mentioned previously, an Asset is a simple POJO with getters and setters (setters are exposed in AbstractBaseAsset). It's the responsibility of the specific AssetProvider to correctly set/get the properties. Based on the assetMetadataType, the AssetProvider has to create the correct implementation of the specified AssetMetadata.

Class Diagram

 

An Asset is built by AssetProvider using AssetBuilder and AssetMetadataBuilder.  

AssetMetadata

Based on the specified assetMetadataType, the specific assetMetadata implementation is created and linked to the Asset.

As the assetMetadata linked to an asset can be change at any moment, the assetMetadata.getMetadata(...) has to be dynamically performed: Following a code snipped of that perform the call,

    @Override
    public AssetMetadata getMetadata(String metadataType) throws AssetMetadataTypeNotSupportedException {
        return assetMetadataBuilder.createAssetMetadata(assetNode, metadataType);
    }
Rendition and Media Types

A MediaType is defined based on the Asset MimeType.  This MediaType is related to an AssetRenderer. An AssetRenderer is responsible for things like creating the correct Rendition link (Equivalent to the Magnolia 4.5.x Variation link).

Media Types

DamModule is responsible to perform the link between the MimeType and MediaType. This is done based on configuration and Voters (RegexVoter).

Supported MediaType :

MediaTypeRegexVoter
Imageimage/.*
Audioaudio/.*
Videovideo/.*
Documenttext/.*
application.*(powerpoint)
application.*(msword)
application.*(excel|xls)
application/pdf
Flashapplication/x-shockwave-flash
Applicationapplication/.*

Expand MediaType Mapping Configuration

Requirement: Handle 'wordperfect' as Document
Add a Voter contentNode under configuration/modules/dam/config/mediaTypes/document/voter/wrodperfect_voter
   Define a regEx pattern applicable for wordperfect mimeTypes (like 'application/wordperfect.') and set it under the pattern property.
   Set the property level to 2.
   (warning) This is mandatory as we already have a voter pattern defined for Application MediaType that is applicable for this mimetype ('application/.').
         Otherwise DamModule  will have two Available MediaType with the same Voter value, and the first found will be returned.   

Requirement: Handle 'json' as JsonApplication
Add a json contentNode under configuration/modules/dam/config/mediaTypes/json
  Create a rendererClass pointing to your own implementation of AssetRenderer
  Add a Voter contentNode under configuration/modules/dam/config/mediaTypes/json/voter
      Define a regEx pattern applicable for json mimeTypes (like 'application/json') and set it under the pattern property.
      Set the property level to 2.


Rendition

By default all MediaType are linked to an JcrAssetRenderer class. During STK installation the Dam configuration is modified, and STK set an STKAssetRenderer for Image MediaType. This specific AssetRenderer support the  STK and Imaging Variation concept.

Jcr AssetProvider Implementation (Asset stored in the DAM workspace)

Magnolia version 5.0 includes one implementation of the AssetProvider class for working with Assets stored in the "dam" workspace: JcrAssetProvider.
Following are details on this implementation:

Dam workspace structure and node definition

Current DAM workspace hierarchy structure:

mgnl:asset

Contains all Asset main properties, and also all non MagnoliaAssetMetadata properties like DublinCoreAssetMetadata properties.

mgnl:resource

Contains the Binary and all MagnoliaAssetMetadata properties.

Asset to JCR Node mapping
NodeProperty NameAsset GetterDescription
mgnl:assetnot related to a property
mgnl:asset.getName()
Asset.getName()Jcr Asset Node Name
mgnl:assetlanguageAsset.getLanguage()String representation of Local http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
mgnl:assetnot related to a property
CompositeAssetId
Asset.getIdentifier()Composite Id build using :
DamIdParser.createCompositeId(InternalAssetProvider.PROVIDER_ID, assetNode.getIdentifier())
mgnl:assettitleAsset.getTitle()Title of the Asset
mgnl:assetmediaTypeAsset.getMediaType()The MediaType is defined based on the mimeType.
Current Defined MediaType: Audio, Video, Image, Document, Application, Flash
mgnl:assetsubjectAsset.getSubject()Subject of the Asset.
mgnl:assetdescriptionAsset.getDescription()Description of the Asset.
mgnl:assetcaptionAsset.getCaption()Caption of the Asset.
mgnl:assetcopyrightAsset.getCopyright()Copyright definition of the Asset.
mgnl:assetcommentAsset.getComment()Comment defined on the Asset.
mgnl:assetmgnl:lastModifiedAsset.getLastModified()Last modification date of an Asset.
jcr:contentjcr:mimeTypeAsset.getMimeType()Mime Type of the Asset (red star)
jcr:contentextensionAsset.getFileExtension()File Extension (.ppt) of the Asset(red star)
jcr:contentfileNameAsset.getFileName()File Name of the Asset(red star)
jcr:contentsizeAsset.getFileSize()Size of the Asset in Bytes. (red star)
jcr:contentjcr:dataAsset.getContentStream()Asset content returned as a java.io.InputStream
mgnl:assetnot related to a propertyAsset.getPath()Asset path.
assetNode.getPath()
mgnl:assetnot related to a propertyAsset.getAssetProviderIdentifier()Identifier of the related AssetProvider
InternalAssetProvider.PROVIDER_ID
mgnl:assetnot related to a propertyAsset.isDeleted()boolean indicating if the Asset Node is marked as Deleted.
NodeUtil.isNodeType(assetNode,NodeType.Deleted.NAME)
mgnl:assetnot related to a propertyAsset.getCustomProperty(String propertyName)Return the related asset propertyName value as an Object if defined on the  Asset Node.
Exception JCR properties having name stating jcr: with or mgnl: will never be returned (they are not custom properties) .

(red star) Fields marked with this star are required to be at this Node Level Hierarchy (mgnl:asset.jcr:content) by the current implementation of the Imaging module. 
They will be moved under the mgnl:asset node level in the next iteration of the implementing phase when the Imaging module will be updated to work with the Asset. 

AssetMetadata to JCR Node mapping

MagnoliaAssetMetadata

NodeProperty NameAsset GetterDescription
jcr:contentheightAsset.getHeight()File Height of the Asset in case of an Image MediaType  (red star)
jcr:contentwidthAsset.getWidth()File Width of the Asset in case of an Image MediaType (red star)

DublinCoreAssetMetadata

For additional Information, refers to the DublinCore specification.

NodeProperty NameAsset GetterDescription
mgnl:assetlanguageDublinCoreAssetMetadata.getLanguage()The returned value is equivalent to : Asset.getLanguage()
mgnl:assettitleDublinCoreAssetMetadata.getTitle()The returned value is equivalent to : Asset.getTitle()
mgnl:assetsubjectDublinCoreAssetMetadata.getSubject()The returned value is equivalent to : Asset.getSubject()
mgnl:assetdescriptionDublinCoreAssetMetadata.getDescription()The returned value is equivalent to : Asset.getDescription()
mgnl:assetcopyrightDublinCoreAssetMetadata.getRight()The returned value is equivalent to : Asset.getCopyright()
jcr:contentjcr:mimeTypeDublinCoreAssetMetadata.getFormat()The returned value is equivalent to : Asset.getMimeType()
mgnl:assetnot related to a property
CompositeAssetId
DublinCoreAssetMetadata.getIdentifier()The returned value is equivalent to : Asset.getIdentifier()
mgnl:assetcreatorDublinCoreAssetMetadata.getCreator()An entity primarily responsible for making the resource.
mgnl:assetmgnl:lastModifiedDublinCoreAssetMetadata.getDate()The returned value is equivalent to : Asset.getLastModified()
mgnl:assetcontributorDublinCoreAssetMetadata.getContributor() An entity responsible for making contributions to the resource.
mgnl:assetcoverageDublinCoreAssetMetadata.getCoverage()

The spatial or temporal topic of the resource, the spatial applicability
of the resource, or the jurisdiction under which the resource is relevant

mgnl:assetpublisherDublinCoreAssetMetadata.getPublisher()An entity responsible for making the resource available.
mgnl:assetrelationDublinCoreAssetMetadata.getRelation()A related resource.
mgnl:assetsourceDublinCoreAssetMetadata.getSource()A related resource from which the described resource is derived.
mgnl:assettypeDublinCoreAssetMetadata.getType()The returned value is equivalent to : Asset.getMediaType()
The MediaType is defined based on the mimeType.

 

Dam Utility Class

Dam API provides two main utility class:

  • a DamTemplatingFunction used in templates or in model class. Gives direct access to Asset's and define useful methods.
  • a AssetMap used in templates in order to directly call Asset's properties (like ContentMap)

DamTemplatingFunction

DamTemplatingFunction  can easily be injected in Model Class

    @Inject
    public CustomFunction(DamTemplatingFunctions damTemplatingFunction) {
        this.damTemplatingFunction = damTemplatingFunction;
    }
    public Asset getAsset(String assetIdentifier) {
        return this.damTemplatingFunction.getAssetRenditionForAssetId(assetIdentifier, "renditionName");
    }

and by default accessed like 'cmsfn' or 'stkfn' from FTL's templates using 'damfn'.

[#assign asset = damfn.getAssetForId(content.link)]
[#assign assetMap = damfn.getAssetMapForAssetId(content.link)]

If your module is not dependent from STK, add to your renderer definition

Requirement: Your module should depend on Dam module.

Add a damfn damfn contentNode under configuration/modules/my-module/renderers/myModule/contextAttributes/
   Define a componentClass property pointing to the DamTemplatingFunction class.
   Set the property name to the name you with to use in templates to access this DamTemplatingFunction.

 

AssetMap

 AssetMap can easily be accessed using DamTemplatingFunction and allows an easy access to Asset's properties and Metadatas.

FTL's
[#assign assetMap = damfn.getAssetMapForAssetId(content.link)]    

<br>assetMap.title = ${assetMap.title}
<br>assetMap.metadata.dc.title = ${assetMap.metadata.dc.title}
Access to your custom properties

Assume that you extend the DAM Asset App and decide to add two custom Text fields called 'longComment' and 'reviwer'.
From now on, when you will use the DAM Asset App to create a new Asset, this two properties will be added to the JCR Asset Node as properties (if the value is not blank).
To access these custom properties you have two options:  

From a Java Class (Model Class) using Asset.getCustomProperty(String propertyName):Object

    private DamManager damManager;
    // BY Injection
    @Inject
    public CustomFunction(DamManager damManager) {
        this.damManager = damManager;
    }
    
    public Object myCustomProperty(String assetId, String customPropertyName) {
        Asset asset = damManager.getAssetForId(assetId);
        return asset.getCustomProperty(customPropertyName);
    }

From Templates, using AssetMap.longComment

Exposed Methods in detail

Introduction of the main method exposed by the DAM API.

DamManager
ReturnMethod
AssetgetAssetForId(String assetIdentifier)

Retrieve an Asset based on an assetIdentifier. Deleted/Hidden Asset will not be returned.
For DAM Asset  the assetIdentifier   is a composite key looking like jcr:178effda-d054-4a5a-a8f0-f0546754484e

AssetgetAssetForPath(String assetPath)

Retrieve an Asset based on an Asset path. Deleted/Hidden Asset will not be returned.
Logic:
Iterate the registered provider.
For every active provider call AssetProvider.getAssetIdentifierForPath(String assetPath) and keep the result if not null.
  If one and only one result found, return the related Asset.
  In no results or more than one result found, log and return null.
For DAM Asset  the assetPath  is an absolute JCR path looking like /demo-project/images/assetImage1

List<Asset>getAssetsFromFolderId(String folderIdentifier)

Retrieve an Asset List based on a folder identifier. Like the assetIdentifier, the folder identifier is a composite key (jcr:178effda-d054-4a5a-a8f0-f0546754484e).
Deleted/Hidden Asset will not be returned.

List<Asset>getAssetsForFilter(AssetFilter assetFilter)

Retrieve an Asset List based on an AssetFilter. This implementation supports multi-asset type (asset linked to different providers).
Logic:
Iterate the registered provider.
  For every active provider call AssetProvider.getAssetsForFilter(AssetFilter assetFilter).
  Concatenate the results.

Current AssetFilter properties:
 folderPath : '/demo-project/img/bk/Opener/%'
     will only return assets found under this folder.
 extension  :  'jpg' 
     will only return assets with the specified extension.

AssetMapgetAssetMap(Asset asset)

Return the AssetMap representation of the AssetAssetMap is mainly used in Templates to simplify data access.

DamTemplatingFunctions
ReturnMethod
List<Asset>

getAssetsFromFolderId(String folderIdentifier)

Retrieve an Asset List based on a folder identifier. Like the assetIdentifier, the folder identifier is a composite key (jcr:178effda-d054-4a5a-a8f0-f0546754484e).
Deleted/Hidden Asset will not be returned.

AssetMapgetAssetMap(Asset asset)

Return the AssetMap representation of the AssetAssetMap is mainly used in Templates to simplify data access.

AssetMapgetAssetMapForAssetId(String assetIdentifier)

Return the AssetMap representation of the Asset identified by the requested assetIdentifier. AssetMap is mainly used in Templates to simplify data access.

AssetgetAssetForPath(String assetPath)

Retrieve an Asset based on an Asset path. Deleted/Hidden Asset will not be returned.

AssetgetAssetForId(String assetIdentifier)

Retrieve an Asset based on an assetIdentifier. Deleted/Hidden Asset will not be returned.

AssetgetAssetRendition(Asset asset, String renditionName)

Return the specified Asset Rendition for the passed Asset
In case of no Rendition found, return the same Asset.
Return null in case of Exception.

AssetgetAssetRenditionForAssetId(String assetIdentifier, String renditionName)

Return the specified Asset Rendition based on the assetIdentifier.
In case of no Rendition found, return the same Asset.
Return null in case of exception or if assetIdentifier is null or blank.
(warning) This is the equivalent of the previous STKTemplatingFunctions.getAssetVariation(...

String

getAssetLinkForId(String assetIdentifier)

Return the Link to the specified Asset for a given assetIdentifier.
Return null in case of exception or if Asset was not found.

String

getAssetLinkForId(String assetIdentifier, String renditionName)

Return the Link to the specified Asset Rendition for a given assetIdentifier.
Return null in case of exception if Asset or Asset Rendition was not found.

Migration from DMS to DAM

Within M5, all binary content are handled by the DAM module. We provide several migration tasks that let you migrate DMS or Data binary repository to DAM workspace. 

Additional informations.

 

Interaction with STK

DAM API is fully integrated within Standard Templating Kit (STK). 

Let us consider an arbitrary TextImage component that resides on the page. Its image part is backed up by an asset. In order to be rendered the following steps have to be completed:

  • STK which provides the template for our TextImage component makes a queries the DAM module for an asset. 
    • The argument of the query is the asset assetIdentifier which is stored in the "image" property of TextImage.
      Remember that , assetIdentifier is a composite id  (for a JcrAssetProvider this id will look like jcr:178effda-d054-4a5a-a8f0-f0546754484e)
    • STK model (TextImageModel) obtain the reference to the DAM module through the injected DamTemplatingFunctions
      This function is bounded to a DamManager implemented class which acts as a dispatcher for assets.
  • (1)  DamTemplatingFunctions will retrieve the Original Asset
    • DamManager define the appropriate AssetProvider to use  (referenced in assetIdentifier : first part of the composite key).
    • AssetProvider assembles the Asset based on specific storage location.
      • Provides direct access to binary media data (again, typically - from the internals of asset node but potentially - from external places as well).
    • Asset is returned to DamTemplatingFunctions.
  • (2) Based on the MediaType the DamModule define with AssetRenderer  should be used
         In this case it's the STKAssetRenderer
    • STKAssetRenderer will create a Rendition
      Rendition requires context info (e.g. current site/current theme). For Images STK implement it's own AssetRenderer , STKAssetRenderer:
      This STKAssetRenderer Override the getRendition(... method in order to create a specific Rendition that contain the correct Rendition image link.
  • During rendering phase asset Rendition is used to generates a URL to the generated image.

 

 

Get an Asset Pojo from a Template model

From your Model class or any business logic class:

    // Get the DamTemplatingFunctions
    private DamTemplatingFunctions damTemplatingFunction;
    // Or based on your need
	// Get the DamManager
    private DamManager damManager;
	
    // BY Injection
    @Inject
    public CustomFunction(DamManager damManager, DamTemplatingFunctions damTemplatingFunction) {
        this.damManager = damManager;
		this.damTemplatingFunction = damTemplatingFunction;
	 }
    // OR by using Components
    public void myCustomMethod() {
        this.damManager = Components.getComponent(DamManager.class);
		this.damTemplatingFunction = Components.getComponent(DamTemplatingFunctions.class);
	 }

    public Asset getAsset() {
		String assetIdentifier = PropertyUtil.getString(content, getImageName());
 		return damManager.getAssetForId(assetIdentifier);
    }

    public AssetMap getAssetMap() {
		String assetIdentifier = PropertyUtil.getString(content, getImageName());
 		return damTemplatingFunction.getAssetMapForAssetId(assetIdentifier);
    }

Uses of Asset in FTL's

[#assign assetMap = damfn.getAssetMapForAssetId(content.link)]    
[#assign asset = damfn.getAssetForId(content.link)]
[#assign assetMap2 = model.getAsset()]
[#assign asset2 = model.getAssetMap()]
...

Deprecation

All STKTemplatingFunctions.getAsset..  methods are now deprecated. Use instead DamTemplatingFunctions.get....

Also from Model class, please refer to DamTemplatingFunctions.get....

 

 

  • No labels