use of com.zimbra.common.mailbox.Color in project zm-mailbox by Zimbra.
the class SyncTest method tags.
@Test
public void tags() throws Exception {
Account acct = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(acct);
mbox.beginTrackingSync();
// create one tag implicitly and one explicitly
ParsedContact pc = new ParsedContact(ImmutableMap.of(ContactConstants.A_firstName, "Bob", ContactConstants.A_lastName, "Smith"));
mbox.createContact(null, pc, Mailbox.ID_FOLDER_CONTACTS, new String[] { "bar" }).getId();
int tagId = mbox.createTag(null, "foo", new Color((byte) 4)).getId();
Element request = new Element.XMLElement(MailConstants.SYNC_REQUEST);
Map<String, Object> context = new HashMap<String, Object>();
context.put(SoapEngine.ZIMBRA_CONTEXT, new ZimbraSoapContext(AuthProvider.getAuthToken(acct), acct.getId(), SoapProtocol.Soap12, SoapProtocol.Soap12));
Element response = new Sync().handle(request, context);
String token = response.getAttribute(MailConstants.A_TOKEN);
// check that only the explicitly-created tag is returned in the sync response
Element tagFolder = null;
for (Element hidden : response.getElement(MailConstants.E_FOLDER).listElements(MailConstants.E_FOLDER)) {
if (hidden.getAttribute(MailConstants.A_NAME).equals("Tags")) {
tagFolder = hidden;
break;
}
}
Assert.assertNotNull("could not find Tags folder in initial sync response", tagFolder);
Assert.assertEquals("1 tag listed", 1, tagFolder.listElements(MailConstants.E_TAG).size());
Element t = tagFolder.listElements(MailConstants.E_TAG).get(0);
Assert.assertEquals("listed tag named 'foo'", "foo", t.getAttribute(MailConstants.A_NAME));
Assert.assertEquals("correct color for tag 'foo'", 4, t.getAttributeLong(MailConstants.A_COLOR, MailItem.DEFAULT_COLOR));
// change tag color and re-sync
mbox.setColor(null, tagId, MailItem.Type.TAG, (byte) 6);
// mbox.purge(MailItem.Type.TAG);
request = new Element.XMLElement(MailConstants.SYNC_REQUEST).addAttribute(MailConstants.A_TOKEN, token);
response = new Sync().handle(request, context);
Assert.assertFalse("sync token change after tag color", token.equals(response.getAttribute(MailConstants.A_TOKEN)));
token = response.getAttribute(MailConstants.A_TOKEN);
// make sure the modified tag is returned in the sync response
t = response.getOptionalElement(MailConstants.E_TAG);
Assert.assertNotNull("modified tag missing", t);
Assert.assertEquals("new color on serialized tag", 6, t.getAttributeLong(MailConstants.A_COLOR, MailItem.DEFAULT_COLOR));
}
use of com.zimbra.common.mailbox.Color in project zm-mailbox by Zimbra.
the class MailItemResource method patchProperties.
/* Modifies the set of dead properties saved for this resource.
* Properties in the parameter 'set' are added to the existing properties.
* Properties in 'remove' are removed.
*/
@Override
public void patchProperties(DavContext ctxt, java.util.Collection<Element> set, java.util.Collection<QName> remove) throws DavException, IOException {
List<QName> reqProps = new ArrayList<QName>();
for (QName n : remove) {
mDeadProps.remove(n);
reqProps.add(n);
}
for (Element e : set) {
QName name = e.getQName();
if (name.equals(DavElements.E_DISPLAYNAME) && (type == MailItem.Type.FOLDER || type == MailItem.Type.MOUNTPOINT)) {
// rename folder
try {
String val = e.getText();
String uri = getUri();
Mailbox mbox = getMailbox(ctxt);
mbox.rename(ctxt.getOperationContext(), mId, type, val, mFolderId);
setProperty(DavElements.P_DISPLAYNAME, val);
UrlNamespace.addToRenamedResource(getOwner(), uri, this);
UrlNamespace.addToRenamedResource(getOwner(), uri.substring(0, uri.length() - 1), this);
} catch (ServiceException se) {
ctxt.getResponseProp().addPropError(DavElements.E_DISPLAYNAME, new DavException(se.getMessage(), DavProtocol.STATUS_FAILED_DEPENDENCY));
}
mDeadProps.remove(name);
continue;
} else if (name.equals(DavElements.E_CALENDAR_COLOR) && (type == MailItem.Type.FOLDER || type == MailItem.Type.MOUNTPOINT)) {
// change color
String colorStr = e.getText();
Color color = new Color(colorStr.substring(0, 7));
byte col = (byte) COLOR_LIST.indexOf(colorStr);
if (col >= 0)
color.setColor(col);
try {
Mailbox mbox = getMailbox(ctxt);
mbox.setColor(ctxt.getOperationContext(), new int[] { mId }, type, color);
} catch (ServiceException se) {
ctxt.getResponseProp().addPropError(DavElements.E_CALENDAR_COLOR, new DavException(se.getMessage(), DavProtocol.STATUS_FAILED_DEPENDENCY));
}
mDeadProps.remove(name);
continue;
} else if (name.equals(DavElements.E_SUPPORTED_CALENDAR_COMPONENT_SET)) {
// change default view
@SuppressWarnings("unchecked") List<Element> elements = e.elements(DavElements.E_COMP);
boolean isTodo = false;
boolean isEvent = false;
for (Element element : elements) {
Attribute attr = element.attribute(DavElements.P_NAME);
if (attr != null && CalComponent.VTODO.name().equals(attr.getValue())) {
isTodo = true;
} else if (attr != null && CalComponent.VEVENT.name().equals(attr.getValue())) {
isEvent = true;
}
}
if (isEvent ^ isTodo) {
// we support a calendar collection of type event or todo, not both or none.
Type type = (isEvent) ? Type.APPOINTMENT : Type.TASK;
try {
Mailbox mbox = getMailbox(ctxt);
mbox.setFolderDefaultView(ctxt.getOperationContext(), mId, type);
// See UrlNamespace.addToRenamedResource()
if (this instanceof Collection) {
((Collection) this).view = type;
}
} catch (ServiceException se) {
ctxt.getResponseProp().addPropError(name, new DavException(se.getMessage(), DavProtocol.STATUS_FAILED_DEPENDENCY));
}
} else {
ctxt.getResponseProp().addPropError(name, new DavException.CannotModifyProtectedProperty(name));
}
continue;
}
mDeadProps.put(name, e);
reqProps.add(name);
}
String configVal = "";
if (mDeadProps.size() > 0) {
org.dom4j.Document doc = org.dom4j.DocumentHelper.createDocument();
Element top = doc.addElement(CONFIG_KEY);
for (Map.Entry<QName, Element> entry : mDeadProps.entrySet()) top.add(entry.getValue().detach());
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputFormat format = OutputFormat.createCompactFormat();
XMLWriter writer = new XMLWriter(out, format);
writer.write(doc);
configVal = new String(out.toByteArray(), "UTF-8");
if (configVal.length() > PROP_LENGTH_LIMIT)
for (Map.Entry<QName, Element> entry : mDeadProps.entrySet()) ctxt.getResponseProp().addPropError(entry.getKey(), new DavException("prop length exceeded", DavProtocol.STATUS_INSUFFICIENT_STORAGE));
}
Mailbox mbox = null;
try {
mbox = getMailbox(ctxt);
mbox.lock.lock();
Metadata data = mbox.getConfig(ctxt.getOperationContext(), CONFIG_KEY);
if (data == null) {
data = new Metadata();
}
data.put(Integer.toString(mId), configVal);
mbox.setConfig(ctxt.getOperationContext(), CONFIG_KEY, data);
} catch (ServiceException se) {
for (QName qname : reqProps) ctxt.getResponseProp().addPropError(qname, new DavException(se.getMessage(), HttpServletResponse.SC_FORBIDDEN));
} finally {
if (mbox != null)
mbox.lock.release();
}
}
use of com.zimbra.common.mailbox.Color in project zm-mailbox by Zimbra.
the class SaveDraft method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
boolean wantImapUid = request.getAttributeBool(MailConstants.A_WANT_IMAP_UID, false);
boolean wantModSeq = request.getAttributeBool(MailConstants.A_WANT_MODIFIED_SEQUENCE, false);
Element msgElem = request.getElement(MailConstants.E_MSG);
int id = (int) msgElem.getAttributeLong(MailConstants.A_ID, Mailbox.ID_AUTO_INCREMENT);
String originalId = msgElem.getAttribute(MailConstants.A_ORIG_ID, null);
ItemId iidOrigid = originalId == null ? null : new ItemId(originalId, zsc);
String replyType = msgElem.getAttribute(MailConstants.A_REPLY_TYPE, null);
String identity = msgElem.getAttribute(MailConstants.A_IDENTITY_ID, null);
String account = msgElem.getAttribute(MailConstants.A_FOR_ACCOUNT, null);
// allow the caller to update the draft's metadata at the same time as they save the draft
String folderId = msgElem.getAttribute(MailConstants.A_FOLDER, null);
ItemId iidFolder = new ItemId(folderId == null ? "-1" : folderId, zsc);
if (!iidFolder.belongsTo(mbox)) {
throw ServiceException.INVALID_REQUEST("cannot move item between mailboxes", null);
} else if (folderId != null && iidFolder.getId() <= 0) {
throw MailServiceException.NO_SUCH_FOLDER(iidFolder.getId());
}
String flags = msgElem.getAttribute(MailConstants.A_FLAGS, null);
String[] tags = TagUtil.parseTags(msgElem, mbox, octxt);
Color color = ItemAction.getColor(msgElem);
// check to see whether the entire message has been uploaded under separate cover
String attachment = msgElem.getAttribute(MailConstants.A_ATTACHMENT_ID, null);
long autoSendTime = new Long(msgElem.getAttribute(MailConstants.A_AUTO_SEND_TIME, "0"));
ParseMimeMessage.MimeMessageData mimeData = new ParseMimeMessage.MimeMessageData();
Message msg;
try {
MimeMessage mm;
if (attachment != null) {
mm = SendMsg.parseUploadedMessage(zsc, attachment, mimeData);
} else {
mm = ParseMimeMessage.parseMimeMsgSoap(zsc, octxt, mbox, msgElem, null, mimeData, true);
}
long date = System.currentTimeMillis();
try {
Date d = new Date();
mm.setSentDate(d);
date = d.getTime();
} catch (Exception ignored) {
}
try {
mm.saveChanges();
} catch (MessagingException me) {
throw ServiceException.FAILURE("completing MIME message object", me);
}
ParsedMessage pm = new ParsedMessage(mm, date, mbox.attachmentsIndexingEnabled());
if (autoSendTime != 0) {
AccountUtil.checkQuotaWhenSendMail(mbox);
}
String origid = iidOrigid == null ? null : iidOrigid.toString(account == null ? mbox.getAccountId() : account);
msg = mbox.saveDraft(octxt, pm, id, origid, replyType, identity, account, autoSendTime);
} catch (IOException e) {
throw ServiceException.FAILURE("IOException while saving draft", e);
} finally {
// purge the messages fetched from other servers.
if (mimeData.fetches != null) {
FileUploadServlet.deleteUploads(mimeData.fetches);
}
}
// we can now purge the uploaded attachments
if (mimeData.uploads != null) {
FileUploadServlet.deleteUploads(mimeData.uploads);
}
// try to set the metadata on the new/revised draft
if (folderId != null || flags != null || !ArrayUtil.isEmpty(tags) || color != null) {
try {
// best not to fail if there's an error here...
ItemActionHelper.UPDATE(octxt, mbox, zsc.getResponseProtocol(), Arrays.asList(msg.getId()), MailItem.Type.MESSAGE, null, null, iidFolder, flags, tags, color);
// and make sure the Message object reflects post-update reality
msg = mbox.getMessageById(octxt, msg.getId());
} catch (ServiceException e) {
ZimbraLog.soap.warn("error setting metadata for draft " + msg.getId() + "; skipping that operation", e);
}
}
if (schedulesAutoSendTask()) {
if (id != Mailbox.ID_AUTO_INCREMENT) {
// Cancel any existing auto-send task for this draft
AutoSendDraftTask.cancelTask(id, mbox.getId());
}
if (autoSendTime != 0) {
// schedule a new auto-send-draft task
AutoSendDraftTask.scheduleTask(msg.getId(), mbox.getId(), autoSendTime);
}
}
return generateResponse(zsc, ifmt, octxt, mbox, msg, wantImapUid, wantModSeq);
}
use of com.zimbra.common.mailbox.Color in project zm-mailbox by Zimbra.
the class MailboxUpgrade method upgradeTo1_7.
/**
* bug 41893: revert folder colors back to mapped value.
*/
public static void upgradeTo1_7(Mailbox mbox) throws ServiceException {
OperationContext octxt = new OperationContext(mbox);
for (Folder folder : mbox.getFolderList(octxt, SortBy.NONE)) {
Color color = folder.getRgbColor();
if (!color.hasMapping()) {
Byte value = UPGRADE_TO_1_7_COLORS.get(color.getValue());
if (value != null) {
Color newcolor = new Color(value);
mbox.setColor(octxt, new int[] { folder.getId() }, folder.getType(), newcolor);
}
}
}
}
use of com.zimbra.common.mailbox.Color in project zm-mailbox by Zimbra.
the class MailboxUpgrade method createTagRows.
private static Map<Integer, String> createTagRows(DbConnection conn, Mailbox mbox, boolean checkDuplicates) throws ServiceException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement("SELECT id, name, mod_metadata, metadata FROM " + DbMailItem.getMailItemTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type = " + MailItem.Type.TAG.toByte());
DbMailItem.setMailboxId(stmt, mbox, 1);
rs = stmt.executeQuery();
Map<Integer, String> tagNames = Maps.newHashMap();
while (rs.next()) {
UnderlyingData data = new UnderlyingData();
data.id = rs.getInt(1);
data.name = rs.getString(2);
data.modMetadata = rs.getInt(3);
Color color = Color.fromMetadata(new Metadata(rs.getString(4)).getLong(Metadata.FN_COLOR, MailItem.DEFAULT_COLOR));
try {
DbTag.createTag(conn, mbox, data, color.getMappedColor() == MailItem.DEFAULT_COLOR ? null : color, true);
} catch (ServiceException se) {
if (checkDuplicates && se.getCode().equals(MailServiceException.ALREADY_EXISTS)) {
// tag name already exist. append a random number to the tag name.
SecureRandom sr = new SecureRandom();
data.name = data.name + sr.nextInt();
DbTag.createTag(conn, mbox, data, color.getMappedColor() == MailItem.DEFAULT_COLOR ? null : color, true);
} else {
throw se;
}
}
tagNames.put(data.id, data.name);
}
return tagNames;
} catch (SQLException e) {
throw ServiceException.FAILURE("creating TAG rows in mbox " + mbox.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
Aggregations