001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020package org.apache.james.mime4j.field; 021 022import java.text.ParseException; 023import java.text.SimpleDateFormat; 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.Date; 027import java.util.List; 028import java.util.Locale; 029import java.util.TimeZone; 030 031import org.apache.james.mime4j.codec.DecodeMonitor; 032import org.apache.james.mime4j.dom.FieldParser; 033import org.apache.james.mime4j.dom.field.DateTimeField; 034import org.apache.james.mime4j.stream.Field; 035 036/** 037 * Date-time field such as <code>Date</code> or <code>Resent-Date</code>. 038 */ 039public class DateTimeFieldLenientImpl extends AbstractField implements DateTimeField { 040 041 private static final String[] DEFAULT_DATE_FORMATS = { 042 "EEE, dd MMM yyyy HH:mm:ss ZZZZ", 043 "dd MMM yyyy HH:mm:ss ZZZZ"}; 044 045 private final List<String> datePatterns; 046 047 private boolean parsed = false; 048 private Date date; 049 050 DateTimeFieldLenientImpl(final Field rawField, 051 final Collection<String> dateParsers, final DecodeMonitor monitor) { 052 super(rawField, monitor); 053 this.datePatterns = new ArrayList<String>(); 054 if (dateParsers != null) { 055 this.datePatterns.addAll(dateParsers); 056 } else { 057 for (String pattern: DEFAULT_DATE_FORMATS) { 058 this.datePatterns.add(pattern); 059 } 060 } 061 } 062 063 public Date getDate() { 064 if (!parsed) { 065 parse(); 066 } 067 return date; 068 } 069 070 private void parse() { 071 parsed = true; 072 date = null; 073 String body = getBody(); 074 for (String datePattern: datePatterns) { 075 try { 076 SimpleDateFormat parser = new SimpleDateFormat(datePattern, Locale.US); 077 parser.setTimeZone(TimeZone.getTimeZone("GMT")); 078 parser.setLenient(true); 079 date = parser.parse(body); 080 break; 081 } catch (ParseException ignore) { 082 } 083 } 084 } 085 086 public static final FieldParser<DateTimeField> PARSER = new FieldParser<DateTimeField>() { 087 088 public DateTimeField parse(final Field rawField, final DecodeMonitor monitor) { 089 return new DateTimeFieldLenientImpl(rawField, null, monitor); 090 } 091 092 }; 093 094 public static FieldParser<DateTimeField> createParser(final Collection<String> dateParsers) { 095 096 return new FieldParser<DateTimeField>() { 097 098 public DateTimeField parse(final Field rawField, final DecodeMonitor monitor) { 099 return new DateTimeFieldLenientImpl(rawField, dateParsers, monitor); 100 } 101 102 }; 103 104 } 105 106}