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 public static final String HEADER_CONTENT_DURATION = "Content-Duration"; 40 41 /** Fields that should be omitted when writing the header using writeTo() */ 42 private static final String[] WRITE_OMIT_FIELDS = { 43 // HEADER_ANDROID_ATTACHMENT_DOWNLOADED, 44 // HEADER_ANDROID_ATTACHMENT_ID, 45 HEADER_ANDROID_ATTACHMENT_STORE_DATA 46 }; 47 48 protected final ArrayList<Field> fields = new ArrayList<Field>(); 49 clear()50 public void clear() { 51 fields.clear(); 52 } 53 getFirstHeader(String name)54 public String getFirstHeader(String name) throws MessagingException { 55 String[] header = getHeader(name); 56 if (header == null) { 57 return null; 58 } 59 return header[0]; 60 } 61 addHeader(String name, String value)62 public void addHeader(String name, String value) throws MessagingException { 63 fields.add(new Field(name, value)); 64 } 65 setHeader(String name, String value)66 public void setHeader(String name, String value) throws MessagingException { 67 if (name == null || value == null) { 68 return; 69 } 70 removeHeader(name); 71 addHeader(name, value); 72 } 73 getHeader(String name)74 public String[] getHeader(String name) throws MessagingException { 75 ArrayList<String> values = new ArrayList<String>(); 76 for (Field field : fields) { 77 if (field.name.equalsIgnoreCase(name)) { 78 values.add(field.value); 79 } 80 } 81 if (values.size() == 0) { 82 return null; 83 } 84 return values.toArray(new String[] {}); 85 } 86 removeHeader(String name)87 public void removeHeader(String name) throws MessagingException { 88 ArrayList<Field> removeFields = new ArrayList<Field>(); 89 for (Field field : fields) { 90 if (field.name.equalsIgnoreCase(name)) { 91 removeFields.add(field); 92 } 93 } 94 fields.removeAll(removeFields); 95 } 96 97 /** 98 * Write header into String 99 * 100 * @return CR-NL separated header string except the headers in writeOmitFields null if header is 101 * empty 102 */ writeToString()103 public String writeToString() { 104 if (fields.size() == 0) { 105 return null; 106 } 107 StringBuilder builder = new StringBuilder(); 108 for (Field field : fields) { 109 if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) { 110 builder.append(field.name + ": " + field.value + "\r\n"); 111 } 112 } 113 return builder.toString(); 114 } 115 writeTo(OutputStream out)116 public void writeTo(OutputStream out) throws IOException, MessagingException { 117 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024); 118 for (Field field : fields) { 119 if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) { 120 writer.write(field.name + ": " + field.value + "\r\n"); 121 } 122 } 123 writer.flush(); 124 } 125 126 private static class Field { 127 final String name; 128 final String value; 129 Field(String name, String value)130 public Field(String name, String value) { 131 this.name = name; 132 this.value = value; 133 } 134 135 @Override toString()136 public String toString() { 137 return name + "=" + value; 138 } 139 } 140 141 @Override toString()142 public String toString() { 143 return (fields == null) ? null : fields.toString(); 144 } 145 arrayContains(Object[] a, Object o)146 public static final boolean arrayContains(Object[] a, Object o) { 147 int index = arrayIndex(a, o); 148 return (index >= 0); 149 } 150 arrayIndex(Object[] a, Object o)151 public static final int arrayIndex(Object[] a, Object o) { 152 for (int i = 0, count = a.length; i < count; i++) { 153 if (a[i].equals(o)) { 154 return i; 155 } 156 } 157 return -1; 158 } 159 } 160