Search in sources :

Example 1 with Task

use of com.zimbra.cs.mailbox.Task in project zm-mailbox by Zimbra.

the class ZimbraQueryResultsImpl method getZimbraHit.

/**
 * We've got a {@link Mailbox}, a {@link DbSearch.Result} and (optionally) a Lucene Doc...
 * that's everything we need to build a real ZimbraHit.
 *
 * @param doc - Optional, only set if this search had a Lucene part
 */
ZimbraHit getZimbraHit(Mailbox mbox, DbSearch.Result sr, Document doc, DbSearch.FetchMode fetch) {
    MailItem item = null;
    ImapMessage i4msg = null;
    int modseq = -1, parentId = 0;
    switch(fetch) {
        case MAIL_ITEM:
            item = sr.getItem();
            break;
        case IMAP_MSG:
            i4msg = sr.getImapMessage();
            break;
        case MODSEQ:
            modseq = sr.getModSeq();
            break;
        case PARENT:
            parentId = sr.getParentId();
            break;
    }
    ZimbraHit result = null;
    switch(sr.getType()) {
        case CHAT:
        case MESSAGE:
            if (doc != null) {
                result = getMessagePartHit(mbox, sr.getId(), (Message) item, doc, sr.getSortValue());
            } else {
                result = getMessageHit(mbox, sr.getId(), (Message) item, null, sr.getSortValue());
            }
            break;
        case CONTACT:
            result = getContactHit(mbox, sr.getId(), (Contact) item, sr.getSortValue());
            break;
        case NOTE:
            result = getNoteHit(mbox, sr.getId(), (Note) item, sr.getSortValue());
            break;
        case APPOINTMENT:
            result = getAppointmentHit(mbox, sr.getId(), (CalendarItem) item, sr.getSortValue());
            break;
        case TASK:
            result = getTaskHit(mbox, sr.getId(), (Task) item, sr.getSortValue());
            break;
        case DOCUMENT:
        case WIKI:
            result = getDocumentHit(mbox, sr.getId(), (com.zimbra.cs.mailbox.Document) item, doc, sr.getSortValue());
            break;
        default:
            assert (false);
    }
    if (i4msg != null) {
        result.cacheImapMessage(i4msg);
    }
    if (modseq > 0) {
        result.cacheModifiedSequence(modseq);
    }
    if (parentId != 0) {
        result.cacheParentId(parentId);
    }
    return result;
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) Task(com.zimbra.cs.mailbox.Task) ImapMessage(com.zimbra.cs.imap.ImapMessage) Message(com.zimbra.cs.mailbox.Message) ImapMessage(com.zimbra.cs.imap.ImapMessage) Note(com.zimbra.cs.mailbox.Note) Document(org.apache.lucene.document.Document) Contact(com.zimbra.cs.mailbox.Contact)

Example 2 with Task

use of com.zimbra.cs.mailbox.Task in project zm-mailbox by Zimbra.

the class ArchiveFormatter method saveItem.

