1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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.ide.eclipse.adt.internal.editors.layout.gle2; 18 19 import com.android.ide.common.rendering.api.LayoutLog; 20 import com.android.ide.eclipse.adt.AdtPlugin; 21 22 import org.eclipse.core.runtime.IStatus; 23 24 import java.util.ArrayList; 25 import java.util.HashSet; 26 import java.util.List; 27 import java.util.Set; 28 29 /** 30 * A {@link LayoutLog} which records the problems it encounters and offers them as a 31 * single summary at the end 32 */ 33 class RenderLogger extends LayoutLog { 34 private final String mName; 35 private List<String> mFidelityWarnings; 36 private List<String> mWarnings; 37 private List<String> mErrors; 38 private boolean mHaveExceptions; 39 private List<String> mTags; 40 private static Set<String> sIgnoredFidelityWarnings; 41 42 /** Construct a logger for the given named layout */ 43 RenderLogger(String name) { 44 mName = name; 45 } 46 47 /** 48 * Are there any logged errors or warnings during the render? 49 * 50 * @return true if there were problems during the render 51 */ 52 public boolean hasProblems() { 53 return mFidelityWarnings != null || mErrors != null || mWarnings != null || 54 mHaveExceptions; 55 } 56 57 /** 58 * Returns a (possibly multi-line) description of all the problems 59 * 60 * @param includeFidelityWarnings if true, include fidelity warnings in the problem 61 * summary 62 * @return a string describing the rendering problems 63 */ 64 public String getProblems(boolean includeFidelityWarnings) { 65 StringBuilder sb = new StringBuilder(); 66 67 if (mErrors != null) { 68 for (String error : mErrors) { 69 sb.append(error).append('\n'); 70 } 71 } 72 73 if (mWarnings != null) { 74 for (String warning : mWarnings) { 75 sb.append(warning).append('\n'); 76 } 77 } 78 79 if (includeFidelityWarnings && mFidelityWarnings != null) { 80 sb.append("The graphics preview in the layout editor may not be accurate:\n"); 81 for (String warning : mFidelityWarnings) { 82 sb.append("* "); 83 sb.append(warning).append('\n'); 84 } 85 } 86 87 if (mHaveExceptions) { 88 sb.append("Exception details are logged in Window > Show View > Error Log"); 89 } 90 91 return sb.toString(); 92 } 93 94 /** 95 * Returns the fidelity warnings 96 * 97 * @return the fidelity warnings 98 */ 99 public List<String> getFidelityWarnings() { 100 return mFidelityWarnings; 101 } 102 103 // ---- extends LayoutLog ---- 104 105 @Override 106 public void error(String tag, String message, Object data) { 107 String description = describe(message); 108 109 AdtPlugin.log(IStatus.ERROR, "%1$s: %2$s", mName, description); 110 111 addError(tag, description); 112 } 113 114 @Override 115 public void error(String tag, String message, Throwable throwable, Object data) { 116 String description = describe(message); 117 AdtPlugin.log(throwable, "%1$s: %2$s", mName, description); 118 if (throwable != null) { 119 if (throwable instanceof ClassNotFoundException) { 120 // The project callback is given a chance to resolve classes, 121 // and when it fails, it will record it in its own list which 122 // is displayed in a special way (with action hyperlinks etc). 123 // Therefore, include these messages in the visible render log, 124 // especially since the user message from a ClassNotFoundException 125 // is really not helpful (it just lists the class name without 126 // even mentioning that it is a class-not-found exception.) 127 return; 128 } 129 130 mHaveExceptions = true; 131 } 132 133 addError(tag, description); 134 } 135 136 @Override 137 public void warning(String tag, String message, Object data) { 138 String description = describe(message); 139 AdtPlugin.log(IStatus.WARNING, "%1$s: %2$s", mName, description); 140 addWarning(tag, description); 141 } 142 143 @Override 144 public void fidelityWarning(String tag, String message, Throwable throwable, Object data) { 145 if (sIgnoredFidelityWarnings != null && sIgnoredFidelityWarnings.contains(message)) { 146 return; 147 } 148 149 String description = describe(message); 150 AdtPlugin.log(throwable, "%1$s: %2$s", mName, description); 151 if (throwable != null) { 152 mHaveExceptions = true; 153 } 154 155 addFidelityWarning(tag, description); 156 } 157 158 /** 159 * Ignore the given render fidelity warning for the current session 160 * 161 * @param message the message to be ignored for this session 162 */ 163 public static void ignoreFidelityWarning(String message) { 164 if (sIgnoredFidelityWarnings == null) { 165 sIgnoredFidelityWarnings = new HashSet<String>(); 166 } 167 sIgnoredFidelityWarnings.add(message); 168 } 169 170 private String describe(String message) { 171 StringBuilder sb = new StringBuilder(); 172 if (message != null) { 173 if (sb.length() > 0) { 174 sb.append(": "); 175 } 176 sb.append(message); 177 } 178 return sb.toString(); 179 } 180 181 private void addWarning(String tag, String description) { 182 if (mWarnings == null) { 183 mWarnings = new ArrayList<String>(); 184 } else if (mWarnings.contains(description)) { 185 // Avoid duplicates 186 return; 187 } 188 mWarnings.add(description); 189 addTag(tag); 190 } 191 192 private void addError(String tag, String description) { 193 if (mErrors == null) { 194 mErrors = new ArrayList<String>(); 195 } else if (mErrors.contains(description)) { 196 // Avoid duplicates 197 return; 198 } 199 mErrors.add(description); 200 addTag(tag); 201 } 202 203 private void addFidelityWarning(String tag, String description) { 204 if (mFidelityWarnings == null) { 205 mFidelityWarnings = new ArrayList<String>(); 206 } else if (mFidelityWarnings.contains(description)) { 207 // Avoid duplicates 208 return; 209 } 210 mFidelityWarnings.add(description); 211 addTag(tag); 212 } 213 214 // ---- Tags ---- 215 216 private void addTag(String tag) { 217 if (tag != null) { 218 if (mTags == null) { 219 mTags = new ArrayList<String>(); 220 } 221 mTags.add(tag); 222 } 223 } 224 225 /** 226 * Returns true if the given tag prefix has been seen 227 * 228 * @param prefix the tag prefix to look for 229 * @return true iff any tags with the given prefix was seen during the render 230 */ 231 public boolean seenTagPrefix(String prefix) { 232 if (mTags != null) { 233 for (String tag : mTags) { 234 if (tag.startsWith(prefix)) { 235 return true; 236 } 237 } 238 } 239 240 return false; 241 } 242 243 /** 244 * Returns true if the given tag has been seen 245 * 246 * @param tag the tag to look for 247 * @return true iff the tag was seen during the render 248 */ 249 public boolean seenTag(String tag) { 250 if (mTags != null) { 251 return mTags.contains(tag); 252 } else { 253 return false; 254 } 255 } 256 } 257