ScopedException.java revision 731b74f7f44e67312a1fc4161c4e0aae221b2417
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 17package android.databinding.tool.processing; 18 19import org.apache.commons.lang3.StringUtils; 20 21import android.databinding.tool.store.Location; 22import android.databinding.tool.util.L; 23 24import java.util.ArrayList; 25import java.util.List; 26import java.util.regex.Matcher; 27import java.util.regex.Pattern; 28 29/** 30 * An exception that contains scope information. 31 */ 32public class ScopedException extends RuntimeException { 33 public static final String ERROR_LOG_PREFIX = "****/ data binding error ****"; 34 public static final String ERROR_LOG_SUFFIX = "****\\ data binding error ****"; 35 public static final String MSG_KEY = "msg:"; 36 public static final String LOCATION_KEY = "loc:"; 37 public static final String FILE_KEY = "file:"; 38 private ScopedErrorReport mScopedErrorReport; 39 private String mScopeLog; 40 41 public ScopedException(String message, Object... args) { 42 super(message == null ? "unknown data binding exception" : String.format(message, args)); 43 mScopedErrorReport = Scope.createReport(); 44 mScopeLog = L.isDebugEnabled() ? Scope.produceScopeLog() : null; 45 } 46 47 ScopedException(String message, ScopedErrorReport scopedErrorReport) { 48 super(message); 49 mScopedErrorReport = scopedErrorReport; 50 } 51 52 public String getBareMessage() { 53 return super.getMessage(); 54 } 55 56 @Override 57 public String getMessage() { 58 ScopedErrorReport scopedError = getScopedErrorReport(); 59 StringBuilder sb = new StringBuilder(); 60 sb.append(ERROR_LOG_PREFIX) 61 .append(MSG_KEY).append(super.getMessage()).append("\n") 62 .append(FILE_KEY).append(scopedError.getFilePath()).append("\n"); 63 if (scopedError.getLocations() != null) { 64 for (Location location : scopedError.getLocations()) { 65 sb.append(LOCATION_KEY).append(location.toUserReadableString()).append("\n"); 66 } 67 } 68 sb.append(ERROR_LOG_SUFFIX); 69 return StringUtils.join(StringUtils.split(sb.toString(), System.lineSeparator()), " "); 70 } 71 72 public ScopedErrorReport getScopedErrorReport() { 73 return mScopedErrorReport; 74 } 75 76 public boolean isValid() { 77 return mScopedErrorReport.isValid(); 78 } 79 80 public static ScopedException createFromOutput(String output) { 81 String message = ""; 82 String file = ""; 83 List<Location> locations = new ArrayList<>(); 84 int msgStart = output.indexOf(MSG_KEY); 85 if (msgStart < 0) { 86 message = output; 87 } else { 88 int fileStart = output.indexOf(FILE_KEY, msgStart + MSG_KEY.length()); 89 if (fileStart < 0) { 90 message = output; 91 } else { 92 message = output.substring(msgStart + MSG_KEY.length(), fileStart); 93 int locStart = output.indexOf(LOCATION_KEY, fileStart + FILE_KEY.length()); 94 if (locStart < 0) { 95 file = output.substring(fileStart + FILE_KEY.length()); 96 } else { 97 file = output.substring(fileStart + FILE_KEY.length(), locStart); 98 int nextLoc = 0; 99 while(nextLoc >= 0) { 100 nextLoc = output.indexOf(LOCATION_KEY, locStart + LOCATION_KEY.length()); 101 Location loc; 102 if (nextLoc < 0) { 103 loc = Location.fromUserReadableString( 104 output.substring(locStart + LOCATION_KEY.length())); 105 } else { 106 loc = Location.fromUserReadableString( 107 output.substring(locStart + LOCATION_KEY.length(), nextLoc)); 108 } 109 if (loc != null && loc.isValid()) { 110 locations.add(loc); 111 } 112 locStart = nextLoc; 113 } 114 } 115 } 116 } 117 return new ScopedException(message.trim(), 118 new ScopedErrorReport(StringUtils.isEmpty(file) ? null : file.trim(), locations)); 119 } 120 121 public static List<ScopedException> extractErrors(String output) { 122 List<ScopedException> errors = new ArrayList<>(); 123 int index = output.indexOf(ERROR_LOG_PREFIX); 124 final int limit = output.length(); 125 while (index >= 0 && index < limit) { 126 int end = output.indexOf(ERROR_LOG_SUFFIX, index + ERROR_LOG_PREFIX.length()); 127 if (end == -1) { 128 errors.add(createFromOutput(output.substring(index + ERROR_LOG_PREFIX.length()))); 129 break; 130 } else { 131 errors.add(createFromOutput(output.substring(index + ERROR_LOG_PREFIX.length(), 132 end))); 133 index = output.indexOf(ERROR_LOG_PREFIX, end + ERROR_LOG_SUFFIX.length()); 134 } 135 } 136 return errors; 137 } 138} 139