/** Set the value for the key in this context. */ public <T> void put(Key<T> key, T data) { DEBUG.P(this, "put(Key<T> key, T data)"); if (data != null) DEBUG.P("data=" + data.getClass().getName()); else DEBUG.P("data=" + data); // DEBUG.P("context前="+toString()); /*例如: Context context = new Context(); Context.Key<Context.Factory> factoryKey =new Context.Key<Context.Factory>(); context.put(factoryKey,new Context.Factory<String>(){public String make() {return "";}}); 出现如下类似异常: Exception in thread "main" java.lang.AssertionError: T extends Context.Factory 因为Context.Key<T>的参数化类型不允许是Context.Key<Context.Factory> */ if (data instanceof Factory) throw new AssertionError("T extends Context.Factory"); checkState(ht); Object old = ht.put(key, data); if (old != null && !(old instanceof Factory) && old != data && data != null) throw new AssertionError("duplicate context value"); DEBUG.P("context后=" + toString()); DEBUG.P(0, this, "put(Key<T> key, T data)"); }
protected Enter(Context context) { DEBUG.P(this,"Enter(1)"); context.put(enterKey, this); log = Log.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); syms = Symtab.instance(context); chk = Check.instance(context); memberEnter = MemberEnter.instance(context); annotate = Annotate.instance(context); lint = Lint.instance(context); predefClassDef = make.ClassDef( make.Modifiers(PUBLIC), syms.predefClass.name, null, null, null, null); //predefClass是一个ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage) //且它的Scope members_field已有成员(几个基本类型符号(symbols for basic types)及其他操作符) //请参考Systab类的predefClass字段说明 predefClassDef.sym = syms.predefClass; todo = Todo.instance(context); fileManager = context.get(JavaFileManager.class); names = Name.Table.instance(context); //我加上的 DEBUG.P(0,this,"Enter(1)"); }
private TypeHandler resolveTypeHandler( TypeHandlerFactory typeHandlerFactory, Class clazz, String propertyName, String javaType, String jdbcType) { try { // 我加上的 DEBUG.P(this, "resolveTypeHandler(5)"); TypeHandler handler = null; if (clazz == null) { // Unknown handler = typeHandlerFactory.getUnkownTypeHandler(); } else if (DomTypeMarker.class.isAssignableFrom(clazz)) { // DOM handler = typeHandlerFactory.getTypeHandler(String.class, jdbcType); } else if (java.util.Map.class.isAssignableFrom(clazz)) { // Map if (javaType == null) { handler = typeHandlerFactory .getUnkownTypeHandler(); // BUG 1012591 - // typeHandlerFactory.getTypeHandler(java.lang.Object.class, jdbcType); } else { try { javaType = typeHandlerFactory.resolveAlias(javaType); Class javaClass = Resources.classForName(javaType); handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType); } catch (Exception e) { throw new SqlMapException("Error. Could not set TypeHandler. Cause: " + e, e); } } } else if (typeHandlerFactory.getTypeHandler(clazz, jdbcType) != null) { // Primitive handler = typeHandlerFactory.getTypeHandler(clazz, jdbcType); } else { // JavaBean if (javaType == null) { Class type = PROBE.getPropertyTypeForGetter(clazz, propertyName); handler = typeHandlerFactory.getTypeHandler(type, jdbcType); } else { try { javaType = typeHandlerFactory.resolveAlias(javaType); Class javaClass = Resources.classForName(javaType); handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType); } catch (Exception e) { throw new SqlMapException("Error. Could not set TypeHandler. Cause: " + e, e); } } } return handler; } finally { // 我加上的 DEBUG.P(0, this, "resolveTypeHandler(5)"); } }
public <T> void put(Class<T> clazz, Factory<T> fac) { DEBUG.P(this, "put(Class<T> clazz, Factory<T> fac)"); if (fac != null) DEBUG.P("fac=" + fac.getClass().getName()); else DEBUG.P("fac=" + fac); // DEBUG.P("context前="+toString()); put(key(clazz), fac); // DEBUG.P("context后="+toString()); DEBUG.P(0, this, "put(Class<T> clazz, Factory<T> fac)"); }
public <T> void put(Class<T> clazz, T data) { DEBUG.P(this, "put(Class<T> clazz, T data)"); if (data != null) DEBUG.P("data=" + data.getClass().getName()); else DEBUG.P("data=" + data); // DEBUG.P("context前="+toString()); put(key(clazz), data); // DEBUG.P("context后="+toString()); DEBUG.P(0, this, "put(Class<T> clazz, T data)"); }
public SqlText parseInlineParameterMap( TypeHandlerFactory typeHandlerFactory, String sqlStatement) { try { // 我加上的 DEBUG.P(this, "parseInlineParameterMap(2)"); return parseInlineParameterMap(typeHandlerFactory, sqlStatement, null); } finally { // 我加上的 DEBUG.P(0, this, "parseInlineParameterMap(2)"); } }
public <T> T get(Class<T> clazz) { try { DEBUG.P(this, "get(Class<T> clazz)"); if (clazz != null) DEBUG.P("clazz=" + clazz.getName()); else DEBUG.P("clazz=" + clazz); return get(key(clazz)); } finally { DEBUG.P(0, this, "get(Class<T> clazz)"); } }
/** Set the factory for the key in this context. */ public <T> void put(Key<T> key, Factory<T> fac) { DEBUG.P(this, "put(Key<T> key, Factory<T> fac)"); // DEBUG.P("context前="+toString()) if (fac != null) DEBUG.P("fac=" + fac.getClass().getName()); else DEBUG.P("fac=" + fac); checkState(ht); Object old = ht.put(key, fac); if (old != null) throw new AssertionError("duplicate context value"); DEBUG.P("context后=" + toString()); DEBUG.P(0, this, "put(Key<T> key, Factory<T> fac)"); }
/** Default constructor */ public SessionScope() { try { // 我加上的 DEBUG.P(this, "SessionScope()"); this.preparedStatements = new HashMap(); this.inBatch = false; this.requestStackDepth = 0; this.id = getNextId(); DEBUG.P("this.id=" + this.id); } finally { // 我加上的 DEBUG.P(0, this, "SessionScope()"); } }
public ServerErrorMessage(String p_serverError, int verbosity) { try { // 我加上的 DEBUG.P(this, "ServerErrorMessage(2)"); DEBUG.P("p_serverError=" + p_serverError); DEBUG.P("verbosity=" + verbosity); this.verbosity = verbosity; char[] l_chars = p_serverError.toCharArray(); int l_pos = 0; int l_length = l_chars.length; while (l_pos < l_length) { char l_mesgType = l_chars[l_pos]; if (l_mesgType != '\0') { l_pos++; int l_startString = l_pos; while (l_chars[l_pos] != '\0' && l_pos < l_length) { l_pos++; } String l_mesgPart = new String(l_chars, l_startString, l_pos - l_startString); m_mesgParts.put(new Character(l_mesgType), l_mesgPart); DEBUG.P("l_mesgPart=" + l_mesgPart); DEBUG.P("m_mesgParts=" + m_mesgParts); } l_pos++; } DEBUG.P("m_mesgParts=" + m_mesgParts); } finally { // 我加上的 DEBUG.P(0, this, "ServerErrorMessage(2)"); } }
private <T> Key<T> key(Class<T> clss) { DEBUG.P(this, "key(Class<T> clss)"); if (clss != null) DEBUG.P("clss=" + clss.getName()); else DEBUG.P("clss=" + clss); checkState(kt); // 等价于Key<T> k = Context.<Key<T>>uncheckedCast(kt.get(clss)); // 因为kt.get(clss)返回的类型是Key<T>,刚好与等式左边的类型一样 Key<T> k = uncheckedCast(kt.get(clss)); DEBUG.P("k=" + k); if (k == null) { k = new Key<T>(); kt.put(clss, k); } DEBUG.P(0, this, "key(Class<T> clss)"); return k; }
/** Get the value for the key in this context. */ public <T> T get(Key<T> key) { try { DEBUG.P(this, "get(Key<T> key)"); // if(key!=null) DEBUG.P("key="+key.getClass().getName()); // else DEBUG.P("key="+key); DEBUG.P("key=" + key); checkState(ht); Object o = ht.get(key); if (o != null) DEBUG.P("o=" + o.getClass().getName()); else DEBUG.P("o=" + o); DEBUG.P("(o instanceof Factory)=" + (o instanceof Factory)); if (o instanceof Factory) { Factory fac = (Factory) o; o = fac.make(); if (o instanceof Factory) throw new AssertionError("T extends Context.Factory"); // 也就是说在调用make()时已把make()返回的结果放入ht(例子见:JavacFileManager.preRegister()) assert ht.get(key) == o; } /* The following cast can't fail unless there was * cheating elsewhere, because of the invariant on ht. * Since we found a key of type Key<T>, the value must * be of type T. */ return Context.<T>uncheckedCast(o); } finally { DEBUG.P(0, this, "get(Key<T> key)"); } /* 注意这里的“<T>”与 “private static <T> T uncheckedCast(Object o)”中 的“<T>”的差别,前者表示的是get(Key<T> key)方法中的“T”的实际类型, 假设最开始: ------------------------------------- Context context = new Context(); Context.Key<Number> numberKey = new Context.Key<Number>(); Number number=new Number(); context.put(numberKey,number); number=context.get(numberKey); ------------------------------------ 这时把“numberKey”传进“get(Key<T> key)”方法, 因为参数“numberKey”是“Context.Key<Number>”类型, 所以get(Key<T> key)中的“T”的实际类型是“Number”。 但是“get(Key<T> key)”方法里的“Object o = ht.get(key)”, 变量“o”是Object类型的,必需调用“Context.<T>uncheckedCast(o)”将 变量“o”引用的Object实例转换成“Number”类型, 这样“number=context.get(numberKey)”得到的结果才正确。 “Context.<T>uncheckedCast(o)”相当于把“Object o”转换成“<T>”(这里就是Number) 像“Context.<T>uncheckedCast(o)”这种语法确实很古怪, 这主要是由于“private static <T> T uncheckedCast(Object o)”方法的定义 造成的,这个方法是一个静态泛型方法,而且只有返回类型与泛型变量“<T>”相关, 方法参数只有( Object o ),并且不与泛型变量“<T>”相关, 当要调用uncheckedCast方法时,可以用下面的格式调用它: Context.<返回值类型>uncheckedCast(参数Object o) 返回值类型可以是泛型变量 (泛型变量的实际类型在编译期间只能推断它的上限绑定, 具体是什么类型只能在运行期间确定) 假设最开始: Object o=new String("str"); 那么可以这样调用它: String str=Context.<String>uncheckedCast(o);(等价于: String str=(String)o) 把“return Context.<T>uncheckedCast(o);”与uncheckedCast方法的调用格式对照 “<T>”对应“<返回值类型>”,“(o)”对应“(参数Object o)” 另外“uncheckedCast”方法的定义如下: -------------------------------------- @SuppressWarnings("unchecked") private static <T> T uncheckedCast(Object o) { return (T)o; } -------------------------------------- 注释“@SuppressWarnings("unchecked")”间接指出了uncheckedCast方法会在 运行时有可能产生转换异常(java.lang.ClassCastException), 因为(T)的类型是未确定的, 比如(T)的类型可能是“Number”,当参数(Object o)实际是String的实例引用时, 这时“(T)o”就等价于“(Number)String”,显然是不对的。 */ }
public SqlText parseInlineParameterMap( TypeHandlerFactory typeHandlerFactory, String sqlStatement, Class parameterClass) { try { // 我加上的 DEBUG.P(this, "parseInlineParameterMap(3)"); DEBUG.P("sqlStatement=" + sqlStatement); DEBUG.P("parameterClass=" + parameterClass); String newSql = sqlStatement; List mappingList = new ArrayList(); // 第三个参数为true,表示把分隔符PARAMETER_TOKEN("#")也返回 StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true); StringBuffer newSqlBuffer = new StringBuffer(); String token = null; String lastToken = null; while (parser.hasMoreTokens()) { token = parser.nextToken(); DEBUG.P("lastToken=" + lastToken); DEBUG.P("token=" + token); if (PARAMETER_TOKEN.equals(lastToken)) { if (PARAMETER_TOKEN.equals(token)) { // 连续的两个#代表一个"#"字符 // 如:select * from ACCOUNT where ACC_FIRST_NAME = "##" // 实际是: select * from ACCOUNT where ACC_FIRST_NAME = "#" newSqlBuffer.append(PARAMETER_TOKEN); token = null; } else { ParameterMapping mapping = null; if (token.indexOf(PARAM_DELIM) > -1) { mapping = oldParseMapping(token, parameterClass, typeHandlerFactory); } else { mapping = newParseMapping(token, parameterClass, typeHandlerFactory); } mappingList.add(mapping); newSqlBuffer.append("?"); token = parser.nextToken(); DEBUG.P("token2=" + token); if (!PARAMETER_TOKEN.equals(token)) { throw new SqlMapException( "Unterminated inline parameter in mapped statement (" + "statement.getId()" + ")."); } token = null; } } else { if (!PARAMETER_TOKEN.equals(token)) { newSqlBuffer.append(token); } } lastToken = token; } newSql = newSqlBuffer.toString(); DEBUG.P(1); DEBUG.P("newSql=" + newSql); ParameterMapping[] mappingArray = (ParameterMapping[]) mappingList.toArray(new ParameterMapping[mappingList.size()]); DEBUG.PA("mappingArray", mappingArray); SqlText sqlText = new SqlText(); sqlText.setText(newSql); sqlText.setParameterMappings(mappingArray); return sqlText; } finally { // 我加上的 DEBUG.P(0, this, "parseInlineParameterMap(3)"); } }
private ParameterMapping oldParseMapping( String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) { try { // 我加上的 DEBUG.P(this, "oldParseMapping(3)"); ParameterMapping mapping = new ParameterMapping(); if (token.indexOf(PARAM_DELIM) > -1) { StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true); int n1 = paramParser.countTokens(); if (n1 == 3) { String name = paramParser.nextToken(); paramParser.nextToken(); // ignore ":" String type = paramParser.nextToken(); mapping.setPropertyName(name); mapping.setJdbcTypeName(type); TypeHandler handler; if (parameterClass == null) { handler = typeHandlerFactory.getUnkownTypeHandler(); } else { handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type); } mapping.setTypeHandler(handler); return mapping; } else if (n1 >= 5) { String name = paramParser.nextToken(); paramParser.nextToken(); // ignore ":" String type = paramParser.nextToken(); paramParser.nextToken(); // ignore ":" String nullValue = paramParser.nextToken(); while (paramParser.hasMoreTokens()) { nullValue = nullValue + paramParser.nextToken(); } mapping.setPropertyName(name); mapping.setJdbcTypeName(type); mapping.setNullValue(nullValue); TypeHandler handler; if (parameterClass == null) { handler = typeHandlerFactory.getUnkownTypeHandler(); } else { handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type); } mapping.setTypeHandler(handler); return mapping; } else { throw new SqlMapException("Incorrect inline parameter map format: " + token); } } else { mapping.setPropertyName(token); TypeHandler handler; if (parameterClass == null) { handler = typeHandlerFactory.getUnkownTypeHandler(); } else { handler = resolveTypeHandler(typeHandlerFactory, parameterClass, token, null, null); } mapping.setTypeHandler(handler); return mapping; } } finally { // 我加上的 DEBUG.P(0, this, "oldParseMapping(3)"); } }
private ParameterMapping newParseMapping( String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) { try { // 我加上的 DEBUG.P(this, "newParseMapping(3)"); DEBUG.P("token=" + token); DEBUG.P("parameterClass=" + parameterClass); ParameterMapping mapping = new ParameterMapping(); // #propertyName,javaType=string,jdbcType=VARCHAR,mode=IN,nullValue=N/A,handler=string,numericScale=2# StringTokenizer paramParser = new StringTokenizer(token, "=,", false); mapping.setPropertyName(paramParser.nextToken()); while (paramParser.hasMoreTokens()) { String field = paramParser.nextToken(); if (paramParser.hasMoreTokens()) { String value = paramParser.nextToken(); if ("javaType".equals(field)) { value = typeHandlerFactory.resolveAlias(value); mapping.setJavaTypeName(value); } else if ("jdbcType".equals(field)) { mapping.setJdbcTypeName(value); } else if ("mode".equals(field)) { mapping.setMode(value); } else if ("nullValue".equals(field)) { mapping.setNullValue(value); } else if ("handler".equals(field)) { try { value = typeHandlerFactory.resolveAlias(value); Object impl = Resources.instantiate(value); if (impl instanceof TypeHandlerCallback) { mapping.setTypeHandler(new CustomTypeHandler((TypeHandlerCallback) impl)); } else if (impl instanceof TypeHandler) { mapping.setTypeHandler((TypeHandler) impl); } else { throw new SqlMapException( "The class " + value + " is not a valid implementation of TypeHandler or TypeHandlerCallback"); } } catch (Exception e) { throw new SqlMapException( "Error loading class specified by handler field in " + token + ". Cause: " + e, e); } } else if ("numericScale".equals(field)) { try { Integer numericScale = Integer.valueOf(value); if (numericScale.intValue() < 0) { throw new SqlMapException( "Value specified for numericScale must be greater than or equal to zero"); } mapping.setNumericScale(numericScale); } catch (NumberFormatException e) { throw new SqlMapException("Value specified for numericScale is not a valid Integer"); } } else { throw new SqlMapException( "Unrecognized parameter mapping field: '" + field + "' in " + token); } } else { throw new SqlMapException( "Incorrect inline parameter map format (missmatched name=value pairs): " + token); } } if (mapping.getTypeHandler() == null) { TypeHandler handler; if (parameterClass == null) { handler = typeHandlerFactory.getUnkownTypeHandler(); } else { handler = resolveTypeHandler( typeHandlerFactory, parameterClass, mapping.getPropertyName(), mapping.getJavaTypeName(), mapping.getJdbcTypeName()); } mapping.setTypeHandler(handler); } return mapping; } finally { // 我加上的 DEBUG.P(0, this, "newParseMapping(3)"); } }