/*
* Copyright 2009-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.executor;
/**
* @author Clinton Begin
*/
/**
*
* 错误上下文
*/
public class ErrorContext {
// 获得 \n 不同的操作系统不一样
private static final String LINE_SEPARATOR = System.getProperty("line.separator","\n");
//每个线程给开一个错误上下文,防止多线程问题
private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
private ErrorContext stored;
private String resource;
private String activity;
private String object;
private String message;
private String sql;
private Throwable cause;
//单例模式
private ErrorContext() {
}
//工厂方法,得到一个实例
public static ErrorContext instance() {
//因为是多线程,所以用了ThreadLocal 线程安全
ErrorContext context = LOCAL.get();
//懒汉 单例模式
if (context == null) {
context = new ErrorContext();
LOCAL.set(context);
}
return context;
}
//啥意思?把ErrorContext存起来供后用?并把ThreadLocal里的东西清空了?
public ErrorContext store() {
stored = this;
LOCAL.set(new ErrorContext());
return LOCAL.get();
}
//应该是和store相对应的方法,store是存储起来,recall是召回
public ErrorContext recall() {
if (stored != null) {
LOCAL.set(stored);
stored = null;
}
return LOCAL.get();
}
//以下都是建造者模式
public ErrorContext resource(String resource) {
this.resource = resource;
return this;
}
public ErrorContext activity(String activity) {
this.activity = activity;
return this;
}
public ErrorContext object(String object) {
this.object = object;
return this;
}
public ErrorContext message(String message) {
this.message = message;
return this;
}
public ErrorContext sql(String sql) {
this.sql = sql;
return this;
}
public ErrorContext cause(Throwable cause) {
this.cause = cause;
return this;
}
//全部清空重置
public ErrorContext reset() {
resource = null;
activity = null;
object = null;
message = null;
sql = null;
cause = null;
LOCAL.remove();
return this;
}
//打印信息供人阅读
@Override
public String toString() {
StringBuilder description = new StringBuilder();
// message
if (this.message != null) {
description.append(LINE_SEPARATOR);
description.append("### ");
description.append(this.message);
}
// resource
if (resource != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may exist in ");
description.append(resource);
}
// object
if (object != null) {
description.append(LINE_SEPARATOR);
description.append("### The error may involve ");
description.append(object);
}
// activity
if (activity != null) {
description.append(LINE_SEPARATOR);
description.append("### The error occurred while ");
description.append(activity);
}
// activity
if (sql != null) {
description.append(LINE_SEPARATOR);
description.append("### SQL: ");
//把sql压缩到一行里
description.append(sql.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ').trim());
}
// cause
if (cause != null) {
description.append(LINE_SEPARATOR);
description.append("### Cause: ");
description.append(cause.toString());
}
return description.toString();
}
}