diff --git a/src/com/fsck/k9/provider/MessageProvider.java b/src/com/fsck/k9/provider/MessageProvider.java index 621cd8daf..361be740f 100644 --- a/src/com/fsck/k9/provider/MessageProvider.java +++ b/src/com/fsck/k9/provider/MessageProvider.java @@ -3,6 +3,7 @@ package com.fsck.k9.provider; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executors; @@ -71,6 +72,16 @@ public class MessageProvider extends ContentProvider *

Type: TEXT

*/ String PREVIEW = "preview"; + + String ACCOUNT = "account"; + String URI = "uri"; + String DELETE_URI = "delUri"; + + /** + * @deprecated the field value is misnamed/misleading - present for compatibility purpose only. To be removed. + */ + @Deprecated + String INCREMENT = "id"; } protected interface QueryHandler @@ -96,6 +107,119 @@ public class MessageProvider extends ContentProvider String selection, String[] selectionArgs, String sortOrder) throws Exception; } + /** + * Extracts a value from an object. + * + * @param + * @param + */ + public static interface FieldExtractor + { + K getField(T source); + } + + /** + * Extracts the {@link LocalStore.LocalMessage#getId() ID} from the given + * {@link MessageInfoHolder}. The underlying {@link Message} is expected to + * be a {@link LocalStore.LocalMessage}. + */ + public static class IdExtractor implements FieldExtractor + { + @Override + public Long getField(final MessageInfoHolder source) + { + return ((LocalStore.LocalMessage) source.message).getId(); + } + } + public static class CountExtractor implements FieldExtractor + { + private Integer mCount; + public CountExtractor(final int count) + { + mCount = count; + } + @Override + public Integer getField(final T source) + { + return mCount; + } + } + public static class SubjectExtractor implements FieldExtractor + { + @Override + public String getField(final MessageInfoHolder source) + { + return source.subject; + } + } + public static class SendDateExtractor implements FieldExtractor + { + @Override + public Long getField(final MessageInfoHolder source) + { + return source.message.getSentDate().getTime(); + } + } + public static class PreviewExtractor implements FieldExtractor + { + @Override + public String getField(final MessageInfoHolder source) + { + return source.preview; + } + } + public static class UriExtractor implements FieldExtractor + { + @Override + public String getField(final MessageInfoHolder source) + { + return source.uri; + } + } + public static class DeleteUriExtractor implements FieldExtractor + { + @Override + public String getField(final MessageInfoHolder source) + { + final Message message = source.message; + return CONTENT_URI + "/delete_message/" + + message.getFolder().getAccount().getAccountNumber() + "/" + + message.getFolder().getName() + "/" + message.getUid(); + } + } + public static class SenderExtractor implements FieldExtractor + { + @Override + public CharSequence getField(final MessageInfoHolder source) + { + return source.sender; + } + } + public static class AccountExtractor implements FieldExtractor + { + @Override + public String getField(final MessageInfoHolder source) + { + return source.message.getFolder().getAccount().getDescription(); + } + } + + /** + * @deprecated having an incremential value has no real interest, + * implemented for compatibility only + */ + @Deprecated + // TODO remove + public static class IncrementExtractor implements FieldExtractor + { + private int count = 0; + @Override + public Integer getField(final MessageInfoHolder source) + { + return count++; + } + } + /** * Retrieve messages from the integrated inbox. */ @@ -124,8 +248,6 @@ public class MessageProvider extends ContentProvider */ protected MatrixCursor getMessages(final String[] projection) throws InterruptedException { - // TODO use the given projection if prevent - final MatrixCursor cursor = new MatrixCursor(DEFAULT_MESSAGE_PROJECTION); final BlockingQueue> queue = new SynchronousQueue>(); // new code for integrated inbox, only execute this once as it will be processed afterwards via the listener @@ -141,29 +263,94 @@ public class MessageProvider extends ContentProvider Collections.sort(holders, new MessageList.ReverseComparator( new MessageList.DateComparator())); - int id = -1; + final String[] projectionToUse; + if (projection == null) + { + projectionToUse = DEFAULT_MESSAGE_PROJECTION; + } + else + { + projectionToUse = projection; + } + + final LinkedHashMap> extractors = resolveMessageExtractors(projectionToUse, holders.size()); + final int fieldCount = extractors.size(); + + final String[] actualProjection = extractors.keySet().toArray(new String[fieldCount]); + final MatrixCursor cursor = new MatrixCursor(actualProjection); + for (final MessageInfoHolder holder : holders) { - final Message message = holder.message; - id++; + final Object[] o = new Object[fieldCount]; - cursor.addRow(new Object[] - { - id, - message.getSentDate().getTime(), - holder.sender, - holder.subject, - holder.preview, - holder.account, - holder.uri, - CONTENT_URI + "/delete_message/" - + message.getFolder().getAccount().getAccountNumber() + "/" - + message.getFolder().getName() + "/" + message.getUid() - }); + int i = 0; + for (final FieldExtractor extractor : extractors.values()) + { + o[i] = extractor.getField(holder); + i += 1; + } + + cursor.addRow(o); } + return cursor; } + // returns LinkedHashMap (rather than Map) to emphasize the inner element ordering + protected LinkedHashMap> resolveMessageExtractors(final String[] projection, int count) + { + final LinkedHashMap> extractors = new LinkedHashMap>(); + + for (final String field : projection) + { + if (extractors.containsKey(field)) + { + continue; + } + if (MessageColumns._ID.equals(field)) + { + extractors.put(field, new IdExtractor()); + } + else if (MessageColumns._COUNT.equals(field)) + { + extractors.put(field, new CountExtractor(count)); + } + else if (MessageColumns.SUBJECT.equals(field)) + { + extractors.put(field, new SubjectExtractor()); + } + else if (MessageColumns.SENDER.equals(field)) + { + extractors.put(field, new SenderExtractor()); + } + else if (MessageColumns.SEND_DATE.equals(field)) + { + extractors.put(field, new SendDateExtractor()); + } + else if (MessageColumns.PREVIEW.equals(field)) + { + extractors.put(field, new PreviewExtractor()); + } + else if (MessageColumns.URI.equals(field)) + { + extractors.put(field, new UriExtractor()); + } + else if (MessageColumns.DELETE_URI.equals(field)) + { + extractors.put(field, new DeleteUriExtractor()); + } + else if (MessageColumns.ACCOUNT.equals(field)) + { + extractors.put(field, new AccountExtractor()); + } + else if (MessageColumns.INCREMENT.equals(field)) + { + extractors.put(field, new IncrementExtractor()); + } + } + return extractors; + } + } /** @@ -659,9 +846,9 @@ public class MessageProvider extends ContentProvider MessageColumns.SENDER, MessageColumns.SUBJECT, MessageColumns.PREVIEW, - "account", - "uri", - "delUri" + MessageColumns.ACCOUNT, + MessageColumns.URI, + MessageColumns.DELETE_URI }; /**