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 17 package com.android.ahat; 18 19 import com.google.common.html.HtmlEscapers; 20 import java.net.URI; 21 import java.net.URISyntaxException; 22 23 /** 24 * A class representing a small string of document content consisting of text, 25 * links, images, etc. 26 */ 27 class DocString { 28 private StringBuilder mStringBuilder; 29 30 public DocString() { 31 mStringBuilder = new StringBuilder(); 32 } 33 34 /** 35 * Construct a new DocString, initialized with the given text. 36 */ 37 public static DocString text(String str) { 38 DocString doc = new DocString(); 39 return doc.append(str); 40 } 41 42 /** 43 * Construct a new DocString, initialized with the given formatted text. 44 */ 45 public static DocString format(String format, Object... args) { 46 DocString doc = new DocString(); 47 return doc.appendFormat(format, args); 48 } 49 50 /** 51 * Construct a new DocString, initialized with the given link. 52 */ 53 public static DocString link(URI uri, DocString content) { 54 DocString doc = new DocString(); 55 return doc.appendLink(uri, content); 56 } 57 58 /** 59 * Construct a new DocString initialized with the given image. 60 */ 61 public static DocString image(URI uri, String alt) { 62 return (new DocString()).appendImage(uri, alt); 63 } 64 65 /** 66 * Append literal text to the given doc string. 67 * Returns this object. 68 */ 69 public DocString append(String text) { 70 mStringBuilder.append(HtmlEscapers.htmlEscaper().escape(text)); 71 return this; 72 } 73 74 /** 75 * Append formatted text to the given doc string. 76 * Returns this object. 77 */ 78 public DocString appendFormat(String format, Object... args) { 79 append(String.format(format, args)); 80 return this; 81 } 82 83 public DocString append(DocString str) { 84 mStringBuilder.append(str.html()); 85 return this; 86 } 87 88 /** 89 * Adorn the given string to indicate it represents something added relative 90 * to a baseline. 91 */ 92 public static DocString added(DocString str) { 93 DocString string = new DocString(); 94 string.mStringBuilder.append("<span class=\"added\">"); 95 string.mStringBuilder.append(str.html()); 96 string.mStringBuilder.append("</span>"); 97 return string; 98 } 99 100 /** 101 * Adorn the given string to indicate it represents something added relative 102 * to a baseline. 103 */ 104 public static DocString added(String str) { 105 return added(text(str)); 106 } 107 108 /** 109 * Adorn the given string to indicate it represents something removed relative 110 * to a baseline. 111 */ 112 public static DocString removed(DocString str) { 113 DocString string = new DocString(); 114 string.mStringBuilder.append("<span class=\"removed\">"); 115 string.mStringBuilder.append(str.html()); 116 string.mStringBuilder.append("</span>"); 117 return string; 118 } 119 120 /** 121 * Adorn the given string to indicate it represents something removed relative 122 * to a baseline. 123 */ 124 public static DocString removed(String str) { 125 return removed(text(str)); 126 } 127 128 /** 129 * Standard formatted DocString for describing a change in size relative to 130 * a baseline. 131 * @param noCurrent - whether no current object exists. 132 * @param noBaseline - whether no basline object exists. 133 * @param current - the size of the current object. 134 * @param baseline - the size of the baseline object. 135 */ 136 public static DocString delta(boolean noCurrent, boolean noBaseline, 137 long current, long baseline) { 138 DocString doc = new DocString(); 139 return doc.appendDelta(noCurrent, noBaseline, current, baseline); 140 } 141 142 /** 143 * Standard formatted DocString for describing a change in size relative to 144 * a baseline. 145 */ 146 public DocString appendDelta(boolean noCurrent, boolean noBaseline, 147 long current, long baseline) { 148 if (noCurrent) { 149 append(removed(format("%+,14d", 0 - baseline))); 150 } else if (noBaseline) { 151 append(added("new")); 152 } else if (current > baseline) { 153 append(added(format("%+,14d", current - baseline))); 154 } else if (current < baseline) { 155 append(removed(format("%+,14d", current - baseline))); 156 } 157 return this; 158 } 159 160 public DocString appendLink(URI uri, DocString content) { 161 mStringBuilder.append("<a href=\""); 162 mStringBuilder.append(uri.toASCIIString()); 163 mStringBuilder.append("\">"); 164 mStringBuilder.append(content.html()); 165 mStringBuilder.append("</a>"); 166 return this; 167 } 168 169 public DocString appendImage(URI uri, String alt) { 170 mStringBuilder.append("<img alt=\""); 171 mStringBuilder.append(HtmlEscapers.htmlEscaper().escape(alt)); 172 mStringBuilder.append("\" src=\""); 173 mStringBuilder.append(uri.toASCIIString()); 174 mStringBuilder.append("\" />"); 175 return this; 176 } 177 178 public DocString appendThumbnail(URI uri, String alt) { 179 mStringBuilder.append("<img height=\"16\" alt=\""); 180 mStringBuilder.append(HtmlEscapers.htmlEscaper().escape(alt)); 181 mStringBuilder.append("\" src=\""); 182 mStringBuilder.append(uri.toASCIIString()); 183 mStringBuilder.append("\" />"); 184 return this; 185 } 186 187 /** 188 * Convenience function for constructing a URI from a string with a uri 189 * known to be valid. 190 */ 191 public static URI uri(String uriString) { 192 try { 193 return new URI(uriString); 194 } catch (URISyntaxException e) { 195 throw new IllegalStateException("Known good uri has syntax error: " + uriString, e); 196 } 197 } 198 199 /** 200 * Convenience function for constructing a URI from a formatted string with 201 * a uri known to be valid. 202 */ 203 public static URI formattedUri(String format, Object... args) { 204 return uri(String.format(format, args)); 205 } 206 207 /** 208 * Render the DocString as html. 209 */ 210 public String html() { 211 return mStringBuilder.toString(); 212 } 213 } 214