1 /** 2 * Copyright (C) 2013 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mail.ui; 19 20 import android.content.Context; 21 import android.content.res.Resources; 22 23 import java.io.IOException; 24 import java.io.InputStreamReader; 25 import java.util.Formatter; 26 27 /** 28 * Abstract class to support common functionality for both 29 * {@link com.android.mail.ui.HtmlConversationTemplates} and 30 * {@link com.android.mail.print.HtmlPrintTemplates}. 31 * 32 * Renders data into very simple string-substitution HTML templates. 33 * 34 * Templates should be UTF-8 encoded HTML with '%s' placeholders to be substituted upon render. 35 * Plain-jane string substitution with '%s' is slightly faster than typed substitution. 36 */ 37 public abstract class AbstractHtmlTemplates { 38 // TODO: refine. too expensive to iterate over cursor and pre-calculate total. so either 39 // estimate it, or defer assembly until the end when size is known (deferring increases 40 // working set size vs. estimation but is exact). 41 private static final int BUFFER_SIZE_CHARS = 64 * 1024; 42 43 protected Context mContext; 44 protected Formatter mFormatter; 45 protected StringBuilder mBuilder; 46 protected boolean mInProgress = false; 47 AbstractHtmlTemplates(Context context)48 public AbstractHtmlTemplates(Context context) { 49 mContext = context; 50 } 51 emit()52 public String emit() { 53 final String out = mFormatter.toString(); 54 // release the builder memory ASAP 55 mFormatter = null; 56 mBuilder = null; 57 return out; 58 } 59 reset()60 public void reset() { 61 mBuilder = new StringBuilder(BUFFER_SIZE_CHARS); 62 mFormatter = new Formatter(mBuilder, null /* no localization */); 63 } 64 readTemplate(int id)65 protected String readTemplate(int id) throws Resources.NotFoundException { 66 final StringBuilder out = new StringBuilder(); 67 InputStreamReader in = null; 68 try { 69 try { 70 in = new InputStreamReader( 71 mContext.getResources().openRawResource(id), "UTF-8"); 72 final char[] buf = new char[4096]; 73 int chars; 74 75 while ((chars=in.read(buf)) > 0) { 76 out.append(buf, 0, chars); 77 } 78 79 return out.toString(); 80 81 } finally { 82 if (in != null) { 83 in.close(); 84 } 85 } 86 } catch (IOException e) { 87 throw new Resources.NotFoundException("Unable to open template id=" 88 + Integer.toHexString(id) + " exception=" + e.getMessage()); 89 } 90 } 91 append(String template, Object... args)92 protected void append(String template, Object... args) { 93 mFormatter.format(template, args); 94 } 95 } 96