1 package org.columba.mail.gui.table.model; 19 20 import java.text.Collator ; 21 import java.util.Collections ; 22 import java.util.Comparator ; 23 import java.util.Date ; 24 import java.util.Enumeration ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.StringTokenizer ; 29 import java.util.logging.Logger ; 30 31 import org.columba.mail.message.ColumbaHeader; 32 import org.columba.mail.message.IColumbaHeader; 33 34 49 public class TableModelThreadedView implements ModelVisitor { 50 51 52 private static final Logger LOG = Logger 53 .getLogger("org.columba.mail.gui.table.model"); 54 55 private boolean enabled; 56 57 private HashMap hashtable; 58 59 private int idCount = 0; 60 61 private Collator collator; 62 63 public TableModelThreadedView() { 64 65 enabled = false; 66 67 collator = Collator.getInstance(); 68 } 69 70 public boolean isEnabled() { 71 return enabled; 72 } 73 74 public void setEnabled(boolean b) { 75 enabled = b; 76 } 77 78 89 public static String [] parseReferences(String references) { 90 91 StringTokenizer tk = new StringTokenizer (references, ">"); 92 String [] list = new String [tk.countTokens()]; 93 int i = 0; 94 95 while (tk.hasMoreTokens()) { 96 String str = (String ) tk.nextToken(); 97 str = str.trim(); 98 str = str + ">"; 99 list[i++] = str; 100 101 } 102 103 return list; 104 } 105 106 protected boolean add(MessageNode node, MessageNode rootNode) { 107 IColumbaHeader header = node.getHeader(); 108 String references = (String ) header.get("References"); 109 String inReply = (String ) header.get("In-Reply-To"); 110 111 if (inReply != null) { 112 inReply = inReply.trim(); 113 114 if (hashtable.containsKey(inReply)) { 115 116 MessageNode parent = (MessageNode) hashtable.get(inReply); 117 if ( !parent.isNodeAncestor(node)) 118 parent.add(node); 119 120 return true; 121 } 122 } else if (references != null) { 123 references = references.trim(); 124 125 String [] referenceList = parseReferences(references); 126 int count = referenceList.length; 127 128 if (count >= 1) { 129 MessageNode parent = (MessageNode) hashtable 131 .get(referenceList[referenceList.length - 1].trim()); 132 if (parent != null) { 133 parent.add(node); 134 return true; 135 } 136 } 137 } 138 139 return false; 140 } 141 142 protected void thread(MessageNode rootNode) { 144 idCount = 0; 145 146 if (rootNode == null) { 147 return; 148 } 149 150 createHashmap(rootNode); 152 153 Iterator it = hashtable.keySet().iterator(); 157 while (it.hasNext()) { 158 String key = (String ) it.next(); 159 160 MessageNode node = (MessageNode) hashtable.get(key); 161 add(node, rootNode); 162 } 163 164 } 165 166 private String getMessageID(MessageNode node) { 167 IColumbaHeader header = node.getHeader(); 168 169 String id = (String ) header.get("Message-ID"); 170 171 if (id == null) { 172 id = (String ) header.get("Message-Id"); 173 } 174 175 if (id == null) { 177 id = new String ("<bogus-id:" + (idCount++) + ">"); 178 header.set("Message-ID", id); 179 } 180 181 id = id.trim(); 182 183 return id; 184 } 185 186 194 private void createHashmap(MessageNode rootNode) { 195 hashtable = new HashMap (rootNode.getChildCount()); 196 197 for (Enumeration enumeration = rootNode.children(); enumeration 199 .hasMoreElements();) { 200 MessageNode node = (MessageNode) enumeration.nextElement(); 201 String id = getMessageID(node); 202 203 hashtable.put(id, node); 204 205 } 206 } 207 208 215 protected void sort(int columnNumber, MessageNode node) { 216 for (int i = 0; i < node.getChildCount(); i++) { 217 MessageNode child = (MessageNode) node.getChildAt(i); 218 219 if (!child.isLeaf()) { 222 List v = child.getVector(); 224 Collections.sort(v, new MessageHeaderComparator(columnNumber, 225 true)); 226 227 boolean contains = containsRecentChildren(child); 230 child.setHasRecentChildren(contains); 231 } 232 } 233 } 234 235 protected boolean containsRecentChildren(MessageNode parent) { 236 for (int i = 0; i < parent.getChildCount(); i++) { 237 MessageNode child = (MessageNode) parent.getChildAt(i); 238 239 if (((ColumbaHeader) child.getHeader()).getFlags().getSeen() == false) { 240 LOG.info("found recent message"); 242 243 return true; 244 } else { 245 containsRecentChildren(child); 246 } 247 } 248 249 return false; 250 } 251 252 class MessageHeaderComparator implements Comparator { 253 254 protected int column; 255 256 protected boolean ascending; 257 258 private String columnName; 259 260 public MessageHeaderComparator(int sortCol, boolean sortAsc) { 261 column = sortCol; 262 ascending = sortAsc; 263 264 this.columnName = "Date"; 265 } 266 267 public int compare(Object o1, Object o2) { 268 269 MessageNode node1 = (MessageNode) o1; 270 MessageNode node2 = (MessageNode) o2; 271 272 IColumbaHeader header1 = node1.getHeader(); 273 IColumbaHeader header2 = node2.getHeader(); 274 275 if ((header1 == null) || (header2 == null)) { 276 return 0; 277 } 278 279 int result = 0; 280 281 if (columnName.equals("Date")) { 282 Date d1 = (Date ) header1.get("columba.date"); 283 Date d2 = (Date ) header2.get("columba.date"); 284 285 if ((d1 == null) || (d2 == null)) { 286 result = 0; 287 } else { 288 result = d1.compareTo(d2); 289 } 290 } else { 291 Object item1 = header1.get(columnName); 292 Object item2 = header2.get(columnName); 293 294 if ((item1 != null) && (item2 == null)) { 295 result = 1; 296 } else if ((item1 == null) && (item2 != null)) { 297 result = -1; 298 } else if ((item1 == null) && (item2 == null)) { 299 result = 0; 300 } else if (item1 instanceof String ) { 301 result = collator.compare((String ) item1, (String ) item2); 302 } 303 } 304 305 if (!ascending) { 306 result = -result; 307 } 308 309 return result; 310 } 311 312 public boolean equals(Object obj) { 313 if (obj instanceof MessageHeaderComparator) { 314 MessageHeaderComparator compObj = (MessageHeaderComparator) obj; 315 316 return (compObj.column == column) 317 && (compObj.ascending == ascending); 318 } 319 320 return false; 321 } 322 } 323 324 327 public void visit(HeaderTableModel realModel) { 328 if ( enabled == false ) return; 329 330 thread(realModel.getRootNode()); 331 332 sort(realModel.getColumnNumber("Date"), realModel.getRootNode()); 334 } 335 } | Popular Tags |