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.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> mFields = new ArrayList<Field>();
     49 
     50   public void clear() {
     51     mFields.clear();
     52   }
     53 
     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 
     62   public void addHeader(String name, String value) throws MessagingException {
     63     mFields.add(new Field(name, value));
     64   }
     65 
     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 
     74   public String[] getHeader(String name) throws MessagingException {
     75     ArrayList<String> values = new ArrayList<String>();
     76     for (Field field : mFields) {
     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 
     87   public void removeHeader(String name) throws MessagingException {
     88     ArrayList<Field> removeFields = new ArrayList<Field>();
     89     for (Field field : mFields) {
     90       if (field.name.equalsIgnoreCase(name)) {
     91         removeFields.add(field);
     92       }
     93     }
     94     mFields.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    */
    103   public String writeToString() {
    104     if (mFields.size() == 0) {
    105       return null;
    106     }
    107     StringBuilder builder = new StringBuilder();
    108     for (Field field : mFields) {
    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 
    116   public void writeTo(OutputStream out) throws IOException, MessagingException {
    117     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
    118     for (Field field : mFields) {
    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 
    130     public Field(String name, String value) {
    131       this.name = name;
    132       this.value = value;
    133     }
    134 
    135     @Override
    136     public String toString() {
    137       return name + "=" + value;
    138     }
    139   }
    140 
    141   @Override
    142   public String toString() {
    143     return (mFields == null) ? null : mFields.toString();
    144   }
    145 
    146   public static final boolean arrayContains(Object[] a, Object o) {
    147     int index = arrayIndex(a, o);
    148     return (index >= 0);
    149   }
    150 
    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