Skip to content
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,26 @@ annotate Attachments with @Common: {SideEffects #ContentChanged: {
- Replace `AdminService` in `Action: 'AdminService.createLink'` with the name of your service.
- Repeat for other entities and elements if you have defined multiple `composition of many Attachments`.

### Updating Tenant Databases for Link Feature
To support the Link feature, additional database columns are introduced.
Upon re-deployment of your multitenant application, you may encounter "invalid column" errors if tenant database containers are not updated.

To resolve this, ensure the following hook command is added to the mta.yaml for the sidecar application.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You missed adding the mta.yaml hook here. Please add it .

```
hooks:
- name: upgrade-all
type: task
phases:
- blue-green.application.before-start.idle
- deploy.application.before-start
parameters:
name: upgrade
memory: 512M
disk-quota: 768M
command: npx -p @sap/cds-mtx cds-mtx upgrade "*"
```
This will automatically update tenant databases during deployment. See this [example](https://github.com/vibhutikumar07/cloud-cap-samples-java/blob/31009de404af0ddc92b8c593b21395757ed053e6/mta.yaml#L71).

## Support for edit of link type attachments

This plugin provides the capability to update/edit the URL of attachments of link type.
Expand Down Expand Up @@ -834,6 +854,7 @@ annotate Attachments with @Common: {SideEffects #ContentChanged: {
- Replace `AdminService` in `Action: 'AdminService.editLink'` with the name of your service.
- Repeat for other entities and elements if you have defined multiple `composition of many Attachments`.


## Known Restrictions

- UI5 Version 1.135.0: This version causes error in upload of attachments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ public void eventHandlers(CdsRuntimeConfigurer configurer) {
dbQueryInstance,
tokenHandlerInstance));
configurer.eventHandler(
new SDMCustomServiceHandler(sdmService, draftServiceList, tokenHandlerInstance));
new SDMCustomServiceHandler(
sdmService,
draftServiceList,
tokenHandlerInstance,
dbQueryInstance,
persistenceService));
}

