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