1. XDIP Structure

The XDIP behaves the same way as file-identification in the AEM file system structure. This structure is based on the Java Content Repository (JCR) specification. The structure used will therefore also be the same url structure as the AEM API with the additional XDIP features.

The XDIP used for the AEM connector will therefore be:

xdip://<aem-configuration-id>/<path>

Table 1. URL Part Descriptions
Part Name Description

configuration-id

The id of the configuration to use.

path

The percent-encoded path to the resource as defined by the AEM API

If no path is specified (e.a. the root of the connector) the /contents folder will be requested by default since this folder contains the most usable content for the connector. The other folders at root level of the application are thus also available and will mostly be used in special cases.

The given path must be Percent encoded, but the forward slashes / should not be encoded with it. If a slash appears in the name of a part, it must be encoded! For example when a page is called: The owners of cats and/or dogs, this should be translated to The owners of cats and%2For dogs beforehand.
Example 1. Several AEM specific URLs

The url to an icon of the geometrixx website:

xdip://aem-001/content/dam/geometrixx/icons/target.png

The URL to the english homepage of the geometrixx outdoors website:

xdip://aem-001/content/geometrixx%20outdoors/en

The URL to the user accounts and their privileges of the geometrixx website:

xdip://aemUsers/home/users/geometrixx

2. Connector Configuration

Each configuration requires a type field as specified by the regarding connector. For the AEM connector this field must be "connector.aem". Furthermore the following fields are accepted or even required:

Name Description

baseUrl

Required. The base URL to the wanted AEM server. For a local instance of AEM this would be: http://localhost:4502

password

Required. The password or personal access token to perform basic authentication with. Some calls do require this field filled in.

username

Required. The username to perform basic authentication with.

Example 2. JSON persistence configuration example.

A possible configuration for the AEM connector using the JSON Persistence. This persistence method is extensively documented in the Connector Framework.

{
    "configurationIdentifier": {
        "type" : "connector.aem",
        "state": {
            "username" : "MyUsername"
        },
        "properties" : {
            "password": "MySuperAwesomeSecretPassword"
        },
        "constants" : {
            "baseUrl": "http://localhost:4052"
        }
    }
}

2.1. State Object

The state object is an object that contains the state retrieved from the Connector Configuration Library. This state is build up from the configuration that was set up before using this connector. See [connector-configuration] how to set up this configuration with possible overrides. See the Connector Framework documentation on how to retrieve the state from the Connector Configuration Library.

Example 3. An example of the representation of the state-object.

The outcome for the state object with the configuration shown in the example of connector configuration at above is as follows:

{
    "type" : "connector.aem",
    "username" : "MyUsername",
    "password": "MySuperAwesomeSecretPassword",
    "baseUrl": "http://localhost:4052"
}

3. Data types

3.1. Required Field

AEM only knows one required field for every type; jcr:primaryType. This type helps identifying the rest of the nodes fields.

3.2. Common Fields

Some fields occur frequently in multiple data types. They appear based on their primaryType:

Table 2. Common Fields
Field Name Description

jcr:created

The creation date of the object

jcr:createdBy

The username of the user which created this object

jcr:data

The binary contents of a file/resource

:jcr:data

Indicates the byte size of the resource. This common field is not well documented. It appears in nt:resource nodes where jcr:data should occur. It appears that this is a placeholder so that a request must explicitly request jcr:data. If this is not explicitly requested, :jcr:data will be returned.

jcr:description

The description of this object

jcr:encoding

The encoding used for this object

jcr:mimeType

The MIME Type of the object

jcr:language

The language of this object

jcr:lastModified

The last modification date of the object

jcr:lastModifiedBy

The username of the user that last modified this object

jcr:mixinTypes

The mixins used for this data (defines required fields and such)

jcr:title

The friendly (human readable) name of this object

3.3. Common Types

AEM has some types that are commonly used. There are many more types available, but most types are derived of the types listed below.

3.3.1. cq:Page

Table 3. cq:Page

Field Name

Type

Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

jcr:content

nt:base (commonly cq:Page or cq:PageContent)

Yes

* zero-or-more of any nt:base object

nt:base (commonly cq:Page)

Yes

3.3.2. cq:PageContent

Table 4. cq:PageContent
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

jcr:language

STRING

No

jcr:title

STRING

No

cq:allowedTemplate

STRING

No

cq:template

STRING

No

cq:lastModified

DATE

No

cq:lastModifiedBy

STRING

No

cq:designPath

STRING

No

pageTitle

STRING

No

navTitle

STRING

No

hideInNav

BOOLEAN

No

onTime

DATE

No

offTime

DATE

No

* zero-or-more of any nt:base object

nt:base (commonly nt:unstructured)

Yes

3.3.3. dam:Asset

Table 5. dam:Asset
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

jcr:content

