How to work with Document Metadata extensions

Hi,
i was asked to repeat my questions here so everyone can get an answer, so here they are:

as documented here Redirecting… we want to extend the document metadata.

  • is there a way to get the SME display the fields of the metadata?
  • I assume we should put new fields to the “extensions” group?
  • How can we then access them again? I do not see getters for extensions in e.g. DataServicesDocumentMetadata, did I overlook something or should it be done different?
  • Can you maybe extend the documentation a little?

Thanks and Cheers
Jana

Moin @jana-nimble-larch,

:information_source: I used 2025.06 with DocumentV2, this should work in a similar way with 2024.06 as well.

you can provide custom metadata and have proper getters in the following way:

  1. You have to override the default metadata Document Model by following the documentation GetA12 Login. This means e.g. adding your custom metadata Document Model (document-meta-data.json (6.3 KB)) under server/app/src/main/resources/com/mgmtp/a12/platform/model/document-meta-data.json. This path is based on the Project Template, so it might differ, but it’s only important that you provide your custom metadata Document Model on the classpath as described in the Data Services documentation.
  2. You have to provide your CustomMetadata.java class, that shall include your new metadata field(s). E.g. see the following implementation as an example:
    CustomMetadata.java
package com.mgmtp.a12.template.server.metadata;

import com.mgmtp.a12.dataservices.document.DataServicesDocumentMetadata;
import com.mgmtp.a12.dataservices.document.DocumentReference;
import com.mgmtp.a12.dataservices.model.metadata.DocumentMetadataConstants;
import com.mgmtp.a12.kernel.md.document.apiV2.DocumentPointer;
import com.mgmtp.a12.kernel.md.document.apiV2.immutable.DocumentV2;

import java.time.Instant;
import java.util.List;
import java.util.Optional;

public class CustomMetadata implements DataServicesDocumentMetadata {

    private final DocumentV2 document;

    public CustomMetadata(DocumentV2 document) {
        this.document = document;
    }

    @Override public DocumentReference getDocRef() {
        return getStringValue(DocumentMetadataConstants.DOC_REF_METADATA_NAME)
                .map(DocumentReference::new)
                .orElse(null);
    }

    public DocumentReference getSecondDocRef() {
        return getStringValue("secondDocRef")
                .map(DocumentReference::new)
                .orElse(null);
    }

    public String getDocumentModelReference() {
        return getStringValue(DocumentMetadataConstants.MODEL_REFERENCE_METADATA_NAME).orElse(null);
    }

    public String getDocumentModelVersion() {
        return getStringValue(DocumentMetadataConstants.MODEL_VERSION_METADATA_NAME).orElse(null);
    }

    public String getCreator() {
        return getStringValue(DocumentMetadataConstants.CREATOR_METADATA_NAME).orElse(null);
    }

    public String getModifier() {
        return getStringValue(DocumentMetadataConstants.MODIFIER_METADATA_NAME).orElse(null);
    }

    public Instant getCreatedAt() {
        return getInstantValue(DocumentMetadataConstants.CREATED_AT_METADATA_NAME).orElse(null);
    }

    public Instant getModifiedAt() {
        return getInstantValue(DocumentMetadataConstants.MODIFIED_AT_METADATA_NAME).orElse(null);
    }

    private Optional<String> getStringValue(String fieldName) {
        return getTypedValue(fieldName, List.of(1, 1), String.class);
    }

    private Optional<Instant> getInstantValue(String fieldName) {
        return getTypedValue(fieldName, List.of(1, 1), Instant.class);
    }

    private <T> Optional<T> getTypedValue(String fieldName, List<Integer> repetitions, Class<T> type) {
        return Optional.of(
                type.cast(
                        document.fieldValue(DocumentPointer.of(List.of(DocumentMetadataConstants.DOCUMENT_METADATA_GROUP_NAME, fieldName), repetitions))
                )
        );
    }
}
  1. You have to provide an implementation for IDataServicesDocumentMetadataExtractor that returns your CustomMetadata object:
    CustomDataServicesDocumentMetadataExtractor
package com.mgmtp.a12.template.server.metadata;

import com.mgmtp.a12.dataservices.document.DataServicesDocumentMetadata;
import com.mgmtp.a12.dataservices.document.IDataServicesDocumentMetadataExtractor;
import com.mgmtp.a12.kernel.md.document.apiV2.immutable.DocumentV2;
import org.springframework.stereotype.Component;

@Component
public class CustomDataServicesDocumentMetadataExtractor implements IDataServicesDocumentMetadataExtractor {

    @Override public DataServicesDocumentMetadata getMetadata(DocumentV2 documentV2) {
        return new CustomMetadata(documentV2);
    }
}
  1. Then you should be able to call your custom metadata field(s) e.g. on server-side via the following:
((CustomMetadata) dataservicesDocument.getMetadata()).getSecondDocRef()

I am not sure about the SME, I will check if these custom metadata fields can be also referenced there. But this would require to provide the custom metadata Document Model somehow to the SME.

:information_source: Regarding the display and handling of custom metadata in the SME. This is an open overall A12 requirement, see: A12-16029.

Therefore, it is not possible at the moment to handle such custom metadata fields in the SME. But you can still fully work on it in the application with the implementation above.

Hello @jana-nimble-larch , I am a member of the Discourse team. I can see that there was a new response to your question. Do you find it helpful or should the question remain open?

Thanks ahead for your feedback and have a nice rest of the day!

it is very helpful and i think the topic is solved :slight_smile: