1 package SnowMailClient.utils; 2 3 import java.util.regex.Matcher ; 4 import java.util.regex.Pattern ; 5 import SnowMailClient.crypto.Utilities; 6 import snow.utils.storage.*; 7 import SnowMailClient.model.Header; 8 import SnowMailClient.model.Address; 9 import SnowMailClient.model.HeaderEntry; 10 import java.util.*; 11 import java.text.*; 12 import java.io.*; 13 import java.text.SimpleDateFormat ; 14 15 16 public final class MailMessageUtils 17 { 18 private static final SimpleDateFormat dateFormat = new SimpleDateFormat ("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH); 19 20 private static final SimpleDateFormat pdateFormat = new SimpleDateFormat ("d MMM yyyy HH:mm:ss Z", Locale.ENGLISH); 22 private static final SimpleDateFormat pbadButFrequentDateFormat = new SimpleDateFormat ("d MMM yyyy HH:mm:ss Z", Locale.ENGLISH); 23 private static final SimpleDateFormat pbadButFrequentDateFormat2 = new SimpleDateFormat ("d MMM yyyy HH:mm:ss", Locale.ENGLISH); 24 private static final SimpleDateFormat pbadButFrequentDateFormat3 = new SimpleDateFormat ("d MMM yyyy HH:mm Z", Locale.ENGLISH); 25 private static final SimpleDateFormat pbadButFrequentDateFormat4 = new SimpleDateFormat ("MM.dd.yyyy HH:mm:ss", Locale.ENGLISH); 26 27 41 public final static String msgDateFormat(Date date) 42 { 43 return dateFormat.format(date); 44 } 45 46 49 public final static Date parseDateFromString(String s) throws Exception 50 { 51 int posComa = s.indexOf(","); 53 if(posComa>=0) 54 { 55 s = s.substring(posComa+1).trim(); 56 } 57 58 try 59 { 60 return pdateFormat.parse(s); 61 } 62 catch(Exception e1) 63 { 64 try 65 { 66 return pbadButFrequentDateFormat.parse(s); 67 } 68 catch(Exception e2) { } 69 70 try 71 { 72 return pbadButFrequentDateFormat2.parse(s); 73 } 74 catch(Exception e2) { } 75 76 try 77 { 78 return pbadButFrequentDateFormat3.parse(s); 79 } 80 catch(Exception e2) { } 81 82 try 83 { 84 return pbadButFrequentDateFormat4.parse(s); 85 } 86 catch(Exception e2) { } 87 88 try 89 { 90 return pdateFormat.parse(s+"00"); 91 } 92 catch(Exception e3) { } 93 94 95 96 if(s.equalsIgnoreCase("%CURRENT_DATE_TIME")) return new Date(); 97 98 if(s.endsWith(":00")) 99 { 100 return parseDateFromString(s.substring(0,s.length()-3)); 102 } 103 } 104 105 throw new Exception ("Cannot parse date from "+s); 106 } 107 108 113 public static String createMessageID(Address address) 114 { 115 int rand = (int)(Math.random()*1e8); 116 return "<"+rand+"."+address.getMailAddress()+">"; 117 118 120 123 } 124 125 public static final DecimalFormat formatSize0 = new DecimalFormat("0.0"); 126 public static final DecimalFormat formatSize = new DecimalFormat("0"); 127 128 public static String formatSize(long size) 129 { 130 if(size>3000000) return ""+formatSize.format(size/1000000.0) +" MB"; 131 if(size>1000000) return ""+formatSize0.format(size/1000000.0) +" MB"; 132 if(size>3000) return ""+formatSize.format(size/1000.0) +" kB"; 133 if(size>1000) return ""+formatSize0.format(size/1000.0) +" kB"; 134 return ""+(size) +" B"; 135 } 136 137 138 141 public static String grabAddress(String addddressssssss) 142 { 143 String strToCmd = addddressssssss.trim(); 145 146 int intFoundStart = strToCmd.indexOf('<'); 149 if (intFoundStart != -1) 150 { 151 int intFoundEnd = strToCmd.indexOf('>'); 153 if (intFoundEnd != -1) 154 { 155 return strToCmd.substring(intFoundStart+1,intFoundEnd).trim(); 156 } 157 else 158 { 159 return strToCmd.substring(intFoundStart+1,strToCmd.length()).trim(); 160 } 161 } 162 else 163 { 164 return strToCmd; 166 } 167 } 168 169 170 181 public static String decodeCharsetCodedArgument_(String arg) 182 { 183 int beginOffest = 15; 184 int begCode =0; 185 String charset = "iso-8859-1"; 187 Pattern pat = Pattern.compile("=\\?([^?]*)\\?"); 188 Matcher m = pat.matcher(arg); 189 if(m.find()) 190 { 191 charset = m.group(1); 192 beginOffest = m.end(1)+3; 193 195 } 196 else 197 { 198 return arg; 199 } 200 201 if(arg.length()<beginOffest+1) 202 { 203 return arg; } 205 206 int posEnd = arg.indexOf("?=", beginOffest+3); 208 if(posEnd==-1) return arg; if(beginOffest>=arg.length()) return arg; 211 String coded = arg.substring(beginOffest, posEnd); 213 214 215 char chat = arg.charAt(beginOffest-2); 216 if(chat=='q' || chat=='Q') 217 { 218 coded = decodeQuotedPrintable(coded, charset); 219 } 220 else if(chat=='b' || chat=='B') 221 { 222 try 223 { 224 coded = new String (Utilities.decodeBase64(coded), charset); 225 } 226 catch(Exception e) 227 { 228 e.printStackTrace(); 229 return arg; 230 } 231 } 232 else 233 { 234 return arg; } 236 237 return arg.substring(0,begCode) + coded + arg.substring(posEnd+2); 238 } 239 240 241 243 public static String decodeQuotedPrintable(String in, String charset) 244 { 245 StringBuffer sb = new StringBuffer (in); 246 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 247 248 for(int i=0; i<sb.length(); i++) 249 { 250 char ci = sb.charAt(i); 251 252 if(ci == '\r') continue; 254 255 256 if(ci != '=') 257 { 258 bos.write((byte) ci); 259 } 260 else 261 { 262 int end = i+3; 263 if(end>sb.length()) end = sb.length(); 264 String code = sb.substring(i+1, end); 265 if(code.equals("\r\n")) { 267 i+=2; 268 } 269 else if(code.startsWith("\n")) { 271 i+=1; 272 } 273 else 274 { 275 try 277 { 278 bos.write((byte) Integer.parseInt(code, 16)); 279 i+=2; 280 } 281 catch(NumberFormatException e) 282 { 283 } 286 } 287 } 288 } 289 290 try 291 { 292 return new String (bos.toByteArray(), charset); 293 } 294 catch(Exception e) 295 { 296 return in; 297 } 298 } 299 300 301 305 public static boolean is7Bits(byte[] chars) 306 { 307 if(chars==null) return true; 308 309 for(byte c: chars) 310 { 311 if(c>127) return false; 312 if(c<0) return false; 313 } 314 return true; 315 } 316 317 318 public static int byteCharToInt(byte b) 319 { 320 if(b<0) return 256+b; 321 return b; 322 } 323 324 327 public static byte[] encodeMessageQuotedPrintable(byte[] bytes) 328 { 329 StringBuffer reply = new StringBuffer (); 330 int lineLength = 0; 331 for(int i=0; i<bytes.length; i++) 332 { 333 int ci = byteCharToInt(bytes[i]); 334 335 if(ci==61) { 337 lineLength += 3; 338 reply.append("="+getHexa(61)); 339 } 340 else if(ci>=32 && ci<=126) 341 { 342 lineLength++; 343 if(lineLength>76) 344 { 345 reply.append("=\r\n"); lineLength = 0; 347 } 348 349 reply.append((char) ci); 350 351 } 352 else if(ci==10) { 354 lineLength += 3; 355 if(lineLength>76) 356 { 357 reply.append("=\r\n"); 358 lineLength = 0; 359 } 360 reply.append("=0A"); 361 362 } 363 else 364 { 365 lineLength += 3; 366 if(lineLength>76) 367 { 368 reply.append("=\r\n"); 369 lineLength = 0; 370 } 371 reply.append("="); 372 reply.append(getHexa(ci)); 373 } 374 375 } 377 try 378 { 379 return reply.toString().getBytes("us-ascii"); 380 } 381 catch(Exception e) 382 { 383 return reply.toString().getBytes(); 384 } 385 } 386 387 388 393 public static String encodeLine_QuotedPrintable(String text) 394 { 395 boolean needed = false; 396 String charset = CharsetUtils.getMinimalEncodingCharset(text); 397 398 StringBuffer reply = new StringBuffer (); 399 byte[] textBytes = null; 400 try 401 { 402 textBytes = text.getBytes(charset); } 404 catch(Exception e) 405 { 406 textBytes = text.getBytes(); } 408 409 for(byte b: textBytes) 410 { 411 int ci = byteCharToInt(b); 412 if (ci==61) { 415 needed = true; 416 reply.append("="); 417 reply.append(getHexa(61)); 418 } 419 else if(ci>=32 && ci<128) 420 { 421 reply.append((char)b); } 423 else 424 { 425 needed = true; 426 reply.append("="); 427 reply.append(getHexa(ci)); 428 } 429 } 430 431 if(needed) 432 { 433 return "=?"+charset+"?q?"+ reply.toString() +"?="; 435 } 436 else 437 { 438 return reply.toString(); 439 } 440 } 441 442 443 public static final String base16 = "0123456789ABCDEF"; 444 public static String getHexa(int val) 445 { 446 int first = val/16; 447 int second = val-first*16; 448 return ""+base16.charAt(first)+""+base16.charAt(second); 449 } 450 451 453 public static String decodeCharsetCodedArgumentFully(String in) 454 { 455 int level = 0; 456 String prec = in; 457 while(level<20) 458 { 459 String dec = decodeCharsetCodedArgument_(prec); 460 if(dec.equals(prec)) return dec; 461 prec = dec; 462 level++; 463 } 464 return prec; 465 } 466 467 public static void main(String [] aaa) 468 { 469 System.out.println("reply="+decodeCharsetCodedArgument_("=?iso-8859-1?q?hello=20I=20am?=AAABBB")); 470 System.out.println("reply="+decodeCharsetCodedArgument_("=?iso-8859-1?B?c3VucmlzZSBlLU5ld3NsZXR0ZXI=?=UU")); 471 System.out.println("reply="+decodeCharsetCodedArgument_("=?utf-8?B?TWljcm9zb2Z0IE91dGxvb2sgVGVzdCBNZXNzYWdl?=")); 472 System.out.println("reply="+decodeCharsetCodedArgument_("=?iso-8859-15?Q?Lu:__Re:_Etablissement_d=E9finitif_de_JMA_en_Tha=EFlande?=")); 473 System.out.println("reply="+decodeCharsetCodedArgument_("=?iso-2022-jp?B?MjCWnI+AlPWCtYLcgrWCvYFCjaGT+oLIgueJvY6egsmIp4KmgtyCt4KpgUg=?=")); 474 475 476 String enc = encodeLine_QuotedPrintable("éééé"); 477 System.out.println(""+enc); 478 System.out.println(decodeCharsetCodedArgument_(enc)); 479 480 byte[] bytes = "\r\n".getBytes(); 481 for(byte b: bytes) 482 { 483 int ib = byteCharToInt(b); 484 System.out.println(""+b+" "+ib); 485 } 486 487 byte[] b = encodeMessageQuotedPrintable("Hello\r\nComment =\n vas tú?".getBytes()); 488 System.out.println("ENC="+new String (b)); 489 System.out.println("DEC="+decodeQuotedPrintable(new String (b), "iso-8859-1")); 490 491 System.out.println(msgDateFormat(new Date())); 492 try 493 { 494 System.out.println(parseDateFromString("Tuesday, 17 Jan 2006 09:35:04 +01:00")); 495 System.out.println(parseDateFromString("Fr, 24 Jun 2005 03:55:07")); 496 } catch(Exception ex) {ex.printStackTrace();} 497 498 } 499 500 501 } | Popular Tags |