use of com.zimbra.cs.index.ZimbraQueryResults in project zm-mailbox by Zimbra.
the class SearchConv 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);
SearchConvRequest req = JaxbUtil.elementToJaxb(request);
boolean nest = ZmBoolean.toBool(req.getNestMessages(), false);
Account acct = getRequestedAccount(zsc);
SearchParams params = SearchParams.parse(req, zsc, acct.getPrefMailInitialSearch());
// append (conv:(convid)) onto the beginning of the queryStr
ItemId cid = new ItemId(req.getConversationId(), zsc);
params.setQueryString("conv:\"" + cid.toString(ifmt) + "\" (" + params.getQueryString() + ')');
// force to group-by-message
params.setTypes(EnumSet.of(MailItem.Type.MESSAGE));
Element response = null;
if (cid.belongsTo(mbox)) {
// local
ZimbraQueryResults results = mbox.index.search(zsc.getResponseProtocol(), octxt, params);
try {
response = zsc.createElement(MailConstants.SEARCH_CONV_RESPONSE);
response.addAttribute(MailConstants.A_QUERY_OFFSET, Integer.toString(params.getOffset()));
SortBy sort = results.getSortBy();
response.addAttribute(MailConstants.A_SORTBY, sort.toString());
List<Message> msgs = mbox.getMessagesByConversation(octxt, cid.getId(), sort, -1);
if (msgs.isEmpty() && zsc.isDelegatedRequest()) {
throw ServiceException.PERM_DENIED("you do not have sufficient permissions");
}
// filter out IMAP \Deleted messages from the message lists
Conversation conv = mbox.getConversationById(octxt, cid.getId());
if (conv.isTagged(Flag.FlagInfo.DELETED)) {
List<Message> raw = msgs;
msgs = new ArrayList<Message>();
for (Message msg : raw) {
if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
msgs.add(msg);
}
}
}
Element container = nest ? ToXML.encodeConversationSummary(response, ifmt, octxt, conv, CONVERSATION_FIELD_MASK) : response;
SearchResponse builder = new SearchResponse(zsc, octxt, container, params);
builder.setAllRead(conv.getUnreadCount() == 0);
boolean more = putHits(octxt, ifmt, builder, msgs, results, params, conv);
response.addAttribute(MailConstants.A_QUERY_MORE, more);
// call me AFTER putHits since some of the <info> is generated by the getting of the hits!
builder.add(results.getResultInfo());
} finally {
Closeables.closeQuietly(results);
}
return response;
} else {
// remote
try {
Element proxyRequest = zsc.createElement(MailConstants.SEARCH_CONV_REQUEST);
Account target = Provisioning.getInstance().get(AccountBy.id, cid.getAccountId(), zsc.getAuthToken());
if (target != null) {
params.setInlineRule(params.getInlineRule().toLegacyExpandResults(target.getServer()));
}
params.encodeParams(proxyRequest);
proxyRequest.addAttribute(MailConstants.A_NEST_MESSAGES, nest);
proxyRequest.addAttribute(MailConstants.A_CONV_ID, cid.toString());
// okay, lets run the search through the query parser -- this has the side-effect of
// re-writing the query in a format that is OK to proxy to the other server -- since the
// query has an "AND conv:remote-conv-id" part, the query parser will figure out the right
// format for us. TODO somehow make this functionality a bit more exposed in the
// ZimbraQuery APIs...
String rewrittenQueryString = mbox.getRewrittenQueryString(octxt, params);
proxyRequest.addAttribute(MailConstants.E_QUERY, rewrittenQueryString, Element.Disposition.CONTENT);
// proxy to remote account
response = proxyRequest(proxyRequest, context, target.getId());
return response.detach();
} catch (SoapFaultException e) {
throw ServiceException.FAILURE("SoapFaultException: ", e);
}
}
}
use of com.zimbra.cs.index.ZimbraQueryResults in project zm-mailbox by Zimbra.
the class ArchiveFormatter method formatCallback.
@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException, UserServletException {
// Disable the jetty timeout
disableJettyTimeout(context);
HashMap<Integer, Integer> cnts = new HashMap<Integer, Integer>();
int dot;
HashMap<Integer, String> fldrs = new HashMap<Integer, String>();
String emptyname = context.params.get("emptyname");
String ext = "." + getType();
String filename = context.params.get("filename");
String lock = context.params.get("lock");
String query = context.getQueryString();
Set<String> names = new HashSet<String>(4096);
Set<MailItem.Type> sysTypes = EnumSet.of(MailItem.Type.FOLDER, MailItem.Type.SEARCHFOLDER, MailItem.Type.TAG, MailItem.Type.FLAG, MailItem.Type.MOUNTPOINT);
Set<MailItem.Type> searchTypes = EnumSet.of(MailItem.Type.MESSAGE, MailItem.Type.CONTACT, MailItem.Type.DOCUMENT, MailItem.Type.WIKI, MailItem.Type.APPOINTMENT, MailItem.Type.TASK, MailItem.Type.CHAT, MailItem.Type.NOTE);
ArchiveOutputStream aos = null;
String types = context.getTypesString();
MailboxMaintenance maintenance = null;
try {
if (filename == null || filename.equals("")) {
Date date = new Date();
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
SimpleDateFormat sdf = new SimpleDateFormat(".H-m-s");
if (context.hasPart()) {
filename = "attachments";
} else {
filename = context.targetMailbox.getAccountId() + '.' + df.format(date).replace('/', '-') + sdf.format(date);
}
} else if ((dot = filename.lastIndexOf('.')) != -1) {
String userProvidedExtension = filename.substring(dot + 1);
if (BLE.contains(userProvidedExtension.toUpperCase())) {
filename = filename.substring(0, dot);
}
}
if (!filename.endsWith(ext)) {
filename += ext;
}
if (emptyname != null && !emptyname.equals("") && !emptyname.endsWith(ext)) {
emptyname += ext;
}
context.resp.addHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, Part.ATTACHMENT, filename));
if (ext.equals(".tar")) {
context.resp.setContentType("application/x-tar");
} else if (ext.equals(".tgz")) {
context.resp.setContentType("application/x-compressed-tar");
} else if (ext.equals(".zip")) {
context.resp.setContentType("application/zip");
}
if (!Strings.isNullOrEmpty(types)) {
try {
searchTypes = MailItem.Type.setOf(types);
} catch (IllegalArgumentException e) {
throw MailServiceException.INVALID_TYPE(e.getMessage());
}
sysTypes.clear();
// do not include conversations even when requested
// (to be compatible with 7.1.4 and later. bug 67407)
searchTypes.remove(MailItem.Type.CONVERSATION);
}
if (lock != null && (lock.equals("1") || lock.equals("t") || lock.equals("true"))) {
maintenance = MailboxManager.getInstance().beginMaintenance(context.targetMailbox.getAccountId(), context.targetMailbox.getId());
}
Charset charset = context.getCharset();
CharsetEncoder encoder = charset.newEncoder();
if (context.requestedItems != null) {
try {
for (UserServletContext.Item item : context.requestedItems) aos = saveItem(context, item.mailItem, fldrs, cnts, item.versioned, aos, encoder, names);
} catch (Exception e) {
warn(e);
}
} else if (context.target != null && !(context.target instanceof Folder)) {
try {
aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
} catch (Exception e) {
warn(e);
}
} else {
ZimbraQueryResults results = null;
boolean saveTargetFolder = false;
if (context.target instanceof Folder) {
Folder f = (Folder) context.target;
if (f.getId() != Mailbox.ID_FOLDER_USER_ROOT) {
saveTargetFolder = true;
query = "under:\"" + f.getPath() + "\"" + (query == null ? "" : " " + query);
}
}
int maxDays = context.targetAccount.getIntAttr(Provisioning.A_zimbraExportMaxDays, 0);
if (maxDays > 0) {
if (context.getStartTime() == TIME_UNSPECIFIED || context.getEndTime() == TIME_UNSPECIFIED || context.getEndTime() == 0) {
ZimbraLog.misc.warn("Export rejected. start and end param must be set. end param must be non-zero");
throw new ExportPeriodNotSpecifiedException(maxDays);
} else if (context.getEndTime() - context.getStartTime() > maxDays * Constants.MILLIS_PER_DAY) {
long requestDays = (long) Math.ceil((double) (context.getEndTime() - context.getStartTime()) / Constants.MILLIS_PER_DAY);
ZimbraLog.misc.warn("Export rejected. Specified period %d days is longer than zimbraExportMaxDays %d days.", requestDays, maxDays);
throw new ExportPeriodTooLongException(requestDays, maxDays);
}
}
String taskQuery = query;
if (query == null) {
query = "";
}
String calendarQuery = query;
if (context.getStartTime() != TIME_UNSPECIFIED) {
query = query + " after:" + context.getStartTime();
calendarQuery = calendarQuery + " appt-start:>=" + context.getStartTime();
}
if (context.getEndTime() != TIME_UNSPECIFIED) {
query = query + " before:" + context.getEndTime();
calendarQuery = calendarQuery + " appt-end:<" + context.getEndTime();
}
if (query == null || query.equals("")) {
SortPath sp = new SortPath();
for (MailItem.Type type : sysTypes) {
List<MailItem> items = context.targetMailbox.getItemList(context.opContext, type);
Collections.sort(items, sp);
for (MailItem item : items) {
aos = saveItem(context, item, fldrs, cnts, false, aos, encoder, names);
}
}
query = "is:local";
}
Map<Set<MailItem.Type>, String> typesMap = new HashMap<Set<MailItem.Type>, String>();
typesMap.put(searchTypes, query);
if (context.getStartTime() != TIME_UNSPECIFIED || context.getEndTime() != TIME_UNSPECIFIED) {
if (searchTypes.contains(MailItem.Type.APPOINTMENT)) {
searchTypes.remove(MailItem.Type.APPOINTMENT);
Set<MailItem.Type> calendarTypes = new HashSet<MailItem.Type>();
calendarTypes.add(MailItem.Type.APPOINTMENT);
typesMap.put(calendarTypes, calendarQuery);
}
if (searchTypes.contains(MailItem.Type.TASK)) {
searchTypes.remove(MailItem.Type.TASK);
Set<MailItem.Type> taskTypes = new HashSet<MailItem.Type>();
taskTypes.add(MailItem.Type.TASK);
typesMap.put(taskTypes, (StringUtil.isNullOrEmpty(taskQuery)) ? "is:local" : taskQuery);
}
}
for (Map.Entry<Set<MailItem.Type>, String> entry : typesMap.entrySet()) {
results = context.targetMailbox.index.search(context.opContext, entry.getValue(), entry.getKey(), SortBy.NONE, LC.zimbra_archive_formatter_search_chunk_size.intValue());
try {
while (results.hasNext()) {
if (saveTargetFolder) {
saveTargetFolder = false;
aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
}
aos = saveItem(context, results.getNext().getMailItem(), fldrs, cnts, false, aos, encoder, names);
}
Closeables.closeQuietly(results);
results = null;
} catch (Exception e) {
warn(e);
} finally {
Closeables.closeQuietly(results);
}
}
}
if (aos == null) {
if (emptyname == null) {
context.resp.setHeader("Content-Disposition", null);
throw new UserServletException(HttpServletResponse.SC_NO_CONTENT, "No data found");
}
context.resp.setHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, Part.ATTACHMENT, emptyname));
aos = getOutputStream(context, UTF8);
}
} finally {
if (maintenance != null) {
MailboxManager.getInstance().endMaintenance(maintenance, true, true);
}
if (aos != null) {
try {
aos.close();
} catch (Exception e) {
}
}
}
}
Aggregations