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