1 17 package org.columba.mail.folder.search; 18 19 import java.util.Arrays ; 20 import java.util.Hashtable ; 21 import java.util.LinkedList ; 22 import java.util.List ; 23 import java.util.ListIterator ; 24 import java.util.logging.Logger ; 25 26 import javax.swing.JOptionPane ; 27 28 import org.columba.api.command.IStatusObservable; 29 import org.columba.api.plugin.IExtension; 30 import org.columba.api.plugin.IExtensionHandler; 31 import org.columba.core.base.ListTools; 32 import org.columba.core.filter.AbstractFilter; 33 import org.columba.core.filter.Filter; 34 import org.columba.core.filter.FilterCriteria; 35 import org.columba.core.filter.FilterRule; 36 import org.columba.core.filter.IFilter; 37 import org.columba.core.filter.IFilterCriteria; 38 import org.columba.core.filter.IFilterRule; 39 import org.columba.core.plugin.PluginManager; 40 import org.columba.mail.folder.AbstractMessageFolder; 41 import org.columba.mail.folder.event.FolderListener; 42 import org.columba.mail.folder.event.IFolderEvent; 43 import org.columba.mail.plugin.IExtensionHandlerKeys; 44 import org.columba.mail.util.MailResourceLoader; 45 46 55 public class DefaultSearchEngine { 56 57 private static final Logger LOG = Logger 58 .getLogger("org.columba.mail.folder.search"); 59 60 61 65 private static Hashtable filterCache; 66 67 70 private AbstractMessageFolder folder; 71 72 75 private QueryEngine nonDefaultEngine; 76 77 83 public DefaultSearchEngine(AbstractMessageFolder folder) { 84 this.folder = folder; 85 filterCache = new Hashtable (); 86 nonDefaultEngine = new DummyQueryEngine(); 87 folder.addFolderListener(new FolderListener() { 88 public void messageAdded(IFolderEvent e) { 89 try { 90 getNonDefaultEngine().messageAdded(e.getChanges()); 91 } catch (Exception ex) { 92 } 93 } 94 95 public void messageRemoved(IFolderEvent e) { 96 try { 97 getNonDefaultEngine().messageRemoved(e.getChanges()); 98 } catch (Exception ex) { 99 } 100 } 101 102 public void folderPropertyChanged(IFolderEvent e) { 103 } 104 105 public void folderAdded(IFolderEvent e) { 106 } 107 108 public void folderRemoved(IFolderEvent e) { 109 } 110 111 public void messageFlagChanged(IFolderEvent e) { 112 114 } 115 }); 116 } 117 118 public IStatusObservable getObservable() { 119 return folder.getObservable(); 120 } 121 122 protected synchronized AbstractFilter getFilter( 123 IFilterCriteria filterCriteria, String type) { 124 if (filterCache.containsKey(type) == true) { 126 AbstractFilter f = (AbstractFilter) filterCache.get(type); 127 128 f.setUp(filterCriteria); 130 131 return f; 132 } 133 134 AbstractFilter instance = null; 135 136 try { 137 IExtensionHandler handler = PluginManager 138 .getInstance().getExtensionHandler(IExtensionHandlerKeys.ORG_COLUMBA_MAIL_FILTER); 139 IExtension extension = handler.getExtension(type); 140 141 instance = (AbstractFilter) extension.instanciateExtension(null); 142 } catch (Exception ex) { 143 JOptionPane.showMessageDialog(null, 144 "Error while trying to load filter plugin =" + type); 145 ex.printStackTrace(); 146 } 147 148 instance.setUp(filterCriteria); 150 151 if (instance != null) { 152 filterCache.put(type, instance); 153 } 154 155 return instance; 156 } 157 158 protected boolean processRule(Object uid, IFilterCriteria criteria, 159 String type) throws Exception { 160 if (type == null) { 161 JOptionPane.showMessageDialog(null, 162 "Filter type couldn't been found", "Error occured", 163 JOptionPane.ERROR_MESSAGE); 164 165 return false; 166 } 167 168 AbstractFilter instance = getFilter(criteria, type); 169 170 if (instance == null) { 171 return false; 172 } 173 174 return instance.process(folder, uid); 175 } 176 177 protected List processCriteria(IFilterRule rule, List uids) throws Exception { 178 LinkedList result = new LinkedList (); 179 boolean b; 180 181 int match = rule.getConditionInt(); 182 183 ListIterator it = uids.listIterator(); 184 185 Object uid; 186 187 if (match == FilterRule.MATCH_ALL) { 189 while (it.hasNext()) { 190 b = true; 191 uid = it.next(); 192 193 for (int i = 0; (i < rule.count()) && b; i++) { 194 IFilterCriteria criteria = rule.get(i); 195 196 String type = criteria.getTypeString(); 197 198 b &= processRule(uid, criteria, type); 199 } 200 201 if (b) { 202 result.add(uid); 203 } 204 } 205 } else { 207 while (it.hasNext()) { 208 b = false; 209 uid = it.next(); 210 211 for (int i = 0; (i < rule.count()) && !b; i++) { 212 IFilterCriteria criteria = rule.get(i); 213 214 String type = criteria.getTypeString(); 215 216 b = processRule(uid, criteria, type); 217 } 218 219 if (b) { 220 result.add(uid); 221 } 222 } 223 } 224 225 return result; 229 } 230 231 protected void divideFilterRule(IFilterRule filterRule, 232 IFilterRule notDefaultEngine, IFilterRule defaultEngine) { 233 IFilterCriteria actCriteria; 234 235 String [] caps = getNonDefaultEngine().getCaps(); 236 237 List capList = Arrays.asList(caps); 238 239 notDefaultEngine.setCondition(filterRule.getCondition()); 240 defaultEngine.setCondition(filterRule.getCondition()); 241 242 for (int i = 0; i < filterRule.count(); i++) { 243 actCriteria = filterRule.get(i); 244 245 if (capList.contains(actCriteria.getTypeString())) { 246 defaultEngine.add(actCriteria); 249 } else { 250 notDefaultEngine.add(actCriteria); 252 } 253 } 254 } 255 256 260 public Object [] searchMessages(IFilter filter, Object [] uids) 261 throws Exception { 262 if (!filter.getEnabled()) { 263 return new Object [] {}; 265 } 266 267 List notDefaultEngineResult = null; 268 List defaultEngineResult = new LinkedList (); 269 270 IFilterRule filterRule = filter.getFilterRule(); 271 272 IFilterRule notDefaultEngine = new FilterRule(); 273 IFilterRule defaultEngine = new FilterRule(); 274 275 divideFilterRule(filterRule, notDefaultEngine, defaultEngine); 276 277 if (defaultEngine.count() > 0) { 278 try { 279 if (uids != null) { 280 defaultEngineResult = getNonDefaultEngine().queryEngine( 281 defaultEngine, uids); 282 } else { 283 defaultEngineResult = getNonDefaultEngine().queryEngine( 284 defaultEngine); 285 } 286 } catch (Exception e) { 287 e.printStackTrace(); 288 LOG.warning("NonDefaultSearch engine "+ nonDefaultEngine.toString()+"reported an error: falling back to default search:\n"+e.getMessage()); 289 defaultEngine = new FilterRule(); 290 notDefaultEngine = filter.getFilterRule(); 291 } 292 } 293 294 if (notDefaultEngine.count() == 0) { 295 notDefaultEngineResult = defaultEngineResult; 296 } else { 297 if (filterRule.getConditionInt() == FilterRule.MATCH_ALL) { 299 if (defaultEngine.count() > 0) { 300 notDefaultEngineResult = processCriteria(notDefaultEngine, 301 defaultEngineResult); 302 } else { 303 if (uids != null) { 304 notDefaultEngineResult = processCriteria( 305 notDefaultEngine, Arrays.asList(uids)); 306 } else { 307 notDefaultEngineResult = processCriteria( 308 notDefaultEngine, Arrays.asList(folder 309 .getUids())); 310 } 311 } 312 } 313 else { 315 if (uids != null) { 316 List uidList = new LinkedList (Arrays.asList(uids)); 317 ListTools.substract(uidList, defaultEngineResult); 318 319 notDefaultEngineResult = processCriteria(notDefaultEngine, 320 uidList); 321 322 notDefaultEngineResult.addAll(defaultEngineResult); 323 } else { 324 notDefaultEngineResult = processCriteria(notDefaultEngine, 325 Arrays.asList(folder.getUids())); 326 } 327 } 328 } 329 330 335 return notDefaultEngineResult.toArray(); 336 } 337 338 342 public Object [] searchMessages(IFilter filter) throws Exception { 343 if (getObservable() != null) { 344 getObservable().setMessage( 345 MailResourceLoader.getString("statusbar", "message", 346 "search")); 347 } 348 349 Object [] result = searchMessages(filter, null); 351 352 if (getObservable() != null) { 353 getObservable().clearMessageWithDelay(); 355 } 356 357 return result; 358 } 359 360 364 protected List queryEngine(IFilterRule filter, Object [] uids) 365 throws Exception { 366 return processCriteria(filter, Arrays.asList(uids)); 367 } 368 369 373 protected List queryEngine(IFilterRule filter) throws Exception { 374 Object [] uids = folder.getUids(); 375 376 return processCriteria(filter, Arrays.asList(uids)); 377 } 378 379 382 public QueryEngine getNonDefaultEngine() { 383 return nonDefaultEngine; 384 } 385 386 389 public void setNonDefaultEngine(QueryEngine engine) { 390 nonDefaultEngine = engine; 391 } 392 393 public void sync() throws Exception { 394 getNonDefaultEngine().sync(); 395 } 396 397 public void save() { 398 getNonDefaultEngine().save(); 399 } 400 } 401 | Popular Tags |