private ArchiveOutputStream saveItem(UserServletContext context, MailItem mi, Map<Integer, String> fldrs, Map<Integer, Integer> cnts, boolean version, ArchiveOutputStream aos, CharsetEncoder charsetEncoder, Set<String> names) throws ServiceException {
    String ext = null, name = null;
    String extra = null;
    Integer fid = mi.getFolderId();
    String fldr;
    InputStream is = null;
    String metaParam = context.params.get(UserServlet.QP_META);
    boolean meta = metaParam == null ? getDefaultMeta() : !metaParam.equals("0");
    if (!version && mi.isTagged(Flag.FlagInfo.VERSIONED)) {
        for (MailItem rev : context.targetMailbox.getAllRevisions(context.opContext, mi.getId(), mi.getType())) {
            if (mi.getVersion() != rev.getVersion())
                aos = saveItem(context, rev, fldrs, cnts, true, aos, charsetEncoder, names);
        }
    }
    switch(mi.getType()) {
        case APPOINTMENT:
            Appointment appt = (Appointment) mi;
            if (!appt.isPublic() && !appt.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
                return aos;
            }
            if (meta) {
                name = appt.getSubject();
                ext = "appt";
            } else {
                ext = "ics";
            }
            break;
        case CHAT:
            ext = "chat";
            break;
        case CONTACT:
            Contact ct = (Contact) mi;
            name = ct.getFileAsString();
            if (!meta) {
                ext = "vcf";
            }
            break;
        case FLAG:
            return aos;
        case FOLDER:
        case MOUNTPOINT:
        case SEARCHFOLDER:
            if (mi.getId() == Mailbox.ID_FOLDER_ROOT) {
                name = "ROOT";
            } else if (mi.getId() == Mailbox.ID_FOLDER_USER_ROOT) {
                name = "USER_ROOT";
            } else {
                name = mi.getName();
            }
            break;
        case MESSAGE:
            Message msg = (Message) mi;
            if (msg.hasCalendarItemInfos()) {
                Set<ItemId> calItems = Sets.newHashSet();
                for (Iterator<CalendarItemInfo> it = msg.getCalendarItemInfoIterator(); it.hasNext(); ) {
                    ItemId iid = it.next().getCalendarItemId();
                    if (iid != null) {
                        calItems.add(iid);
                    }
                }
                for (ItemId i : calItems) {
                    if (extra == null) {
                        extra = "calendar=" + i.toString();
                    } else {
                        extra += ',' + i.toString();
                    }
                }
            }
            ext = "eml";
            break;
        case NOTE:
            ext = "note";
            break;
        case TASK:
            Task task = (Task) mi;
            if (!task.isPublic() && !task.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
                return aos;
            }
            ext = "task";
            break;
        case VIRTUAL_CONVERSATION:
            return aos;
        case WIKI:
            ext = "wiki";
            break;
    }
    fldr = fldrs.get(fid);
    if (fldr == null) {
        Folder f = mi.getMailbox().getFolderById(context.opContext, fid);
        cnts.put(fid, 1);
        fldr = f.getPath();
        if (fldr.startsWith("/")) {
            fldr = fldr.substring(1);
        }
        fldr = sanitize(fldr, charsetEncoder);
        fldr = ILLEGAL_FOLDER_CHARS.matcher(fldr).replaceAll("_");
        fldrs.put(fid, fldr);
    } else if (!(mi instanceof Folder)) {
        final int BATCH = 500;
        int cnt = cnts.get(fid) + 1;
        cnts.put(fid, cnt);
        cnt /= BATCH;
        if (cnt > 0) {
            fldr = fldr + '!' + cnt;
        }
    }
    int targetBaseLength = 0;
    if (context.noHierarchy()) {
        // Parent hierarchy is not needed, so construct the folder names without parent hierarchy.
        // e.g> represent "inbox/subfolder/target" as "target".
        String targetPath = null;
        if (context.itemPath.endsWith("/")) {
            // inbox/subfolder/target/
            targetPath = context.itemPath.substring(0, context.itemPath.lastIndexOf("/"));
        } else {
            // inbox/subfolder/target
            targetPath = context.itemPath;
        }
        // "inbox/subfolder".length()
        targetBaseLength = targetPath.lastIndexOf('/');
        if (targetBaseLength >= fldr.length()) {
            // fldr is "inbox/subfolder"
            fldr = "";
        } else if (targetBaseLength > 0) {
            // fldr is "inbox/subfolder/target"
            fldr = fldr.substring(targetBaseLength + 1);
        }
    }
    try {
        ArchiveOutputEntry aoe;
        byte[] data = null;
        String path = mi instanceof Contact ? getEntryName(mi, fldr, name, ext, charsetEncoder, names) : getEntryName(mi, fldr, name, ext, charsetEncoder, !(mi instanceof Document));
        long miSize = mi.getSize();
        if (miSize == 0 && mi.getDigest() != null) {
            ZimbraLog.misc.debug("blob db size 0 for item %d", mi.getId());
            return aos;
        }
        try {
            is = mi.getContentStream();
        } catch (Exception e) {
            ZimbraLog.misc.error("missing blob for item %d: expected %d", mi.getId(), miSize);
            return aos;
        }
        if (aos == null) {
            aos = getOutputStream(context, charsetEncoder.charset().name());
        }
        if ((mi instanceof CalendarItem) && (context.getStartTime() != TIME_UNSPECIFIED || context.getEndTime() != TIME_UNSPECIFIED)) {
            Collection<Instance> instances = ((CalendarItem) mi).expandInstances(context.getStartTime(), context.getEndTime(), false);
            if (instances.isEmpty()) {
                return aos;
            }
        }
        aoe = aos.newOutputEntry(path + ".meta", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
        if (mi instanceof Message && (mi.getFlagBitmask() & Flag.ID_UNREAD) != 0) {
            aoe.setUnread();
        }
        if (meta) {
            ItemData itemData = new ItemData(mi, extra);
            if (context.noHierarchy()) {
                // itemData.path is of the form /Inbox/subfolder/target and after this step it becomes /target.
                if (targetBaseLength > 0 && ((targetBaseLength + 1) < itemData.path.length())) {
                    itemData.path = itemData.path.substring(targetBaseLength + 1);
                }
            }
            byte[] metaData = itemData.encode();
            aoe.setSize(metaData.length);
            aos.putNextEntry(aoe);
            aos.write(metaData);
            aos.closeEntry();
        } else if (mi instanceof CalendarItem) {
            Browser browser = HttpUtil.guessBrowser(context.req);
            List<CalendarItem> calItems = new ArrayList<CalendarItem>();
            boolean needAppleICalHacks = Browser.APPLE_ICAL.equals(browser);
            boolean useOutlookCompatMode = Browser.IE.equals(browser);
            OperationContext octxt = new OperationContext(context.getAuthAccount(), context.isUsingAdminPrivileges());
            StringWriter writer = new StringWriter();
            calItems.add((CalendarItem) mi);
            context.targetMailbox.writeICalendarForCalendarItems(writer, octxt, calItems, useOutlookCompatMode, true, needAppleICalHacks, true);
            data = writer.toString().getBytes(charsetEncoder.charset());
        } else if (mi instanceof Contact) {
            VCard vcf = VCard.formatContact((Contact) mi);
            data = vcf.getFormatted().getBytes(charsetEncoder.charset());
        } else if (mi instanceof Message) {
            if (context.hasPart()) {
                MimeMessage mm = ((Message) mi).getMimeMessage();
                Set<String> attachmentNames = new HashSet<String>();
                for (String part : context.getPart().split(",")) {
                    BufferStream bs;
                    MimePart mp = Mime.getMimePart(mm, part);
                    long sz;
                    if (mp == null) {
                        throw MailServiceException.NO_SUCH_PART(part);
                    }
                    name = Mime.getFilename(mp);
                    if (!Normalizer.isNormalized(name, Normalizer.Form.NFC)) {
                        name = Normalizer.normalize(name, Normalizer.Form.NFC);
                    }
                    ext = null;
                    sz = mp.getSize();
                    if (sz == -1) {
                        sz = miSize;
                    }
                    if (name == null) {
                        name = "attachment";
                    } else {
                        int dot = name.lastIndexOf('.');
                        if (dot != -1 && dot < name.length() - 1) {
                            ext = name.substring(dot + 1);
                            name = name.substring(0, dot);
                        }
                    }
                    bs = new BufferStream(sz, 1024 * 1024);
                    InputStream stream = mp.getInputStream();
                    try {
                        bs.readFrom(stream);
                    } finally {
                        // close the stream, it could be an instance of PipedInputStream.
                        ByteUtil.closeStream(stream);
                    }
                    aoe = aos.newOutputEntry(getEntryName(mi, "", name, ext, charsetEncoder, attachmentNames), mi.getType().toString(), mi.getType().toByte(), mi.getDate());
                    sz = bs.getSize();
                    aoe.setSize(sz);
                    aos.putNextEntry(aoe);
                    bs.copyTo(aos.getOutputStream());
                    bs.close();
                    aos.closeEntry();
                }
                return aos;
            }
        }
        aoe = aos.newOutputEntry(path, mi.getType().toString(), mi.getType().toByte(), mi.getDate());
        if (data != null) {
            aoe.setSize(data.length);
            aos.putNextEntry(aoe);
            aos.write(data);
            aos.closeEntry();
        } else if (is != null) {
            if (context.shouldReturnBody()) {
                byte[] buf = new byte[aos.getRecordSize() * 20];
                int in;
                long remain = miSize;
                aoe.setSize(miSize);
                aos.putNextEntry(aoe);
                while (remain > 0 && (in = is.read(buf)) >= 0) {
                    aos.write(buf, 0, remain < in ? (int) remain : in);
                    remain -= in;
                }
                if (remain != 0) {
                    ZimbraLog.misc.error("mismatched blob size for item %d: expected %d", mi.getId(), miSize);
                    if (remain > 0) {
                        Arrays.fill(buf, (byte) ' ');
                        while (remain > 0) {
                            aos.write(buf, 0, remain < buf.length ? (int) remain : buf.length);
                            remain -= buf.length;
                        }
                    }
                    aos.closeEntry();
                    aoe = aos.newOutputEntry(path + ".err", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
                    aoe.setSize(0);
                    aos.putNextEntry(aoe);
                }
            } else {
                // Read headers into memory to compute size
                byte[] headerData = HeadersOnlyInputStream.getHeaders(is);
                aoe.setSize(headerData.length);
                aos.putNextEntry(aoe);
                aos.write(headerData);
            }
            aos.closeEntry();
        }
    } catch (Exception e) {
        throw ServiceException.FAILURE("archive error", e);
    } finally {
        ByteUtil.closeStream(is);
    }
    return aos;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) Task(com.zimbra.cs.mailbox.Task) EnumSet(java.util.EnumSet) Set(java.util.Set) HashSet(java.util.HashSet) MimeMessage(javax.mail.internet.MimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Message(com.zimbra.cs.mailbox.Message) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) Document(com.zimbra.cs.mailbox.Document) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItemInfo(com.zimbra.cs.mailbox.Message.CalendarItemInfo) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) StringWriter(java.io.StringWriter) MimeMessage(javax.mail.internet.MimeMessage) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) OperationContext(com.zimbra.cs.mailbox.OperationContext) InputStream(java.io.InputStream) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ExportPeriodNotSpecifiedException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodNotSpecifiedException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ExportPeriodTooLongException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodTooLongException) UserServletException(com.zimbra.cs.service.UserServletException) ParsedContact(com.zimbra.cs.mime.ParsedContact) Contact(com.zimbra.cs.mailbox.Contact) BufferStream(com.zimbra.common.util.BufferStream) MailItem(com.zimbra.cs.mailbox.MailItem) MimePart(javax.mail.internet.MimePart) SetCalendarItemData(com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData) ItemData(com.zimbra.cs.service.util.ItemData) Browser(com.zimbra.common.util.HttpUtil.Browser)

