1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.emailcommon.internet; 18 19 import com.android.emailcommon.mail.MessagingException; 20 21 import java.io.BufferedWriter; 22 import java.io.IOException; 23 import java.io.OutputStream; 24 import java.io.OutputStreamWriter; 25 import java.util.ArrayList; 26 27 public class MimeHeader { 28 /** 29 * Application specific header that contains Store specific information about an attachment. 30 * In IMAP this contains the IMAP BODYSTRUCTURE part id so that the ImapStore can later 31 * retrieve the attachment at will from the server. 32 * The info is recorded from this header on LocalStore.appendMessage and is put back 33 * into the MIME data by LocalStore.fetch. 34 */ 35 public static final String HEADER_ANDROID_ATTACHMENT_STORE_DATA = "X-Android-Attachment-StoreData"; 36 37 public static final String HEADER_CONTENT_TYPE = "Content-Type"; 38 public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding"; 39 public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; 40 public static final String HEADER_CONTENT_ID = "Content-ID"; 41 42 /** 43 * Fields that should be omitted when writing the header using writeTo() 44 */ 45 private static final String[] WRITE_OMIT_FIELDS = { 46 // HEADER_ANDROID_ATTACHMENT_DOWNLOADED, 47 // HEADER_ANDROID_ATTACHMENT_ID, 48 HEADER_ANDROID_ATTACHMENT_STORE_DATA 49 }; 50 51 protected final ArrayList<Field> mFields = new ArrayList<Field>(); 52 clear()53 public void clear() { 54 mFields.clear(); 55 } 56 getFirstHeader(String name)57 public String getFirstHeader(String name) throws MessagingException { 58 String[] header = getHeader(name); 59 if (header == null) { 60 return null; 61 } 62 return header[0]; 63 } 64 addHeader(String name, String value)65 public void addHeader(String name, String value) throws MessagingException { 66 mFields.add(new Field(name, value)); 67 } 68 setHeader(String name, String value)69 public void setHeader(String name, String value) throws MessagingException { 70 if (name == null || value == null) { 71 return; 72 } 73 removeHeader(name); 74 addHeader(name, value); 75 } 76 getHeader(String name)77 public String[] getHeader(String name) throws MessagingException { 78 ArrayList<String> values = new ArrayList<String>(); 79 for (Field field : mFields) { 80 if (field.name.equalsIgnoreCase(name)) { 81 values.add(field.value); 82 } 83 } 84 if (values.size() == 0) { 85 return null; 86 } 87 return values.toArray(new String[] {}); 88 } 89 removeHeader(String name)90 public void removeHeader(String name) throws MessagingException { 91 ArrayList<Field> removeFields = new ArrayList<Field>(); 92 for (Field field : mFields) { 93 if (field.name.equalsIgnoreCase(name)) { 94 removeFields.add(field); 95 } 96 } 97 mFields.removeAll(removeFields); 98 } 99 100 /** 101 * Write header into String 102 * 103 * @return CR-NL separated header string except the headers in writeOmitFields 104 * null if header is empty 105 */ writeToString()106 public String writeToString() { 107 if (mFields.size() == 0) { 108 return null; 109 } 110 StringBuilder builder = new StringBuilder(); 111 for (Field field : mFields) { 112 if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) { 113 builder.append(field.name + ": " + field.value + "\r\n"); 114 } 115 } 116 return builder.toString(); 117 } 118 writeTo(OutputStream out)119 public void writeTo(OutputStream out) throws IOException, MessagingException { 120 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024); 121 for (Field field : mFields) { 122 if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) { 123 writer.write(field.name + ": " + field.value + "\r\n"); 124 } 125 } 126 writer.flush(); 127 } 128 129 private static class Field { 130 final String name; 131 final String value; 132 Field(String name, String value)133 public Field(String name, String value) { 134 this.name = name; 135 this.value = value; 136 } 137 138 @Override toString()139 public String toString() { 140 return name + "=" + value; 141 } 142 } 143 144 @Override toString()145 public String toString() { 146 return (mFields == null) ? null : mFields.toString(); 147 } 148 arrayContains(Object[] a, Object o)149 public final static boolean arrayContains(Object[] a, Object o) { 150 int index = arrayIndex(a, o); 151 return (index >= 0); 152 } 153 arrayIndex(Object[] a, Object o)154 public final static int arrayIndex(Object[] a, Object o) { 155 for (int i = 0, count = a.length; i < count; i++) { 156 if (a[i].equals(o)) { 157 return i; 158 } 159 } 160 return -1; 161 } 162 } 163