package org.sothis.mvc; import java.text.ParsePosition; import java.util.Date; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.TimeZone; import org.sothis.core.util.ThreadSafeDateFormat; public abstract class Headers implements Iterable<Map.Entry<String, String[]>> { protected static final ThreadSafeDateFormat FORMAT1 = new ThreadSafeDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH, TimeZone.getTimeZone("GMT")); protected static final ThreadSafeDateFormat FORMAT2 = new ThreadSafeDateFormat("E, dd-MMM-yy HH:mm:ss z", Locale.ENGLISH, TimeZone.getTimeZone("GMT")); protected static final ThreadSafeDateFormat FORMAT3 = new ThreadSafeDateFormat("E MMM d HH:mm:ss yyyy", Locale.ENGLISH, TimeZone.getTimeZone("GMT")); public abstract Iterator<String> names(); public abstract String[] getStrings(String name); public abstract void addString(String name, String value); public abstract void setString(String name, String value); public abstract void remove(String name); public abstract boolean contains(String name); public Iterator<Entry<String, String[]>> iterator() { return new HeaderIterator(names()); } public void setStrings(String name, String[] value) { remove(name); for (String v : value) { addString(name, v); } } public void addDate(String name, Date date) { addString(name, FORMAT1.format(date)); } public void setDate(String name, Date date) { setString(name, FORMAT1.format(date)); } public void addInteger(String name, Integer value) { addString(name, value.toString()); } public void setInteger(String name, Integer value) { setString(name, value.toString()); } public String getString(String name) { String[] values = getStrings(name); return (null == values || values.length == 0) ? null : values[0]; } public String getString(String name, String defaultValue) { String ret = getString(name); return null == ret ? defaultValue : ret; } public Integer getInteger(String name) { String value = getString(name); return null == value ? null : Integer.parseInt(value); } public Integer getInteger(String name, Integer defaultValue) { String value = getString(name); return null == value ? defaultValue : Integer.parseInt(value); } public Integer[] getIntegers(String name) { String[] values = getStrings(name); Integer[] integers; if (values.length > 0) { integers = new Integer[values.length]; for (int i = 0; i < values.length; i++) { integers[i] = Integer.parseInt(values[i]); } } else { integers = new Integer[0]; } return integers; } public Date getDate(String name) { Date[] values = getDates(name); return (null == values || values.length == 0) ? null : values[0]; } public Date getDate(String name, Date defaultValue) { Date value = getDate(name); return null == value ? defaultValue : value; } public Date[] getDates(String name) { String[] values = getStrings(name); Date[] dates; if (values.length > 0) { dates = new Date[values.length]; ParsePosition pos = new ParsePosition(0); for (int i = 0; i < values.length; i++) { dates[i] = FORMAT1.parse(values[i], pos); if (dates[i] == null) { dates[i] = FORMAT2.parse(values[i], pos); if (dates[i] == null) { dates[i] = FORMAT3.parse(values[i], pos); } } } } else { dates = new Date[0]; } return dates; } private class HeaderIterator implements Iterator<Entry<String, String[]>> { private final Iterator<String> headerNames; public HeaderIterator(Iterator<String> headerNames) { super(); this.headerNames = headerNames; } @Override public boolean hasNext() { return headerNames.hasNext(); } @Override public Entry<String, String[]> next() { String name = headerNames.next(); return new HeaderEntry(name); } @Override public void remove() { headerNames.remove(); } } private class HeaderEntry implements Entry<String, String[]> { private final String name; private String[] value; public HeaderEntry(String name) { super(); this.name = name; } @Override public String getKey() { return name; } @Override public String[] getValue() { if (null == value) { value = getStrings(name); } return value; } @Override public String[] setValue(String[] value) { String[] old = this.value; setStrings(name, value); this.value = value; return old; } } }