438 lines
16 KiB
OpenEdge ABL
438 lines
16 KiB
OpenEdge ABL
public with sharing class BoxFeature extends CloudStorageBase {
|
||
|
||
private static final String BOX_API_URL = 'https://api.box.com/2.0';
|
||
private static String externalStorage = 'Box';
|
||
|
||
public override OperationResult listFiles(Boolean isServiceMode,Boolean myDrive,String userId,Boolean isRootFolder,String folderId,String accessToken,String level) {
|
||
|
||
List<Map<String, String>> resultFiles = new List<Map<String, String>>();
|
||
OperationResult result;
|
||
|
||
try {
|
||
System.debug('isServiceMode ' + isServiceMode);
|
||
System.debug('accessToken ' + accessToken);
|
||
System.debug('--Folder ID-- ' + folderId);
|
||
|
||
// Box root folder is always 0 at root level
|
||
String boxFolderId;
|
||
if ((folderId == null || folderId == '') && isRootFolder) {
|
||
System.debug('Root Folder Box');
|
||
boxFolderId = '0';
|
||
} else {
|
||
boxFolderId = folderId;
|
||
}
|
||
|
||
// Endpoint
|
||
String endpoint =BOX_API_URL +'/folders/' + boxFolderId + '/items?fields=id,name,type,created_at,created_by';
|
||
|
||
Map<String, String> header = new Map<String, String>{
|
||
'Authorization' => 'Bearer ' + accessToken,
|
||
'Content-Type' => 'application/json'
|
||
};
|
||
|
||
System.debug('endpoint=' + endpoint);
|
||
|
||
HttpResponse res = CloudStorageUtlilty.makeCallout(null, endpoint, header, 'GET');
|
||
|
||
System.debug('API STATUS --> ' + res.getStatusCode());
|
||
System.debug('BODY --> ' + res.getBody());
|
||
|
||
// Success
|
||
if (res.getStatusCode() == 200) {
|
||
|
||
Map<String, Object> resultMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
|
||
|
||
List<Object> entries = (List<Object>) resultMap.get('entries');
|
||
|
||
for (Object obj : entries) {
|
||
Map<String, Object> fileDetails = (Map<String, Object>) obj;
|
||
|
||
Map<String, String> fileData = new Map<String, String>();
|
||
|
||
String type = (String) fileDetails.get('type');
|
||
|
||
// fileData.put('id', (String) fileDetails.get('id'));
|
||
// changes
|
||
// For files
|
||
fileData.put('id', 'file:' + (String) fileDetails.get('id'));
|
||
|
||
// For folders
|
||
fileData.put('id', 'folder:' + (String) fileDetails.get('id'));
|
||
|
||
fileData.put('name', (String) fileDetails.get('name'));
|
||
// fileData.put('mimeType', type);
|
||
fileData.put('mimeType', type == 'folder' ? 'folder' : 'file');
|
||
|
||
|
||
// Created Date
|
||
if (fileDetails.containsKey('created_at')) {
|
||
fileData.put( 'createdTime',(String) fileDetails.get('created_at'));
|
||
} else {
|
||
fileData.put('createdTime', '-');
|
||
}
|
||
|
||
// Created By
|
||
if (fileDetails.containsKey('created_by')) {
|
||
Map<String, Object> createdBy = (Map<String, Object>) fileDetails.get('created_by');
|
||
|
||
if (createdBy != null) {
|
||
fileData.put('createdBy',(String) createdBy.get('name'));
|
||
}
|
||
}
|
||
|
||
// Parent (Box does not return parents array)
|
||
fileData.put('parents', boxFolderId);
|
||
|
||
// Path display (Box doesn’t provide full path directly)
|
||
fileData.put('path_display', null);
|
||
|
||
|
||
String rawId = (String) fileDetails.get('id');
|
||
|
||
fileData.put('id', rawId);
|
||
fileData.put('name', (String) fileDetails.get('name'));
|
||
|
||
if (type == 'folder') {
|
||
fileData.put('mimeType', 'doctype:folder');
|
||
fileData.put('url', 'https://app.box.com/folder/' + rawId);
|
||
} else {
|
||
fileData.put('mimeType', 'doctype:unknown');
|
||
fileData.put('url', 'https://app.box.com/file/' + rawId);
|
||
}
|
||
|
||
|
||
resultFiles.add(fileData);
|
||
}
|
||
|
||
System.debug('>>>>resultFiles=' + resultFiles);
|
||
result = OperationResult.success(resultFiles);
|
||
}
|
||
else {
|
||
return OperationResult.error('Failed to list Box files.');
|
||
}
|
||
|
||
return result;
|
||
|
||
} catch (Exception e) {
|
||
System.debug('Error occurred: ' + e.getMessage());
|
||
FME_Logger.error('Error in listing Box files: ' + e.getMessage(),'BoxFeature','listFiles');
|
||
return OperationResult.error(e.getMessage());
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// change custom object -- linkedFolder
|
||
public override OperationResult linkFiles(String recordId) {
|
||
List<Map<String, String>> resultFolders = new List<Map<String, String>>();
|
||
|
||
try {
|
||
List<HIC_FilesME__Linked_Folder__c> linkedFolders = [
|
||
SELECT Id,Name,CreatedDate,CreatedBy.Name,HIC_FilesME__External_Folder_ID__c,
|
||
HIC_FilesME__Folder_Name__c,
|
||
HIC_FilesME__Folder_URL__c,
|
||
HIC_FilesME__Storage_Provider__c,
|
||
HIC_FilesME__Access_Level__c
|
||
FROM HIC_FilesME__Linked_Folder__c
|
||
WHERE HIC_FilesME__Linked_Record__c = :recordId
|
||
AND HIC_FilesME__Is_Active__c = true
|
||
];
|
||
|
||
for (HIC_FilesME__Linked_Folder__c folder : linkedFolders) {
|
||
|
||
Map<String, String> folderData = new Map<String, String>();
|
||
|
||
folderData.put('id', folder.HIC_FilesME__External_Folder_ID__c);
|
||
folderData.put('recordId', folder.Id);
|
||
folderData.put('name', folder.HIC_FilesME__Folder_Name__c);
|
||
folderData.put('externalStorageType', folder.HIC_FilesME__Storage_Provider__c);
|
||
folderData.put('accessLevel', folder.HIC_FilesME__Access_Level__c);
|
||
folderData.put('createdTime', String.valueOf(folder.CreatedDate));
|
||
folderData.put('createdBy', folder.CreatedBy != null ? folder.CreatedBy.Name : '-');
|
||
folderData.put('url', folder.HIC_FilesME__Folder_URL__c);
|
||
|
||
resultFolders.add(folderData);
|
||
}
|
||
|
||
System.debug('resultFolders >>>> ' + resultFolders);
|
||
|
||
return OperationResult.success(resultFolders);
|
||
|
||
} catch (Exception e) {FME_Logger.error(e.getMessage(),'LinkedFolderFeature' + e.getLineNumber(),'linkFiles');
|
||
return OperationResult.error('Failed to fetch linked folders. ' + e.getMessage());
|
||
}
|
||
}
|
||
|
||
// change custom object -- linkedFolder
|
||
public override OperationResult toLinkFiles(String recordId,String folderDetails,String providerType) {
|
||
try {
|
||
System.debug('providerType >>>> ' + providerType);
|
||
System.debug('recordId >>>> ' + recordId);
|
||
System.debug('JSON.deserializeUntyped folderDetails >>>> ' + JSON.deserializeUntyped(folderDetails));
|
||
Map<String, Object> folderMap =
|
||
(Map<String, Object>) JSON.deserializeUntyped(folderDetails);
|
||
|
||
HIC_FilesME__Linked_Folder__c linkedFolder = new HIC_FilesME__Linked_Folder__c();
|
||
|
||
linkedFolder.HIC_FilesME__Linked_Record__c = recordId;
|
||
linkedFolder.HIC_FilesME__External_Folder_ID__c = (String) folderMap.get('id');
|
||
linkedFolder.HIC_FilesME__Folder_Name__c = (String) folderMap.get('name');
|
||
//add
|
||
linkedFolder.HIC_FilesME__Created__c = UserInfo.getUserId();
|
||
linkedFolder.HIC_FilesME__Created_Date__c = System.now();
|
||
linkedFolder.HIC_FilesME__Folder_URL__c = (String) folderMap.get('url');
|
||
linkedFolder.HIC_FilesME__Storage_Provider__c = providerType;
|
||
// linkedFolder.HIC_FilesME__Access_Level__c = (String) folderMap.get('accessLevel');
|
||
linkedFolder.HIC_FilesME__Is_Active__c = true;
|
||
|
||
insert linkedFolder;
|
||
System.debug('linkedFolder >>>> ' + linkedFolder);
|
||
return OperationResult.success(linkedFolder);
|
||
|
||
} catch (Exception e) {
|
||
FME_Logger.error(e.getMessage(),'LinkedFolderFeature' + e.getLineNumber(),'toLinkFiles' );
|
||
return OperationResult.error('Error linking folder: ' + e.getMessage());
|
||
}
|
||
}
|
||
|
||
|
||
public override OperationResult createFolder(String parentFolderId,Boolean isServiceMode,String folderName,String userId) {
|
||
|
||
Map<String, Object> resultMap = new Map<String, Object>();
|
||
Map<String, String> accessTokenMap = new Map<String, String>();
|
||
String refreshToken;
|
||
OperationResult result;
|
||
|
||
try {
|
||
String accessToken;
|
||
|
||
// Get access token
|
||
accessTokenMap = CloudStorageUtlilty.getAccessToken(isServiceMode, userId, externalStorage);
|
||
|
||
accessToken = (String) accessTokenMap.get('ACCESS_TOKEN');
|
||
refreshToken = (String) accessTokenMap.get('REFRESH_TOKEN');
|
||
|
||
// Box parent folder
|
||
// Root folder ID = "0"
|
||
String boxParentFolderId = (parentFolderId != null && parentFolderId != '') ? parentFolderId : '0';
|
||
|
||
String folderMetadata =
|
||
'{' +
|
||
'"name": "' + folderName + '",' +
|
||
'"parent": {' +
|
||
'"id": "' + boxParentFolderId + '"' +
|
||
'}' +
|
||
'}';
|
||
|
||
// Headers
|
||
Map<String, String> headers = new Map<String, String>{
|
||
'Authorization' => 'Bearer ' + accessToken,
|
||
'Content-Type' => 'application/json'
|
||
};
|
||
|
||
// Callout
|
||
String endpoint = 'https://api.box.com/2.0/folders';
|
||
|
||
HttpResponse res =
|
||
CloudStorageUtlilty.makeCallout(folderMetadata, endpoint, headers, 'POST');
|
||
|
||
System.debug('STATUS ---> ' + res.getStatusCode());
|
||
System.debug('BODY ---> ' + res.getBody());
|
||
|
||
// Success
|
||
|
||
if (res.getStatusCode() == 201) {
|
||
resultMap =
|
||
(Map<String, Object>) JSON.deserializeUntyped(res.getBody());
|
||
|
||
resultMap.put('code', '201');
|
||
result = OperationResult.success(resultMap);
|
||
|
||
// String userName = UserInfo.getName();
|
||
// String logMsg = userName + ' created folder "' + folderName +
|
||
// '" under parentId ' + boxParentFolderId;
|
||
// FME_Logger.audit('Create Folder', logMsg, 'BoxFeature', 'createFolder');
|
||
|
||
} else {
|
||
System.debug('Failed to create Box folder: ' + res.getBody());
|
||
result = OperationResult.error(res.getBody());
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
FME_Logger.error(e.getMessage(),'BoxFeature' + e.getLineNumber(),'createFolder');
|
||
result = OperationResult.error('Error creating Box folder: ' + e.getMessage());
|
||
|
||
} finally {
|
||
if (accessTokenMap.containsKey('newAccessToken')) {
|
||
CloudStorageUtlilty.updateAccessToken(isServiceMode,userId,refreshToken,externalStorage);
|
||
}
|
||
}
|
||
System.debug('result: ' + result);
|
||
return result;
|
||
}
|
||
|
||
|
||
|
||
|
||
public override OperationResult deleteFile(String fileId, Boolean isServiceMode, String userId) {
|
||
|
||
Map<String, String> accessTokenMap = new Map<String, String>();
|
||
String refreshToken;
|
||
|
||
try {
|
||
accessTokenMap = CloudStorageUtlilty.getAccessToken(isServiceMode,userId, externalStorage);
|
||
System.debug('accessTokenMap: ' + accessTokenMap);
|
||
|
||
String accessToken = accessTokenMap.get('ACCESS_TOKEN');
|
||
refreshToken = accessTokenMap.get('REFRESH_TOKEN');
|
||
|
||
if (String.isBlank(fileId)) {
|
||
return OperationResult.error('FileId is required');
|
||
}
|
||
|
||
// Expecting format: file:{id} OR folder:{id}
|
||
List<String> parts = fileId.split(':');
|
||
System.debug('parts: ' + parts);
|
||
|
||
if (parts.size() != 2) {
|
||
return OperationResult.error('Invalid Box fileId format');
|
||
}
|
||
|
||
String type = parts[0]; // file | folder
|
||
String id = parts[1];
|
||
|
||
String endpoint;
|
||
if (type == 'file') {
|
||
endpoint = 'https://api.box.com/2.0/files/' + id;
|
||
} else if (type == 'folder') {
|
||
endpoint = 'https://api.box.com/2.0/folders/' + id + '?recursive=true';
|
||
} else {
|
||
return OperationResult.error('Unsupported Box item type');
|
||
}
|
||
|
||
Map<String, String> headers = new Map<String, String>{
|
||
'Authorization' => 'Bearer ' + accessToken
|
||
};
|
||
|
||
HttpResponse res =
|
||
CloudStorageUtlilty.makeCallout(null, endpoint, headers, 'DELETE');
|
||
|
||
if (res.getStatusCode() == 204) {
|
||
return OperationResult.success('Deleted successfully');
|
||
} else {
|
||
return OperationResult.error(res.getBody());
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
|
||
FME_Logger.error(
|
||
e.getMessage(),
|
||
'BoxFeature.deleteFile line ' + e.getLineNumber(),
|
||
'deleteFile'
|
||
);
|
||
|
||
return OperationResult.error(
|
||
'Error deleting Box item: ' + e.getMessage()
|
||
);
|
||
|
||
} finally {
|
||
|
||
if (accessTokenMap.containsKey('newAccessToken')) {
|
||
CloudStorageUtlilty.updateAccessToken(
|
||
isServiceMode,
|
||
userId,
|
||
refreshToken,
|
||
externalStorage
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
public override OperationResult renameFile(String fileId,Boolean isServiceMode,String userId,String newFileName) {
|
||
String accessToken;
|
||
String refreshToken;
|
||
Map<String, String> accessTokenMap = new Map<String, String>();
|
||
OperationResult result;
|
||
|
||
try {
|
||
accessTokenMap = CloudStorageUtlilty.getAccessToken(isServiceMode,userId,externalStorage);
|
||
|
||
accessToken = accessTokenMap.get('ACCESS_TOKEN');
|
||
refreshToken = accessTokenMap.get('REFRESH_TOKEN');
|
||
|
||
if (String.isBlank(fileId) || String.isBlank(newFileName)) {
|
||
return OperationResult.error('FileId and newFileName are required');
|
||
}
|
||
|
||
List<String> parts = fileId.split(':');
|
||
if (parts.size() != 2) {
|
||
return OperationResult.error('Invalid Box fileId format');
|
||
}
|
||
|
||
String type = parts[0];
|
||
String id = parts[1];
|
||
|
||
String endpoint;
|
||
if (type == 'file') {
|
||
endpoint = 'https://api.box.com/2.0/files/' + id;
|
||
} else if (type == 'folder') {
|
||
endpoint = 'https://api.box.com/2.0/folders/' + id;
|
||
} else {
|
||
return OperationResult.error('Unsupported Box item type');
|
||
}
|
||
|
||
String body = JSON.serialize(new Map<String, Object>{
|
||
'name' => newFileName
|
||
});
|
||
|
||
Map<String, String> headers = new Map<String, String>{
|
||
'Authorization' => 'Bearer ' + accessToken,
|
||
'Content-Type' => 'application/json'
|
||
};
|
||
|
||
HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, headers, 'PUT');
|
||
|
||
if (res.getStatusCode() == 200) {
|
||
result = OperationResult.success(res.getBody());
|
||
} else {
|
||
result = OperationResult.error(res.getBody());
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
|
||
FME_Logger.error( e.getMessage(), 'BoxFeature.renameFile line ' + e.getLineNumber(), 'renameFile' );
|
||
|
||
result = OperationResult.error(
|
||
'Error renaming Box item: ' + e.getMessage()
|
||
);
|
||
|
||
} finally {
|
||
|
||
if (accessTokenMap.containsKey('newAccessToken')) {
|
||
CloudStorageUtlilty.updateAccessToken(
|
||
isServiceMode,
|
||
userId,
|
||
refreshToken,
|
||
externalStorage
|
||
);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
} |