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