Skip to content

Commit

Permalink
feat: store calendar group as Folder with Appointment view
Browse files Browse the repository at this point in the history
  • Loading branch information
matteobaglini authored and drazen04 committed Nov 11, 2024
1 parent 801972e commit cdcfdbb
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 84 deletions.
6 changes: 0 additions & 6 deletions store/src/main/java/com/zimbra/cs/mailbox/CalendarGroup.java

This file was deleted.

92 changes: 36 additions & 56 deletions store/src/main/java/com/zimbra/cs/mailbox/Mailbox.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@
import com.zimbra.cs.redolog.op.AlterItemTag;
import com.zimbra.cs.redolog.op.ColorItem;
import com.zimbra.cs.redolog.op.CopyItem;
import com.zimbra.cs.redolog.op.CreateCalendarGroup;
import com.zimbra.cs.redolog.op.CreateCalendarItemPlayer;
import com.zimbra.cs.redolog.op.CreateCalendarItemRecorder;
import com.zimbra.cs.redolog.op.CreateChat;
Expand Down Expand Up @@ -244,7 +243,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
Expand Down Expand Up @@ -2668,18 +2666,19 @@ public void deleteMailbox(DeleteBlobs deleteBlobs) throws ServiceException {

/**
* mark mailbox deleted
*
* @throws ServiceException
*/
public void markMailboxDeleted() throws ServiceException {
MailboxManager.getInstance().markMailboxDeleted(this);
Provisioning provisioning = Provisioning.getInstance();
if (provisioning instanceof ProvisioningCache) {
String accountId = getAccountId();
Account acct = Provisioning.getInstance().get(AccountBy.id, accountId);
if (acct != null) {
((ProvisioningCache) provisioning).removeFromCache(acct);
}
Provisioning provisioning = Provisioning.getInstance();
if (provisioning instanceof ProvisioningCache) {
String accountId = getAccountId();
Account acct = Provisioning.getInstance().get(AccountBy.id, accountId);
if (acct != null) {
((ProvisioningCache) provisioning).removeFromCache(acct);
}
}
}

public void renameMailbox(String oldName, String newName) throws ServiceException {
Expand Down Expand Up @@ -4244,8 +4243,7 @@ public Pair<List<Integer>, TypedIdList> getModifiedItems(
lock.lock(false);
try {
if (lastSync >= getLastChangeID()) {
return new Pair<>(
Collections.<Integer>emptyList(), new TypedIdList());
return new Pair<>(Collections.<Integer>emptyList(), new TypedIdList());
}
boolean success = false;
try {
Expand Down Expand Up @@ -5550,13 +5548,14 @@ public List<BrowseTerm> browse(OperationContext octxt, BrowseBy browseBy, String
assert false : browseBy;
}

result.sort((o1, o2) -> {
int retVal = o2.getFreq() - o1.getFreq();
if (retVal == 0) {
retVal = o1.getText().compareTo(o2.getText());
}
return retVal;
});
result.sort(
(o1, o2) -> {
int retVal = o2.getFreq() - o1.getFreq();
if (retVal == 0) {
retVal = o1.getText().compareTo(o2.getText());
}
return retVal;
});

if (max > 0 && result.size() > max) {
result = result.subList(0, max);
Expand Down Expand Up @@ -7179,7 +7178,8 @@ public List<Conversation> lookupConversation(ParsedMessage pm) throws ServiceExc
}

public static String getHash(String subject) {
return ByteUtil.getSHA1Digest(Strings.nullToEmpty(subject).getBytes(StandardCharsets.UTF_8), true);
return ByteUtil.getSHA1Digest(
Strings.nullToEmpty(subject).getBytes(StandardCharsets.UTF_8), true);
}

// please keep this package-visible but not public
Expand Down Expand Up @@ -8421,7 +8421,12 @@ private void delete(
}
for (Integer folderId : folderIds) {
emptyFolder(
octxt, folderId, true /* removeTopLevelFolder */, true /* removeSubfolders */, tcon, null);
octxt,
folderId,
true /* removeTopLevelFolder */,
true /* removeSubfolders */,
tcon,
null);
}
}

Expand Down Expand Up @@ -8890,24 +8895,6 @@ public Folder createFolder(
return createFolder(octxt, name, parentId, fopt);
}

public CalendarGroup createCalendarGroup(OperationContext octxt, String name, List<String> calendarIds) throws ServiceException {
var id = UUID.randomUUID().toString();
// TODO: implement redo logic
// var redoRecorder = new CreateCalendarGroup(mId, id, name, calendarIds);
boolean success = false;
try {
beginTransaction("createContactGroup", octxt);
// var redoPlayer = (CreateCalendarGroup) currentChange().getRedoPlayer();

var group = new CalendarGroup(id, name, calendarIds.stream().map(Integer::parseInt).collect(Collectors.toSet()));
updateCalendarGroupDataSource(group);
success = true;
return group;
} finally {
endTransaction(success);
}
}

public Folder createFolder(
OperationContext octxt, String name, int parentId, Folder.FolderOptions fopt)
throws ServiceException {
Expand Down Expand Up @@ -9289,13 +9276,6 @@ public void setFolderWebOfflineSyncDays(OperationContext octxt, int folderId, in
}
}

/**
* Updates the data source for a calendar group.
*/
protected void updateCalendarGroupDataSource(CalendarGroup group) {

}

/**
* Updates the data source for an RSS folder. If the folder URL is set, checks or creates a data
* source that updates the folder. If the URL is not set, deletes the data source if necessary.
Expand Down Expand Up @@ -9638,8 +9618,9 @@ private void emptyFolder(
} else {
List<Folder> folders = getFolderById(octxt, folderId).getSubfolderHierarchy();
for (Folder folder : folders) {
if (itemsType == null || FolderActionEmptyOpTypes.getIncludedTypesFor(itemsType)
.contains(folder.getDefaultView())
if (itemsType == null
|| FolderActionEmptyOpTypes.getIncludedTypesFor(itemsType)
.contains(folder.getDefaultView())
|| folder.getId() == FolderConstants.ID_FOLDER_TRASH) {
folderIds.add(folder.getId());
}
Expand All @@ -9660,7 +9641,7 @@ private void emptyFolder(
.setModifiedSequenceBefore(lastChangeID + 1)
.setRowLimit(batchSize);

if(itemsType != null){
if (itemsType != null) {
params.setIncludedTypes(FolderActionEmptyOpTypes.getIncludedTypesFor(itemsType));
}

Expand Down Expand Up @@ -9717,15 +9698,13 @@ private void emptyFolder(
}
}

public void emptyFolder(OperationContext octxt, int folderId, boolean removeSubfolders,
public void emptyFolder(
OperationContext octxt,
int folderId,
boolean removeSubfolders,
FolderActionEmptyOpTypes matchType)
throws ServiceException {
emptyFolder(
octxt,
folderId,
false,
removeSubfolders,
null, matchType);
emptyFolder(octxt, folderId, false, removeSubfolders, null, matchType);
}

public void emptyFolder(OperationContext octxt, int folderId, boolean removeSubfolders)
Expand All @@ -9735,7 +9714,8 @@ public void emptyFolder(OperationContext octxt, int folderId, boolean removeSubf
folderId,
false /* removeTopLevelFolder */,
removeSubfolders,
null /* TargetConstraint */, null);
null /* TargetConstraint */,
null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import com.zimbra.common.service.ServiceException;
import com.zimbra.common.soap.Element;
import com.zimbra.common.soap.MailConstants;
import com.zimbra.cs.mailbox.CalendarGroup;
import com.zimbra.cs.mailbox.Folder;
import com.zimbra.cs.mailbox.MailItem;
import com.zimbra.soap.ZimbraSoapContext;
import com.zimbra.soap.mail.message.CreateCalendarGroupRequest;

import java.util.List;
import java.util.Map;
import java.util.UUID;

public class CreateCalendarGroup extends MailDocumentHandler {

Expand All @@ -24,23 +24,29 @@ public Element handle(Element request, Map<String, Object> context) throws Servi

CreateCalendarGroupRequest req = zsc.elementToJaxb(request);

// TODO: implement duplicated calendar name check logic
// TODO - double: implement duplicated calendar name check logic

// TODO - double: use 1 (ROOT?) or -1 as parent folder id?
final var fopt = new Folder.FolderOptions();
fopt.setDefaultView(MailItem.Type.APPOINTMENT);

final var group = mbox.createCalendarGroup(octxt, req.getName(), req.getCalendarIds());
final var group = mbox.createFolder(octxt, req.getName(), 1, fopt);

return buildResponse(zsc, group);
}

private static Element buildResponse(ZimbraSoapContext zsc, CalendarGroup group) {
private static Element buildResponse(ZimbraSoapContext zsc, Folder group) {
final var response = zsc.createElement(MailConstants.CREATE_CALENDAR_GROUP_RESPONSE);
final var groupInfo = response.addUniqueElement("group");
groupInfo.addAttribute("id", group.id());
groupInfo.addAttribute("name", group.name());
for (final var calendarId : group.calendarIds()) {
groupInfo.addAttribute("id", group.getId());
groupInfo.addAttribute("name", group.getName());
// TODO - double: read from metadata?
// final var calendarIds = group.calendarIds();
final var calendarIds = List.of("10", "420", "421");
for (final var calendarId : calendarIds) {
final var calendarIdElement = groupInfo.addNonUniqueElement("calendarId");
calendarIdElement.setText(calendarId.toString());
}
return response;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

public class GetCalendarGroups extends MailDocumentHandler {

// TODO: use UUID or a fixed string like "all-calendars-id"?
// TODO - double: use UUID or a fixed string like "all-calendars-id"?
private static final String ALL_CALENDARS_GROUP_ID = "a970bb9528c94c40bd51bfede60fcb31";
private static final String ALL_CALENDARS_GROUP_NAME = "All calendars";

Expand All @@ -26,7 +26,7 @@ public Element handle(Element request, Map<String, Object> context) throws Servi
throw ServiceException.PERM_DENIED("can not access account");

final var calendars = mbox.getCalendarFolders(octxt, SortBy.NAME_ASC);
// TODO: load all calendar groups from datastore
// TODO - double: load all calendar groups from datastore

return buildResponse(zsc, calendars);
}
Expand All @@ -36,7 +36,7 @@ private static Element buildResponse(ZimbraSoapContext zsc, List<Folder> calenda

addAllCalendarsGroup(calendars, response);
addFakeCalendarGroup(calendars, response);
// TODO: add other groups loaded from datastore
// TODO - double: add other groups loaded from datastore
return response;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.zimbra.cs.service.account;

import static com.zimbra.common.soap.Element.parseXML;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

import com.zextras.mailbox.soap.SoapTestSuite;
import com.zextras.mailbox.util.MailboxTestUtil;
import com.zimbra.common.service.ServiceException;
Expand All @@ -9,6 +13,8 @@
import com.zimbra.soap.JaxbUtil;
import com.zimbra.soap.mail.message.CreateCalendarGroupRequest;
import com.zimbra.soap.mail.message.CreateCalendarGroupResponse;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;
Expand All @@ -17,13 +23,6 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;

import static com.zimbra.common.soap.Element.parseXML;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

@Tag("api")
class CreateCalendarGroupTest extends SoapTestSuite {

Expand Down Expand Up @@ -56,10 +55,9 @@ void createGroup() throws Exception {
var group = response.getGroup();
assertFalse(StringUtil.isNullOrEmpty(group.getId()));
assertEquals("Test Group", group.getName());
assertEquals(List.of("1", "2", "3"), group.getCalendarIds());
assertEquals(List.of("10", "420", "421"), group.getCalendarIds());
}


private static CreateCalendarGroupResponse parseSoapResponse(HttpResponse httpResponse)
throws IOException, ServiceException {
final var responseBody = EntityUtils.toString(httpResponse.getEntity());
Expand Down

0 comments on commit cdcfdbb

Please sign in to comment.