blob: c578bad08be45330fa2ffbca24f8d824c0fa22f9 [file] [log] [blame]
Andrew Sapperstein345c43e2013-05-31 16:23:18 -07001/*
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
17package com.android.emailcommon.internet;
18
19import com.android.emailcommon.mail.MessagingException;
20
21import java.io.BufferedWriter;
22import java.io.IOException;
23import java.io.OutputStream;
24import java.io.OutputStreamWriter;
25import java.util.ArrayList;
26
27public 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.
Tony Mantler48360702014-03-24 13:56:53 -070032 * The info is recorded from this header on LocalStore.appendMessage and is put back
Andrew Sapperstein345c43e2013-05-31 16:23:18 -070033 * into the MIME data by LocalStore.fetch.
34 */
35 public static final String HEADER_ANDROID_ATTACHMENT_STORE_DATA = "X-Android-Attachment-StoreData";
Andrew Sapperstein345c43e2013-05-31 16:23:18 -070036
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
53 public void clear() {
54 mFields.clear();
55 }
56
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
65 public void addHeader(String name, String value) throws MessagingException {
66 mFields.add(new Field(name, value));
67 }
68
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
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
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 */
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
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
133 public Field(String name, String value) {
134 this.name = name;
135 this.value = value;
136 }
137
138 @Override
139 public String toString() {
140 return name + "=" + value;
141 }
142 }
143
144 @Override
145 public String toString() {
146 return (mFields == null) ? null : mFields.toString();
147 }
148
149 public final static boolean arrayContains(Object[] a, Object o) {
150 int index = arrayIndex(a, o);
151 return (index >= 0);
152 }
153
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}