Example 3 with Task

use of com.zimbra.cs.mailbox.Task in project zm-mailbox by Zimbra.

the class TaskHit method getCompletionPercentage.

public int getCompletionPercentage() throws ServiceException {
    Task task = (Task) getCalendarItem();
    Invite inv = task.getDefaultInviteOrNull();
    if (inv != null) {
        String compPerc = inv.getPercentComplete();
        if (compPerc != null) {
            try {
                int toRet = Integer.parseInt(compPerc);
                return toRet;
            } catch (Exception e) {
                return 0;
            }
        }
    }
    return 0;
}
Also used : Task(com.zimbra.cs.mailbox.Task) Invite(com.zimbra.cs.mailbox.calendar.Invite) ServiceException(com.zimbra.common.service.ServiceException)

Example 4 with Task

use of com.zimbra.cs.mailbox.Task in project zm-mailbox by Zimbra.

the class TaskHit method getStatus.

public Status getStatus() throws ServiceException {
    Task task = (Task) getCalendarItem();
    Invite inv = task.getDefaultInviteOrNull();
    if (inv != null) {
        String status = inv.getStatus();
        try {
            Status s = Status.valueOf(status.toUpperCase());
            return s;
        } catch (IllegalArgumentException e) {
            ZimbraLog.index.debug("Unknown Task Status value: " + status.toUpperCase());
        }
    }
    return Status.DEFERRED;
}
Also used : Task(com.zimbra.cs.mailbox.Task) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 5 with Task