private AttachmentService buildAttachmentService() {
Expand Down
1 change: 1 addition & 0 deletions sdm/src/main/java/com/sap/cds/sdm/model/CmisDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ public class CmisDocument {
private String subdomain;
private String url;
private String contentId;
private String type;
}
97 changes: 34 additions & 63 deletions sdm/src/main/java/com/sap/cds/sdm/persistence/DBQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.sap.cds.reflect.CdsEntity;
import com.sap.cds.sdm.constants.SDMConstants;
import com.sap.cds.sdm.model.CmisDocument;
import com.sap.cds.sdm.service.handler.AttachmentCopyEventContext;
import com.sap.cds.services.persistence.PersistenceService;
import java.util.*;

Expand Down Expand Up @@ -62,6 +63,38 @@ public CmisDocument getObjectIdForAttachmentID(
return cmisDocument;
}

public CmisDocument getAttachmentForObjectID(
PersistenceService persistenceService, String id, AttachmentCopyEventContext context) {
Optional<CdsEntity> attachmentEntity = context.getModel().findEntity(context.getFacet());
CqnSelect q =
Select.from(attachmentEntity.get())
.columns("linkUrl", "type")
.where(doc -> doc.get("objectId").eq(id));
Result result = persistenceService.run(q);
Optional<Row> res = result.first();
CmisDocument cmisDocument = new CmisDocument();
if (res.isPresent()) {
Row row = res.get();
cmisDocument.setType(row.get("type") != null ? row.get("type").toString() : null);
cmisDocument.setUrl(row.get("linkUrl") != null ? row.get("linkUrl").toString() : null);
} else {
// Check in draft table as well
attachmentEntity = context.getModel().findEntity(context.getFacet() + "_drafts");
q =
Select.from(attachmentEntity.get())
.columns("linkUrl", "type")
.where(doc -> doc.get("objectId").eq(id));
result = persistenceService.run(q);
res = result.first();
if (res.isPresent()) {
Row row = res.get();
cmisDocument.setType(row.get("type") != null ? row.get("type").toString() : null);
cmisDocument.setUrl(row.get("linkUrl") != null ? row.get("linkUrl").toString() : null);
}
}
return cmisDocument;
}

public Result getAttachmentsForUPIDAndRepository(
CdsEntity attachmentEntity,
PersistenceService persistenceService,
Expand Down Expand Up @@ -96,76 +129,14 @@ public void addAttachmentToDraft(
updatedFields.put("repositoryId", repositoryId);
updatedFields.put("folderId", cmisDocument.getFolderId());
updatedFields.put("status", "Clean");
String icon = getIconForMimeType(cmisDocument.getMimeType());
updatedFields.put("type", icon);

updatedFields.put("type", "sap-icon://document");
CqnUpdate updateQuery =
Update.entity(attachmentEntity)
.data(updatedFields)
.where(doc -> doc.get("ID").eq(cmisDocument.getAttachmentId()));
persistenceService.run(updateQuery);
}

private static String getIconForMimeType(String mimeType) {
if (isExcel(mimeType)) {
return "sap-icon://excel-attachment";
} else if (isImage(mimeType)) {
return "sap-icon://attachment-photo";
} else if (isText(mimeType)) {
return "sap-icon://attachment-text-file";
} else if (isPdf(mimeType)) {
return "sap-icon://pdf-attachment";
} else if (isPowerPoint(mimeType)) {
return "sap-icon://ppt-attachment";
} else if (isVideo(mimeType)) {
return "sap-icon://attachment-video";
} else if (isAudio(mimeType)) {
return "sap-icon://attachment-audio";
} else if (isZip(mimeType)) {
return "sap-icon://attachment-zip-file";
} else if (isHtml(mimeType)) {
return "sap-icon://attachment-html";
}
return "sap-icon://document";
}

private static boolean isExcel(String mimeType) {
return mimeType.contains("vnd.ms-excel")
|| mimeType.contains("vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}

private static boolean isImage(String mimeType) {
return mimeType.contains("image");
}

private static boolean isText(String mimeType) {
return mimeType.contains("text");
}

private static boolean isPdf(String mimeType) {
return mimeType.contains("pdf");
}

private static boolean isPowerPoint(String mimeType) {
return mimeType.contains("powerpoint") || mimeType.contains("presentation");
}

private static boolean isVideo(String mimeType) {
return mimeType.contains("video");
}

private static boolean isAudio(String mimeType) {
return mimeType.contains("audio");
}

private static boolean isZip(String mimeType) {
return mimeType.contains("zip");
}

private static boolean isHtml(String mimeType) {
return mimeType.contains("html");
}

public List<CmisDocument> getAttachmentsForFolder(
String entity,
PersistenceService persistenceService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import com.sap.cds.sdm.handler.TokenHandler;
import com.sap.cds.sdm.model.CmisDocument;
import com.sap.cds.sdm.model.SDMCredentials;
import com.sap.cds.sdm.persistence.DBQuery;
import com.sap.cds.sdm.service.RegisterService;
import com.sap.cds.sdm.service.SDMService;
import com.sap.cds.services.ServiceException;
import com.sap.cds.services.draft.DraftService;
import com.sap.cds.services.handler.annotations.On;
import com.sap.cds.services.handler.annotations.ServiceName;
import com.sap.cds.services.persistence.PersistenceService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -26,14 +28,22 @@
@ServiceName(value = "*", type = RegisterService.class)
public class SDMCustomServiceHandler {
private final SDMService sdmService;
private final DBQuery dbQuery;
private final List<DraftService> draftService;
private final TokenHandler tokenHandler;
private final PersistenceService persistenceService;

public SDMCustomServiceHandler(
SDMService sdmService, List<DraftService> draftService, TokenHandler tokenHandler) {
SDMService sdmService,
List<DraftService> draftService,
TokenHandler tokenHandler,
DBQuery dbQuery,
PersistenceService persistenceService) {
this.sdmService = sdmService;
this.draftService = draftService;
this.tokenHandler = tokenHandler;
this.dbQuery = dbQuery;
this.persistenceService = persistenceService;
}

@On(event = RegisterService.EVENT_COPY_ATTACHMENT)
Expand Down Expand Up @@ -62,12 +72,15 @@ public void copyAttachments(AttachmentCopyEventContext context) throws IOExcepti
folderId = succinctProperties.getString("cmis:objectId");
}
CmisDocument cmisDocument = new CmisDocument();
cmisDocument.setRepositoryId(repositoryId);
cmisDocument.setFolderId(folderId);

List<String> objectIds = context.getObjectIds();
List<List<String>> attachmentsMetadata = new ArrayList<>();
for (String objectId : objectIds) {
// get Link Url from objectId and set to cmisDocument
cmisDocument = dbQuery.getAttachmentForObjectID(persistenceService, objectId, context);
cmisDocument.setObjectId(objectId);
cmisDocument.setRepositoryId(repositoryId);
cmisDocument.setFolderId(folderId);
try {
attachmentsMetadata.add(
sdmService.copyAttachment(cmisDocument, sdmCredentials, isSystemUser));
Expand Down Expand Up @@ -101,15 +114,21 @@ public void copyAttachments(AttachmentCopyEventContext context) throws IOExcepti
for (List<String> attachmentMetadata : attachmentsMetadata) {
String fileName = attachmentMetadata.get(0);
String mimeType = attachmentMetadata.get(1);
if (mimeType.equalsIgnoreCase("application/internet-shortcut")) {
int dotIndex = fileName.lastIndexOf('.');
fileName = fileName.substring(0, dotIndex);
}
Comment on lines +117 to +120
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If link is created sdm creates link as name with suffix .url

String newObjectId = attachmentMetadata.get(2);
updatedFields.put("objectId", newObjectId);
updatedFields.put("repositoryId", repositoryId);
updatedFields.put("folderId", folderId);
updatedFields.put("status", "Clean");
updatedFields.put("mimeType", mimeType);
updatedFields.put("type", cmisDocument.getType());
updatedFields.put("fileName", fileName);
updatedFields.put("HasDraftEntity", false);
updatedFields.put("HasActiveEntity", false);
updatedFields.put("linkUrl", cmisDocument.getUrl());
updatedFields.put(
"contentId", newObjectId + ":" + folderId + ":" + context.getFacet() + ":" + mimeType);
updatedFields.put(upIdKey, upID);
Expand Down
2 changes: 1 addition & 1 deletion sdm/src/main/resources/cds/com.sap.cds/sdm/attachments.cds
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extend aspect Attachments with {
repositoryId : String;
objectId : String;
linkUrl : String default null;
type : String @(UI: {IsImageURL: true}) default null;
type : String @(UI: {IsImageURL: true}) default 'sap-icon://document';
}
annotate Attachments with @UI: {
HeaderInfo: {
Expand Down
Loading
Loading