nt:base (commonly cq:Page or cq:PageContent)

Yes

* zero-or-more of any nt:base object

nt:base (commonly nt:unstructured)

Yes

3.3.4. dam:AssetContent

Table 6. dam:AssetContent
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

metadata

nt:unstructured

Yes

renditions

nt:folder

Yes

3.3.5. nt:hierarchyNode

Table 7. nt:hierarchyNode
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

3.3.6. nt:file

Table 8. nt:file
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

jcr:content

nt:base (commonly nt:resource)

Yes

3.3.7. nt:folder

Table 9. nt:folder
Field Name Type Required

jcr:primaryType

STRING

Yes

jcr:created

DATE

No

jcr:createdBy

STRING

No

* zero-or-more of any nt:base object

nt:hierarchyNode

Yes

3.3.8. nt:resource

Table 10. nt:resource
Field Name Type Required

jcr:data

BINARY

Yes

jcr:encoding

STRING

No

jcr:primaryType

STRING

Yes

jcr:lastModified

DATE

No

jcr:lastModifiedBy

STRING

No

jcr:mimeType

STRING

No

jcr:uuid

STRING

No

3.4. Additional Reference Documentation

A very detailed documentation of this model can be found at: https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html

Standard Application Node Types (identified with the nt: prefix) documentation can be found at: https://docs.adobe.com/content/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.7.11%20Standard%20Application%20Node%20Types

Custom Node Types (identified with the cq: prefix) documentation can be found at: https://docs.adobe.com/docs/en/aem/6-3/develop/platform/custom-nodetypes.html

4. UDM Content Types

4.1. Page

A page is literally a (sub) web page of a site. AEM has the convention to have Pages as children of a Page which contain a subsection of that page (e.g. a header). These sites are located in the root of the contents folder with the site-name as filename. A page will probably have the following decorators:

  • name

  • description

  • created

  • modified

  • parent

  • container

  • objectLocation

4.2. File

A file is a binary document within the AEM repository. These are usually located in the dam folder. It will probably have the following decorators:

  • name

  • created

  • modified

  • file

  • parent

  • mimeType

4.3. Folder

A folder is a general part of the AEM Repository structure. It will probably have the following decorators:

  • name

  • container

  • parent

  • folder

5. Mappings

These are the general mappings of AEM JCR fields to our corresponding UDM Standard Decorators.

Field Name UDM Mapping

cq:lastModified

modified.date

cq:lastModifiedBy

modified.by

dam:comments

description.short

dam:FileFormat

file.extension

dam:sha1

hash.sha1

dc:description

description.short

dc:format

file.extension

dc:modified

modified.date

:jcr:data

file.size

jcr:created

created.date

jcr:createdBy

created.by

jcr:description

description.short

jcr:lastModified

modified.date

jcr:lastModifiedBy

modified.by

jcr:mimeType

mimeType.type

jcr:title

name.displayName

metadata

properties

uuid

properties

6. Connector Layer: UDM

Some assumptions are made to optimize the AEM connector. The assuptions made include:

  • The properties of an object will be set only via the metadata and jcr:content.

  • getChildren and getObject fetch information at the deepest level possible. If this level is reached a debug-message is printed. Note: Because of this behavior it might occour that some information will not be fetched. Deep nested structures in the dam folder are discouraged.

  • If the original file of a dam:Asset is fetched, the filename will be extracted from the url. For example if /content/dam/geometrixx/portraits/scott_reynolds.jpg/jcr:content/renditions/original is called by getChildren or getObject the filename will be scott_reynolds.jpg. The filename is found by searching for the first file in the url from right to left. This means that it is not allowed to have folders containing a dot (.) within the dam:Asset structure. Folders with dots (.) in the url before the file+extension are allowed.

  • Files are only of the type nt:file, nt:resource and dam:Asset

  • The data for the files are added through checking where its metaData stands. This is in the case of a dam:Asset in data.content["jcr:content"]["renditions"]["original"]["jcr:content"][":jcr:data"]. Its jcr:mimeType is listed there as well. In case of a general file (nt:file or nt:resource) we will recursively search for the :jcr:data and mimeType fields.

  • Folders are only of the type nt:folder, sling:Folder and sling:OrderedFolder

  • Properties that have a ':' (colon) in the name or are ATOMIC values are excluded from being children.

  • Objects with the Page content-type will only have 'Container.hasChildren' equal to true if it contains one or more object with the cq:Page type.

6.1. Retrieval Functions

6.1.1. getChildren(url, state)

Description

Returns the children of the given object located at the url.

Parameters
Name Description

url

Required. The url, using the [xdip], that addresses the item that is to be accessed.

state

Required. The State Object.

Example Usage
use System;
include connector.aem.udm.UDM;

var stateObject = {
    "type": "connector.aem",
    "username": "admin",
    "password": "admin",
    "baseUrl": "http://localhost:4502"
};

// Returns the children of the 'content' directory
var result = getChildren(
    "xdip://aem-connector-1/content/",
    stateObject);
System.print(result);

6.1.2. getBinaryContents(url, state)

Description

Returns a json object with the metadata of the file located at the given url.

Parameters
Name Description

url

Required. The url, using the [xdip], that addresses the item that is to be accessed.

state

Required. The State Object.

Example Usage
use System, Stream;
include connector.github.udm.UDM;

var stateObject = {
    "type": "connector.aem",
    "username": "admin",
    "password": "admin",
    "baseUrl": "http://localhost:4502"
};

var filePath = "/content/dam/geometrixx-media/articles/en/2012/August/the-only-festival-playlist-you-need.txt";

var result = getBinaryContents(
    "xdip://aem-connector-1" :: filePath,
     stateObject);
System.print(result);

6.1.3. getObject(url, state)

Description

Returns the object located at the url in the UDM format.

Parameters
Name Description

url

Required. The url, using the [xdip], that addresses the item that is to be accessed.

state

Required. The State Object.

Example Usage
use System;
include connector.aem.udm.UDM;

var stateObject = {
    "type": "connector.aem",
    "username": "admin",
    "password": "admin",
    "baseUrl": "http://localhost:4502"
};

// Gets the 'content' folder object.
var result = getObject("xdip://aem-connector-1/content", stateObject);
System.print(result);

6.2. Mutational Functions

6.2.3. createObject(document, binaryContent, state)

Description

Creates the provided object based on binaryContent at the location derived from document and returns the state of the new document as an UDM object.

Parameters
Name Description

document

Required. The UDM document containing at least a valid name and parent decorator.

binaryContent

Required. The stream containing the JCR object used to create the object. The JCR object needs to contain at least a valid "jcr:primaryType" value.

state

Required. The State Object

Example Usage
use System, Stream,String;

include connector.aem.udm.UDM as udm;

var state = {
    "type" : "connector-aem",
    "baseUrl" : "http://localhost:4502",
    "username" : "admin",
    "password" : "admin"
};

/**
 * This example is an invalid UDM document, but it contains the data necessary to perform this
 * operation.
 **/
var document = {
    "target" : {
        "current" : {
            "name" : {
                "systemName" : "myNewBanner.png"
            },
            "parent" : {
                "id" : "xdip://aem001/content/dam/geometrixx/banners"
            }
        }
    }
};

// The object to create
var jcrObject = {
    "jcr:primaryType" : "nt:file",
    "jcr:content" : {
          "jcr:primaryType" : "nt:resource",
          "jcr:mimeType" : "image/png",
          "jcr:data" : String.stream(binaryFile)
    }
};

var binaryContents = String.stream(System.toJSON(jcrObject));

var udm = udm->createObject(document, binaryContents, state);

System.print(System.toJSON(udm, true));

// The image to create in AEM
var binaryFile = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABdElEQVQ4jY3Sr4tVQRjG8c9cDDuy
                  wXAxyCKyLJ5FjCI2g1sU/FENNlGbRYNBYRGDwaAgIiIIshZBxOAfsGUNJjXcMVxNsqAYRDwXwxnD
                  GXE9e7zuC8MwzzvzfZ93ZthiJFESryXx80hcS+I8DJJ4MIk3k7gwDZDZj2UMA4dwHbZlVgIL2Ifj
                  /wIEJmgwKNIPGAQeYx3DkbhriolZvCrjCa4UcNuf1sVdXMYbLGI33hfAfZyu1F87zv5EEod4iO1Y
                  KnKDTzhcqcddW4ONi0r9BWMsZXmU5TtZXsccjvX1NejRTmS5IR9dNLkohDNFP7klQOZ7q4f5Iv2e
                  m3JXf0XoCiPxbOBBln+WdvaGdtujzM7A09wWPhK4twlQqlzAreJwjKt4hhmcw+2y/eMmQHExhxuB
                  85hU6o252cBb7MGLPgczuIR3lfp5X4Ek7tD+3NfdxDCJH5KYk7jSd7gb3Vc4UKzBqST2PfNUwCpe
                  Zvkblit18z/ALwsIZinuRiMtAAAAAElFTkSuQmCC";

6.2.4. deleteObject(url, state)

Description

Deletes the object located at the url.

Parameters
Name Description

url

Required. The url, using the [xdip], that adresses the item that is to be deleted.

state

A State Object

Example Usage
use System;
include connector.aem.udm;

var stateObject = {
    "type": "connector.aem",
    "username": "admin",
    "password": "admin",
    "baseUrl": "http://localhost:4502"
};

// Deletes a testFile in the 'content' directory
deleteObject(
    "xdip://aem-connector-1/content/testFile",
    stateObject);