1 21 22 package org.armedbear.j.mail; 23 24 import java.util.Stack ; 25 import org.armedbear.j.Debug; 26 import org.armedbear.j.FastStringReader; 27 import org.armedbear.j.Log; 28 29 public abstract class MailboxFilter 30 { 31 public static MailboxFilter getMailboxFilter(String input) 32 { 33 input = input.trim(); 34 if (input.indexOf('~') < 0) 35 return new GenericMailboxFilter(input); 36 FastStringReader reader = new FastStringReader(input); 37 try { 38 return parse(reader); 39 } 40 catch (Exception e) { 41 Log.error(e); 42 return null; 43 } 44 } 45 46 private static MailboxFilter parse(FastStringReader reader) throws Exception 47 { 48 Stack stack = new Stack (); 49 while (parseNextTerm(reader, stack)) 50 ; 51 Debug.assertTrue(stack.size() == 1); 52 return (MailboxFilter) stack.pop(); 53 } 54 55 private static boolean parseNextTerm(FastStringReader reader, Stack stack) 57 throws Exception 58 { 59 reader.skipWhitespace(); 60 char c = reader.readChar(); 61 switch (c) { 62 case '~': { 63 MailboxFilter filter = parseTilde(reader); 64 if (filter != null) { 65 if (stack.size() > 0) { 66 MailboxFilter existing = (MailboxFilter) stack.pop(); 67 if (existing instanceof AndTerm) { 68 ((AndTerm) existing).add(filter); 69 stack.push(existing); 70 } else 71 stack.push(new AndTerm(existing, filter)); 72 } else 73 stack.push(filter); 74 } 75 break; 76 } 77 case '!': { 78 MailboxFilter filter = parseNot(reader); 79 if (filter != null) { 80 if (stack.size() > 0) { 81 MailboxFilter existing = (MailboxFilter) stack.pop(); 82 if (existing instanceof AndTerm) { 83 ((AndTerm) existing).add(filter); 84 stack.push(existing); 85 } else 86 stack.push(new AndTerm(existing, filter)); 87 } else 88 stack.push(filter); 89 } 90 break; 91 } 92 case '(': { 93 MailboxFilter filter = parse(reader); 94 break; 95 } 96 case ')': 97 return false; 98 case '|': { 99 MailboxFilter filter = parseOr(reader); 100 if (filter != null) { 101 if (stack.size() > 0) { 102 MailboxFilter existing = (MailboxFilter) stack.pop(); 103 if (existing instanceof OrTerm) { 104 ((OrTerm) existing).add(filter); 105 stack.push(existing); 106 } else 107 stack.push(new OrTerm(existing, filter)); 108 } else 109 stack.push(filter); 110 } 111 break; 112 } 113 case '\0': 114 return false; default: 116 throw new Exception (); 117 } 118 return true; 119 } 120 121 private static MailboxFilter parseOr(FastStringReader reader) throws Exception 123 { 124 reader.skipWhitespace(); 125 MailboxFilter filter = null; 126 char c = reader.readChar(); 127 switch (c) { 128 case '~': 129 filter = parseTilde(reader); 130 break; 131 case '!': 132 filter = parseNot(reader); 133 break; 134 case '(': 135 filter = parse(reader); 136 break; 137 default: 138 Log.error("char = " + c); 139 throw new Exception (); 140 } 141 Debug.assertTrue(filter != null); 142 return filter; 143 } 144 145 private static NotTerm parseNot(FastStringReader reader) throws Exception 146 { 147 reader.skipWhitespace(); 148 MailboxFilter filter = null; 149 char c = reader.readChar(); 150 switch (c) { 151 case '~': 152 filter = parseTilde(reader); 153 break; 154 case '(': 155 filter = parse(reader); 156 break; 157 default: 158 throw new Exception (); 159 } 160 Debug.assertTrue(filter != null); 161 return new NotTerm(filter); 162 } 163 164 private static MailboxFilter parseTilde(FastStringReader reader) throws Exception 165 { 166 MailboxFilter filter = null; 167 char c = reader.readChar(); 168 switch (c) { 169 case 'C': 170 filter = new ToOrCcMailboxFilter(reader); 171 break; 172 case 'D': 173 filter = new DeletedMailboxFilter(); 174 break; 175 case 'F': 176 filter = new FlaggedMailboxFilter(); 177 break; 178 case 'N': 179 filter = new NewMailboxFilter(); 180 break; 181 case 'R': 182 filter = new ReadMailboxFilter(); 183 break; 184 case 'U': 185 filter = new UnreadMailboxFilter(); 186 break; 187 case 'T': 188 filter = new TaggedMailboxFilter(); 189 break; 190 case 'f': 191 filter = new FromMailboxFilter(reader); 192 break; 193 case 't': 194 filter = new ToMailboxFilter(reader); 195 break; 196 case 'd': 197 filter = DateSentMailboxFilter.getMailboxFilter(reader); 198 break; 199 default: 200 Log.error("parseTilde() returning null, remainder = |" + reader.remainder() + "|"); 201 throw new Exception (); 202 } 203 return filter; 204 } 205 206 public abstract boolean accept(MailboxEntry entry); 207 } 208 | Popular Tags |