001 /*
002 * Copyright 2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package com.hs.mail.imap.mailbox;
017
018 import java.util.List;
019
020 import com.hs.mail.imap.dao.DaoFactory;
021
022 /**
023 * Convert Unique Identifier (UID) to Message Sequence Number (MSN) and vice
024 * versa.
025 *
026 * @author Won Chul Doh
027 * @since Mar 22, 2010
028 *
029 */
030 public class UidToMsnMapper {
031
032 protected SelectedMailbox selected = null;
033 protected List<Long> uids;
034 protected boolean useUID = false;
035
036 public UidToMsnMapper(SelectedMailbox selected, List<Long> uids, boolean useUID) {
037 this.selected = selected;
038 this.uids = uids;
039 this.useUID = useUID;
040 }
041
042 public UidToMsnMapper(SelectedMailbox selected, boolean useUID) {
043 this(selected, selected.getCachedUids(), useUID);
044 }
045
046 public long getUID(int msgnum) {
047 long uid = selected.getUID(msgnum);
048 if (uid == -1) {
049 prepare();
050 uid = (msgnum <= uids.size()) ? (Long) uids.get(msgnum - 1) : -1;
051 if (uid != -1)
052 selected.add(msgnum, uid);
053 }
054 return uid;
055 }
056
057 public int getMessageNumber(long uid) {
058 int msgnum = selected.getMessageNumber(uid);
059 if (msgnum == -1) {
060 prepare();
061 if (uid == Long.MAX_VALUE) { // *
062 msgnum = (uids.size() > 0) ? uids.size() : -1;
063 } else {
064 int i = uids.indexOf(uid);
065 msgnum = (i >= 0) ? i + 1 : -1;
066 if (msgnum != -1)
067 selected.add(msgnum, uid);
068 }
069 }
070 return msgnum;
071 }
072
073 public List<Long> getUIDList() {
074 return uids;
075 }
076
077 /**
078 * Find the smallest message sequence number whose corresponding unique
079 * identifier is equal or greater than the given unique identifier.
080 *
081 * @param min
082 * the key UID to be searched for
083 * @return the smallest message sequence number if found; otherwise -1
084 */
085 public long getMinMessageNumber(long min) {
086 if (useUID) {
087 int msgnum = getMessageNumber(min);
088 if (msgnum == -1) {
089 if ((msgnum = search(uids, min)) != -1) {
090 return (uids.get(msgnum) >= min) ? msgnum + 1 : msgnum + 2;
091 }
092 }
093 return msgnum;
094 } else {
095 return min;
096 }
097 }
098
099 /**
100 * Find the largest message sequence number whose corresponding unique
101 * identifier is equal or less than the given unique identifier.
102 *
103 * @param max
104 * the key UID to be searched for
105 * @return the largest message sequence number if found; otherwise -1
106 */
107 public long getMaxMessageNumber(long max) {
108 if (useUID) {
109 int msgnum = getMessageNumber(max);
110 if (msgnum == -1) {
111 if ((msgnum = search(uids, max)) != -1) {
112 return (uids.get(msgnum) <= max) ? msgnum + 1: msgnum;
113 }
114 }
115 return msgnum;
116 } else {
117 return max;
118 }
119 }
120
121 protected int search(List<Long> v, long t) {
122 int low = 0;
123 int mid = -1;
124 int high = v.size() - 1;
125 while (low <= high) {
126 mid = (low + high) / 2;
127 long c = v.get(mid) - t;
128 if (c > 0)
129 high = mid - 1;
130 else if (c < 0)
131 low = mid + 1;
132 else
133 break;
134 }
135 return mid;
136 }
137
138 private void prepare() {
139 if (uids == null)
140 uids = DaoFactory.getMessageDao().getMessageIDList(
141 selected.getMailboxID());
142 }
143
144 }