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