15c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein/** 25c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Copyright (C) 2013 Google Inc. 35c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Licensed to The Android Open Source Project. 45c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * 55c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 65c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * you may not use this file except in compliance with the License. 75c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * You may obtain a copy of the License at 85c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * 95c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 105c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * 115c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software 125c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 135c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * See the License for the specific language governing permissions and 155c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * limitations under the License. 165c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein */ 175c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 185c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinpackage com.android.mail.ui; 195c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 205c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinimport android.content.Context; 215c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinimport android.content.res.Resources; 225c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 235c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinimport java.io.IOException; 245c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinimport java.io.InputStreamReader; 255c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinimport java.util.Formatter; 265c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 275c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein/** 285c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Abstract class to support common functionality for both 295c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * {@link com.android.mail.ui.HtmlConversationTemplates} and 305c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * {@link com.android.mail.print.HtmlPrintTemplates}. 315c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * 325c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Renders data into very simple string-substitution HTML templates. 335c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * 345c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Templates should be UTF-8 encoded HTML with '%s' placeholders to be substituted upon render. 355c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein * Plain-jane string substitution with '%s' is slightly faster than typed substitution. 365c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein */ 375c1692a5faeab220881a17a3427a8986ef874403Andrew Sappersteinpublic abstract class AbstractHtmlTemplates { 385c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein // TODO: refine. too expensive to iterate over cursor and pre-calculate total. so either 395c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein // estimate it, or defer assembly until the end when size is known (deferring increases 405c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein // working set size vs. estimation but is exact). 415c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein private static final int BUFFER_SIZE_CHARS = 64 * 1024; 425c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 435c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected Context mContext; 445c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected Formatter mFormatter; 455c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected StringBuilder mBuilder; 465c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected boolean mInProgress = false; 475c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 485c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein public AbstractHtmlTemplates(Context context) { 495c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mContext = context; 505c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 515c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 525c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein public String emit() { 535c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein final String out = mFormatter.toString(); 545c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein // release the builder memory ASAP 555c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mFormatter = null; 565c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mBuilder = null; 575c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein return out; 585c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 595c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 605c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein public void reset() { 615c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mBuilder = new StringBuilder(BUFFER_SIZE_CHARS); 625c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mFormatter = new Formatter(mBuilder, null /* no localization */); 635c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 645c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 655c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected String readTemplate(int id) throws Resources.NotFoundException { 665c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein final StringBuilder out = new StringBuilder(); 675c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein InputStreamReader in = null; 685c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein try { 695c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein try { 705c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein in = new InputStreamReader( 715c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mContext.getResources().openRawResource(id), "UTF-8"); 725c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein final char[] buf = new char[4096]; 735c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein int chars; 745c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 755c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein while ((chars=in.read(buf)) > 0) { 765c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein out.append(buf, 0, chars); 775c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 785c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 795c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein return out.toString(); 805c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 815c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } finally { 825c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein if (in != null) { 835c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein in.close(); 845c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 855c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 865c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } catch (IOException e) { 875c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein throw new Resources.NotFoundException("Unable to open template id=" 885c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein + Integer.toHexString(id) + " exception=" + e.getMessage()); 895c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 905c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 915c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein 925c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein protected void append(String template, Object... args) { 935c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein mFormatter.format(template, args); 945c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein } 955c1692a5faeab220881a17a3427a8986ef874403Andrew Sapperstein} 96