use of com.zimbra.cs.mailbox.Task in project zm-mailbox by Zimbra.

the class CompleteTaskInstance 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);
    ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
    Element exceptElem = request.getElement(MailConstants.E_CAL_EXCEPTION_ID);
    mbox.lock.lock();
    try {
        CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
        if (calItem == null) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
        }
        if (!(calItem instanceof Task)) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Calendar item is not a task");
        }
        Invite inv = calItem.getDefaultInviteOrNull();
        if (inv == null) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "No default invite found");
        }
        if (!inv.isRecurrence()) {
            throw ServiceException.INVALID_REQUEST("Task is not a recurring task", null);
        }
        ParsedDateTime recurStart = inv.getStartTime();
        if (recurStart == null) {
            throw ServiceException.INVALID_REQUEST("Recurring task is missing start time", null);
        }
        // the instance being marked complete
        TimeZoneMap tzmap = inv.getTimeZoneMap();
        Element tzElem = request.getOptionalElement(MailConstants.E_CAL_TZ);
        ICalTimeZone tz = null;
        if (tzElem != null) {
            tz = CalendarUtils.parseTzElement(tzElem);
            tzmap.add(tz);
        }
        ParsedDateTime exceptDt = CalendarUtils.parseDateTime(exceptElem, tzmap);
        if (exceptDt.getUtcTime() != recurStart.getUtcTime()) {
            throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
        }
        // Create a new single-instance task for completed date.
        Invite completed = createCompletedInstanceInvite(inv, exceptDt);
        mbox.addInvite(octxt, completed, calItem.getFolderId());
        // Update recurrence's start date to the next instance start date.
        long oldStart = recurStart.getUtcTime();
        long newStart = -1;
        Collection<Instance> instances = calItem.expandInstances(oldStart, Long.MAX_VALUE, false);
        for (Instance inst : instances) {
            if (inst.getStart() > oldStart) {
                newStart = inst.getStart();
                break;
            }
        }
        if (newStart != -1) {
            // Update DTSTART to newStart.
            ParsedDateTime newStartDt = ParsedDateTime.fromUTCTime(newStart);
            newStartDt.toTimeZone(inv.getStartTime().getTimeZone());
            newStartDt.setHasTime(recurStart.hasTime());
            // Update DUE.
            ParsedDuration dur = inv.getEffectiveDuration();
            if (dur != null) {
                ParsedDateTime due = newStartDt.add(dur);
                inv.setDtEnd(due);
            }
            inv.setDtStart(newStartDt);
            inv.setSeqNo(inv.getSeqNo() + 1);
            inv.setDtStamp(System.currentTimeMillis());
            mbox.addInvite(octxt, inv, calItem.getFolderId());
        } else {
            // No more instance left.  Delete the recurring task.
            mbox.delete(octxt, calItem.getId(), calItem.getType());
        }
    } finally {
        mbox.lock.release();
    }
    // response
    Element response = getResponseElement(zsc);
    return response;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Task(com.zimbra.cs.mailbox.Task) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Element(com.zimbra.common.soap.Element) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone)

Aggregations

Task (com.zimbra.cs.mailbox.Task)6 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)4 Invite (com.zimbra.cs.mailbox.calendar.Invite)4 ItemId (com.zimbra.cs.service.util.ItemId)3 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)2 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)2 ServiceException (com.zimbra.common.service.ServiceException)2 Element (com.zimbra.common.soap.Element)2 Appointment (com.zimbra.cs.mailbox.Appointment)2 Instance (com.zimbra.cs.mailbox.CalendarItem.Instance)2 Contact (com.zimbra.cs.mailbox.Contact)2 MailItem (com.zimbra.cs.mailbox.MailItem)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2 Message (com.zimbra.cs.mailbox.Message)2 OperationContext (com.zimbra.cs.mailbox.OperationContext)2 Geo (com.zimbra.common.calendar.Geo)1 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)1 BufferStream (com.zimbra.common.util.BufferStream)1 Browser (com.zimbra.common.util.HttpUtil.Browser)1