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