浏览代码

jfinal 1.9 release ^_^

James 11 年之前
父节点
当前提交
f8f2c854ae
共有 100 个文件被更改,包括 1220 次插入316 次删除
  1. 2 0
      .classpath
  2. 1 1
      .gitignore
  3. 2 0
      .project
  4. 1 0
      .settings/org.eclipse.wst.common.project.facet.core.xml
  5. 1 1
      README.rst
  6. 21 7
      pom.xml
  7. 1 1
      src/com/jfinal/aop/ActionInvocationWrapper.java
  8. 1 1
      src/com/jfinal/aop/Before.java
  9. 1 1
      src/com/jfinal/aop/ClearInterceptor.java
  10. 1 1
      src/com/jfinal/aop/ClearLayer.java
  11. 1 1
      src/com/jfinal/aop/Interceptor.java
  12. 1 1
      src/com/jfinal/aop/InterceptorStack.java
  13. 1 1
      src/com/jfinal/aop/PrototypeInterceptor.java
  14. 1 1
      src/com/jfinal/config/Constants.java
  15. 1 1
      src/com/jfinal/config/Handlers.java
  16. 1 1
      src/com/jfinal/config/Interceptors.java
  17. 74 78
      src/com/jfinal/config/JFinalConfig.java
  18. 1 1
      src/com/jfinal/config/Plugins.java
  19. 1 1
      src/com/jfinal/config/Routes.java
  20. 1 1
      src/com/jfinal/core/Action.java
  21. 1 1
      src/com/jfinal/core/ActionException.java
  22. 4 4
      src/com/jfinal/core/ActionHandler.java
  23. 1 1
      src/com/jfinal/core/ActionInvocation.java
  24. 1 1
      src/com/jfinal/core/ActionKey.java
  25. 1 1
      src/com/jfinal/core/ActionMapping.java
  26. 1 2
      src/com/jfinal/core/ActionRender.java
  27. 1 1
      src/com/jfinal/core/ActionReporter.java
  28. 21 21
      src/com/jfinal/core/Config.java
  29. 5 5
      src/com/jfinal/core/Const.java
  30. 19 12
      src/com/jfinal/core/Controller.java
  31. 1 1
      src/com/jfinal/core/InterceptorBuilder.java
  32. 1 1
      src/com/jfinal/core/JFinal.java
  33. 9 11
      src/com/jfinal/core/JFinalFilter.java
  34. 1 1
      src/com/jfinal/core/ModelInjector.java
  35. 1 1
      src/com/jfinal/core/TypeConverter.java
  36. 1 1
      src/com/jfinal/ext/handler/ContextPathHandler.java
  37. 12 1
      src/com/jfinal/ext/handler/FakeStaticHandler.java
  38. 1 1
      src/com/jfinal/ext/handler/RoutesHandler.java
  39. 1 1
      src/com/jfinal/ext/handler/ServerNameRedirect301Handler.java
  40. 1 1
      src/com/jfinal/ext/handler/UrlSkipHandler.java
  41. 1 1
      src/com/jfinal/ext/interceptor/GET.java
  42. 1 1
      src/com/jfinal/ext/interceptor/LogInterceptor.java
  43. 1 1
      src/com/jfinal/ext/interceptor/NoUrlPara.java
  44. 29 0
      src/com/jfinal/ext/interceptor/NotAction.java
  45. 1 1
      src/com/jfinal/ext/interceptor/POST.java
  46. 1 1
      src/com/jfinal/ext/interceptor/Restful.java
  47. 4 1
      src/com/jfinal/ext/interceptor/SessionInViewInterceptor.java
  48. 1 1
      src/com/jfinal/ext/kit/DateKit.java
  49. 1 1
      src/com/jfinal/ext/kit/SessionIdKit.java
  50. 3 4
      src/com/jfinal/ext/render/CaptchaRender.java
  51. 6 3
      src/com/jfinal/ext/render/StaticHtmlRender.java
  52. 1 1
      src/com/jfinal/handler/Handler.java
  53. 1 1
      src/com/jfinal/handler/HandlerFactory.java
  54. 1 1
      src/com/jfinal/i18n/I18N.java
  55. 64 0
      src/com/jfinal/kit/EncryptionKit.java
  56. 1 1
      src/com/jfinal/kit/FileKit.java
  57. 7 1
      src/com/jfinal/kit/HandlerKit.java
  58. 263 0
      src/com/jfinal/kit/HttpKit.java
  59. 11 4
      src/com/jfinal/kit/JsonKit.java
  60. 1 1
      src/com/jfinal/kit/PathKit.java
  61. 154 0
      src/com/jfinal/kit/Prop.java
  62. 158 0
      src/com/jfinal/kit/PropKit.java
  63. 13 7
      src/com/jfinal/kit/StrKit.java
  64. 1 1
      src/com/jfinal/kit/StringKit.java
  65. 1 1
      src/com/jfinal/log/ILoggerFactory.java
  66. 1 1
      src/com/jfinal/log/JdkLogger.java
  67. 1 1
      src/com/jfinal/log/JdkLoggerFactory.java
  68. 1 1
      src/com/jfinal/log/Log4jLogger.java
  69. 1 1
      src/com/jfinal/log/Log4jLoggerFactory.java
  70. 1 1
      src/com/jfinal/log/Logger.java
  71. 1 1
      src/com/jfinal/log/NullLoggerFactory.java
  72. 1 1
      src/com/jfinal/plugin/IPlugin.java
  73. 1 1
      src/com/jfinal/plugin/activerecord/ActiveRecordException.java
  74. 1 1
      src/com/jfinal/plugin/activerecord/ActiveRecordPlugin.java
  75. 1 1
      src/com/jfinal/plugin/activerecord/CPI.java
  76. 1 1
      src/com/jfinal/plugin/activerecord/CaseInsensitiveContainerFactory.java
  77. 1 1
      src/com/jfinal/plugin/activerecord/Config.java
  78. 71 71
      src/com/jfinal/plugin/activerecord/Db.java
  79. 1 1
      src/com/jfinal/plugin/activerecord/DbKit.java
  80. 22 10
      src/com/jfinal/plugin/activerecord/DbPro.java
  81. 1 1
      src/com/jfinal/plugin/activerecord/IAtom.java
  82. 2 2
      src/com/jfinal/plugin/activerecord/ICallback.java
  83. 1 1
      src/com/jfinal/plugin/activerecord/IContainerFactory.java
  84. 1 1
      src/com/jfinal/plugin/activerecord/IDataSourceProvider.java
  85. 1 1
      src/com/jfinal/plugin/activerecord/Model.java
  86. 1 1
      src/com/jfinal/plugin/activerecord/ModelBuilder.java
  87. 124 0
      src/com/jfinal/plugin/activerecord/ModelRecordElResolver.java
  88. 1 1
      src/com/jfinal/plugin/activerecord/NestedTransactionHelpException.java
  89. 1 1
      src/com/jfinal/plugin/activerecord/OneConnectionPerThread.java
  90. 38 0
      src/com/jfinal/plugin/activerecord/OrderedFieldContainerFactory.java
  91. 1 1
      src/com/jfinal/plugin/activerecord/Page.java
  92. 1 1
      src/com/jfinal/plugin/activerecord/Record.java
  93. 1 1
      src/com/jfinal/plugin/activerecord/RecordBuilder.java
  94. 1 1
      src/com/jfinal/plugin/activerecord/SqlReporter.java
  95. 10 2
      src/com/jfinal/plugin/activerecord/Table.java
  96. 1 1
      src/com/jfinal/plugin/activerecord/TableBuilder.java
  97. 1 1
      src/com/jfinal/plugin/activerecord/TableMapping.java
  98. 1 1
      src/com/jfinal/plugin/activerecord/cache/EhCache.java
  99. 1 1
      src/com/jfinal/plugin/activerecord/cache/ICache.java
  100. 0 0
      src/com/jfinal/plugin/activerecord/dialect/AnsiSqlDialect.java

+ 2 - 0
.classpath

@@ -14,3 +14,5 @@
 	</classpathentry>
 	<classpathentry kind="output" path="webapp/WEB-INF/classes"/>
 </classpath>
+
+

+ 1 - 1
.gitignore

@@ -15,4 +15,4 @@ out
 
 *.jar
 /webapp/WEB-INF/classes/
-/webapp/WEB-INF/target/
+/webapp/WEB-INF/target/

+ 2 - 0
.project

@@ -40,3 +40,5 @@
 		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
 	</natures>
 </projectDescription>
+
+

+ 1 - 0
.settings/org.eclipse.wst.common.project.facet.core.xml

@@ -5,3 +5,4 @@
   <installed facet="wst.jsdt.web" version="1.0"/>
   <installed facet="java" version="1.6"/>
 </faceted-project>
+

+ 1 - 1
README.rst

@@ -18,7 +18,7 @@ JFinal有如下主要特点
 #. 功能齐全,拥有struts2的绝大部分功能
 #. 体积小仅218K,且无第三方依赖
 
-**JFinal 极速开发QQ群欢迎您的加入: 222478625、326297041、196337924**
+**JFinal 极速开发QQ群欢迎您的加入: 335699801、38707273**
 
 **以下是JFinal实现Blog管理的示例:**
 

+ 21 - 7
pom.xml

@@ -4,7 +4,7 @@
 	<artifactId>jfinal</artifactId>
 	<packaging>jar</packaging>
 	<name>JFinal</name>
-	<version>1.8-SNAPSHOT</version>
+	<version>1.9-SNAPSHOT</version>
 	<url>http://www.jfinal.com</url>
 	<description>JFinal is a simple, light, rapid,independent, extensible Java WEB + ORM framework. The feature of JFinal looks like ruby on rails especially ActiveRecord.</description>
 	
@@ -63,6 +63,13 @@
 			<version>2.5</version>
 			<scope>provided</scope>
 		</dependency>
+		<!-- jsp support by jetty -->
+		<dependency>
+			<groupId>org.eclipse.jetty</groupId>
+			<artifactId>jetty-jsp</artifactId>
+			<version>8.1.8.v20121106</version>
+			<scope>provided</scope>
+		</dependency>
 		<!-- cos -->
 		<dependency>
 			<groupId>c3p0</groupId>
@@ -89,12 +96,6 @@
 			<scope>provided</scope>
 		</dependency>
 		<dependency>
-			<groupId>javax.servlet.jsp.jstl</groupId>
-			<artifactId>javax.servlet.jsp.jstl-api</artifactId>
-			<version>1.2.1</version>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
 			<groupId>log4j</groupId>
 			<artifactId>log4j</artifactId>
 			<version>1.2.16</version>
@@ -107,6 +108,12 @@
 			<scope>provided</scope>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.velocity</groupId>
+			<artifactId>velocity-tools</artifactId>
+			<version>2.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
 			<groupId>org.springframework</groupId>
 			<artifactId>spring-context</artifactId>
 			<version>3.2.4.RELEASE</version>
@@ -118,6 +125,13 @@
 			<version>26Dec2008</version>
 			<scope>provided</scope>
 		</dependency>
+		<!--
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+			<version>5.1.20</version>
+		</dependency>
+		-->
 	</dependencies>
 	
 	<build>

+ 1 - 1
src/com/jfinal/aop/ActionInvocationWrapper.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/Before.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/ClearInterceptor.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/ClearLayer.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/Interceptor.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/InterceptorStack.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/aop/PrototypeInterceptor.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/config/Constants.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/config/Handlers.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/config/Interceptors.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 74 - 78
src/com/jfinal/config/JFinalConfig.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,10 @@
 package com.jfinal.config;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Properties;
-import com.jfinal.kit.PathKit;
-import com.jfinal.kit.StrKit;
+import com.jfinal.core.Const;
+import com.jfinal.kit.Prop;
+import com.jfinal.kit.PropKit;
 
 /**
  * JFinalConfig.
@@ -67,97 +64,96 @@ public abstract class JFinalConfig {
 	 */
 	public void beforeJFinalStop(){};
 	
-	private Properties properties;
+	protected Prop prop = null;
+	
+	/**
+	 * Load property file.
+	 * @see #loadPropertyFile(String, String)
+	 */
+	public Properties loadPropertyFile(String fileName) {
+		return loadPropertyFile(fileName, Const.DEFAULT_ENCODING);
+	}
+	
+	/**
+	 * Load property file.
+	 * Example:<br>
+	 * loadPropertyFile("db_username_pass.txt", "UTF-8");
+	 * 
+	 * @param fileName the file in CLASSPATH or the sub directory of the CLASSPATH
+	 * @param encoding the encoding
+	 */
+	public Properties loadPropertyFile(String fileName, String encoding) {
+		prop = PropKit.use(fileName, encoding);
+		return prop.getProperties();
+	}
+	
+	/**
+	 * Load property file.
+	 * @see #loadPropertyFile(File, String)
+	 */
+	public Properties loadPropertyFile(File file) {
+		return loadPropertyFile(file, Const.DEFAULT_ENCODING);
+	}
 	
 	/**
 	 * Load property file
-	 * Example: loadPropertyFile("db_username_pass.txt");
-	 * @param file the file in WEB-INF directory
+	 * Example:<br>
+	 * loadPropertyFile(new File("/var/config/my_config.txt"), "UTF-8");
+	 * 
+	 * @param file the properties File object
+	 * @param encoding the encoding
 	 */
-	public Properties loadPropertyFile(String file) {
-		if (StrKit.isBlank(file))
-			throw new IllegalArgumentException("Parameter of file can not be blank");
-		if (file.contains(".."))
-			throw new IllegalArgumentException("Parameter of file can not contains \"..\"");
-		
-		InputStream inputStream = null;
-		String fullFile;	// String fullFile = PathUtil.getWebRootPath() + file;
-		if (file.startsWith(File.separator))
-			fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + file;
-		else
-			fullFile = PathKit.getWebRootPath() + File.separator + "WEB-INF" + File.separator + file;
-		
-		try {
-			inputStream = new FileInputStream(new File(fullFile));
-			Properties p = new Properties();
-			p.load(inputStream);
-			properties = p;
-		} catch (FileNotFoundException e) {
-			throw new IllegalArgumentException("Properties file not found: " + fullFile);
-		} catch (IOException e) {
-			throw new IllegalArgumentException("Properties file can not be loading: " + fullFile);
-		}
-		finally {
-			try {if (inputStream != null) inputStream.close();} catch (IOException e) {e.printStackTrace();}
-		}
-		if (properties == null)
-			throw new RuntimeException("Properties file loading failed: " + fullFile);
-		return properties;
+	public Properties loadPropertyFile(File file, String encoding) {
+		prop = PropKit.use(file, encoding);
+		return prop.getProperties();
+	}
+	
+	public void unloadPropertyFile(String fileName) {
+		Prop uselessProp = PropKit.useless(fileName);
+		if (this.prop == uselessProp)
+			this.prop = null;
+	}
+	
+	public void unloadAllPropertyFiles() {
+		PropKit.clear();
+		prop = null;
+	}
+	
+	private Prop getProp() {
+		if (prop == null)
+			throw new IllegalStateException("Load propties file by invoking loadPropertyFile(String fileName) method first.");
+		return prop;
 	}
 	
 	public String getProperty(String key) {
-		checkPropertyLoading();
-		return properties.getProperty(key);
+		return getProp().get(key);
 	}
 	
 	public String getProperty(String key, String defaultValue) {
-		checkPropertyLoading();
-		return properties.getProperty(key, defaultValue);
+		return getProp().get(key, defaultValue);
 	}
 	
 	public Integer getPropertyToInt(String key) {
-		checkPropertyLoading();
-		Integer resultInt = null;
-		String resultStr = properties.getProperty(key);
-		if (resultStr != null)
-			resultInt =  Integer.parseInt(resultStr);
-		return resultInt;
+		return getProp().getInt(key);
 	}
 	
 	public Integer getPropertyToInt(String key, Integer defaultValue) {
-		Integer result = getPropertyToInt(key);
-		return result != null ? result : defaultValue;
+		return getProp().getInt(key, defaultValue);
 	}
 	
-	public Boolean getPropertyToBoolean(String key) {
-		checkPropertyLoading();
-		String resultStr = properties.getProperty(key);
-		Boolean resultBool = null;
-		if (resultStr != null) {
-			if (resultStr.trim().equalsIgnoreCase("true"))
-				resultBool = true;
-			else if (resultStr.trim().equalsIgnoreCase("false"))
-				resultBool = false;
-		}
-		return resultBool;
+	public Long getPropertyToLong(String key) {
+		return getProp().getLong(key);
 	}
 	
-	public Boolean getPropertyToBoolean(String key, boolean defaultValue) {
-		Boolean result = getPropertyToBoolean(key);
-		return result != null ? result : defaultValue;
+	public Long getPropertyToLong(String key, Long defaultValue) {
+		return getProp().getLong(key, defaultValue);
 	}
 	
-	private void checkPropertyLoading() {
-		if (properties == null)
-			throw new RuntimeException("You must load properties file by invoking loadPropertyFile(String) method in configConstant(Constants) method before.");
+	public Boolean getPropertyToBoolean(String key) {
+		return getProp().getBoolean(key);
 	}
-}
-
-
-
-
-
-
-
-
-
+	
+	public Boolean getPropertyToBoolean(String key, Boolean defaultValue) {
+		return getProp().getBoolean(key, defaultValue);
+	}
+}

+ 1 - 1
src/com/jfinal/config/Plugins.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/config/Routes.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/Action.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/ActionException.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 4 - 4
src/com/jfinal/core/ActionHandler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ final class ActionHandler extends Handler {
 	 * 3: render(...)
 	 */
 	public final void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
-		if (target.indexOf(".") != -1) {
+		if (target.indexOf('.') != -1) {
 			return ;
 		}
 		
@@ -117,10 +117,10 @@ final class ActionHandler extends Handler {
 			}
 			e.getErrorRender().setContext(request, response).render();
 		}
-		catch (Exception e) {
+		catch (Throwable t) {
 			if (log.isErrorEnabled()) {
 				String qs = request.getQueryString();
-				log.error(qs == null ? target : target + "?" + qs, e);
+				log.error(qs == null ? target : target + "?" + qs, t);
 			}
 			renderFactory.getErrorRender(500).setContext(request, response).render();
 		}

+ 1 - 1
src/com/jfinal/core/ActionInvocation.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/ActionKey.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/ActionMapping.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 2
src/com/jfinal/core/ActionRender.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import com.jfinal.render.Render;
  */
 final class ActionRender extends Render {
 	
-	private static final long serialVersionUID = 3712913909977013446L;
 	private String actionUrl;
 	
 	public ActionRender(String actionUrl) {

+ 1 - 1
src/com/jfinal/core/ActionReporter.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 21 - 21
src/com/jfinal/core/Config.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -72,29 +72,29 @@ class Config {
 	
 	private static void startPlugins() {
 		List<IPlugin> pluginList = plugins.getPluginList();
-		if (pluginList != null) {
-			for (IPlugin plugin : pluginList) {
-				try {
-					// process ActiveRecordPlugin devMode
-					if (plugin instanceof com.jfinal.plugin.activerecord.ActiveRecordPlugin) {
-						com.jfinal.plugin.activerecord.ActiveRecordPlugin arp = (com.jfinal.plugin.activerecord.ActiveRecordPlugin)plugin;
-						if (arp.getDevMode() == null)
-							arp.setDevMode(constants.getDevMode());
-					}
-					
-					boolean success = plugin.start();
-					if (!success) {
-						String message = "Plugin start error: " + plugin.getClass().getName();
-						log.error(message);
-						throw new RuntimeException(message);
-					}
+		if (pluginList == null)
+			return ;
+		
+		for (IPlugin plugin : pluginList) {
+			try {
+				// process ActiveRecordPlugin devMode
+				if (plugin instanceof com.jfinal.plugin.activerecord.ActiveRecordPlugin) {
+					com.jfinal.plugin.activerecord.ActiveRecordPlugin arp = (com.jfinal.plugin.activerecord.ActiveRecordPlugin)plugin;
+					if (arp.getDevMode() == null)
+						arp.setDevMode(constants.getDevMode());
 				}
-				catch (Exception e) {
-					String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage();
-					log.error(message, e);
-					throw new RuntimeException(message, e);
+				
+				if (plugin.start() == false) {
+					String message = "Plugin start error: " + plugin.getClass().getName();
+					log.error(message);
+					throw new RuntimeException(message);
 				}
 			}
+			catch (Exception e) {
+				String message = "Plugin start error: " + plugin.getClass().getName() + ". \n" + e.getMessage();
+				log.error(message, e);
+				throw new RuntimeException(message, e);
+			}
 		}
 	}
 	

+ 5 - 5
src/com/jfinal/core/Const.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,15 +24,15 @@ import com.jfinal.render.ViewType;
  */
 public interface Const {
 	
-	String JFINAL_VERSION = "1.8";
+	String JFINAL_VERSION = "1.9";
 	
 	ViewType DEFAULT_VIEW_TYPE = ViewType.FREE_MARKER;
 	
-	String DEFAULT_ENCODING = "utf-8";
+	String DEFAULT_ENCODING = "UTF-8";
 	
-	String DEFAULT_URL_PARA_SEPARATOR = "-";
+	boolean DEFAULT_DEV_MODE = false;
 	
-	String DEFAULT_FILE_CONTENT_TYPE = "application/octet-stream";
+	String DEFAULT_URL_PARA_SEPARATOR = "-";
 	
 	String DEFAULT_JSP_EXTENSION = ".jsp";
 	

+ 19 - 12
src/com/jfinal/core/Controller.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpSession;
 import static com.jfinal.core.Const.I18N_LOCALE;
 import com.jfinal.i18n.I18N;
 import com.jfinal.kit.StrKit;
+import com.jfinal.render.ContentType;
 import com.jfinal.render.Render;
 import com.jfinal.render.RenderFactory;
 import com.jfinal.upload.MultipartRequest;
@@ -968,13 +969,22 @@ public abstract class Controller {
 	/**
 	 * Render with text and content type.
 	 * <p>
-	 * Example: renderText("<user id='5888'>James</user>", "application/xml");
+	 * Example: renderText("&lt;user id='5888'&gt;James&lt;/user&gt;", "application/xml");
 	 */
 	public void renderText(String text, String contentType) {
 		render = renderFactory.getTextRender(text, contentType);
 	}
 	
 	/**
+	 * Render with text and ContentType.
+	 * <p>
+	 * Example: renderText("&lt;html&gt;Hello James&lt;/html&gt;", ContentType.HTML);
+	 */
+	public void renderText(String text, ContentType contentType) {
+		render = renderFactory.getTextRender(text, contentType);
+	}
+	
+	/**
 	 * Forward to an action
 	 */
 	public void forwardAction(String actionUrl) {
@@ -1072,16 +1082,13 @@ public abstract class Controller {
 	public void renderHtml(String htmlText) {
 		render = renderFactory.getHtmlRender(htmlText);
 	}
+	
+	/**
+	 * Render with xml view using freemarker.
+	 */
+	public void renderXml(String view) {
+		render = renderFactory.getXmlRender(view);
+	}
 }
 
 
-
-
-
-
-
-
-
-
-
-

+ 1 - 1
src/com/jfinal/core/InterceptorBuilder.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/JFinal.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 9 - 11
src/com/jfinal/core/JFinalFilter.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -91,19 +91,17 @@ public final class JFinalFilter implements Filter {
 		if (configClass == null)
 			throw new RuntimeException("Please set configClass parameter of JFinalFilter in web.xml");
 		
+		Object temp = null;
 		try {
-			Object temp = Class.forName(configClass).newInstance();
-			if (temp instanceof JFinalConfig)
-				jfinalConfig = (JFinalConfig)temp;
-			else
-				throw new RuntimeException("Can not create instance of class: " + configClass + ". Please check the config in web.xml");
-		} catch (InstantiationException e) {
+			temp = Class.forName(configClass).newInstance();
+		} catch (Exception e) {
 			throw new RuntimeException("Can not create instance of class: " + configClass, e);
-		} catch (IllegalAccessException e) {
-			throw new RuntimeException("Can not create instance of class: " + configClass, e);
-		} catch (ClassNotFoundException e) {
-			throw new RuntimeException("Class not found: " + configClass + ". Please config it in web.xml", e);
 		}
+		
+		if (temp instanceof JFinalConfig)
+			jfinalConfig = (JFinalConfig)temp;
+		else
+			throw new RuntimeException("Can not create instance of class: " + configClass + ". Please check the config in web.xml");
 	}
 	
 	static void initLogger() {

+ 1 - 1
src/com/jfinal/core/ModelInjector.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/core/TypeConverter.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/handler/ContextPathHandler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 12 - 1
src/com/jfinal/ext/handler/FakeStaticHandler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package com.jfinal.ext.handler;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import com.jfinal.handler.Handler;
+import com.jfinal.kit.HandlerKit;
 import com.jfinal.kit.StrKit;
 
 /**
@@ -39,6 +40,16 @@ public class FakeStaticHandler extends Handler {
 	}
 	
 	public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
+		if ("/".equals(target)) {
+			nextHandler.handle(target, request, response, isHandled);
+			return;
+		}
+		
+		if (target.indexOf('.') == -1) {
+			HandlerKit.renderError404(request, response, isHandled);
+			return ;
+		}
+		
 		int index = target.lastIndexOf(viewPostfix);
 		if (index != -1)
 			target = target.substring(0, index);

+ 1 - 1
src/com/jfinal/ext/handler/RoutesHandler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/handler/ServerNameRedirect301Handler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/handler/UrlSkipHandler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/interceptor/GET.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/interceptor/LogInterceptor.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/interceptor/NoUrlPara.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 29 - 0
src/com/jfinal/ext/interceptor/NotAction.java

@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.ext.interceptor;
+
+import com.jfinal.aop.Interceptor;
+import com.jfinal.core.ActionInvocation;
+
+/**
+ * NotAction
+ */
+public class NotAction implements Interceptor {
+	public void intercept(ActionInvocation ai) {
+		ai.getController().renderError(404);
+	}
+}

+ 1 - 1
src/com/jfinal/ext/interceptor/POST.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/interceptor/Restful.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 4 - 1
src/com/jfinal/ext/interceptor/SessionInViewInterceptor.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,6 +44,9 @@ public class SessionInViewInterceptor implements Interceptor {
 		ai.invoke();
 		
 		Controller c = ai.getController();
+		if (c.getRender() instanceof com.jfinal.render.JsonRender)
+			return ;
+		
 		HttpSession hs = c.getSession(createSession);
 		if (hs != null) {
 			Map session = new JFinalSession(hs);

+ 1 - 1
src/com/jfinal/ext/kit/DateKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/ext/kit/SessionIdKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 3 - 4
src/com/jfinal/ext/render/CaptchaRender.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@ import com.jfinal.render.Render;
 
 public class CaptchaRender extends Render {
 	
-	private static final long serialVersionUID = -916701543933591834L;
 	private static final int WIDTH = 85, HEIGHT = 20;
 	private static final String[] strArr = {"3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"};
 	
@@ -91,9 +90,9 @@ public class CaptchaRender extends Render {
 			g.drawLine(x, y, x + xl, y + yl);
 		}
 
-		// 取随机产生的认证码(6位数字)
+		// 取随机产生的认证码(4位数字)
 		String sRand = "";
-		for (int i = 0; i < 6; i++) {
+		for (int i = 0; i < 4; i++) {
 			String rand = String.valueOf(strArr[random.nextInt(strArr.length)]);
 			sRand += rand;
 			// 将认证码显示到图象中

+ 6 - 3
src/com/jfinal/ext/render/StaticHtmlRender.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,9 +23,12 @@ import com.jfinal.render.Render;
  */
 public class StaticHtmlRender extends Render {
 	
-	private static final long serialVersionUID = 1438855188898365097L;
-	
 	public void render() {
 		throw new RuntimeException("Not finish!!!");
 	}
 }
+
+
+
+
+

+ 1 - 1
src/com/jfinal/handler/Handler.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/handler/HandlerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/i18n/I18N.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 64 - 0
src/com/jfinal/kit/EncryptionKit.java

@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.kit;
+
+import java.security.MessageDigest;
+
+public class EncryptionKit {
+	
+	public static String md5Encrypt(String srcStr){
+		return encrypt("MD5", srcStr);
+	}
+	
+	public static String sha1Encrypt(String srcStr){
+		return encrypt("SHA-1", srcStr);
+	}
+	
+	public static String sha256Encrypt(String srcStr){
+		return encrypt("SHA-256", srcStr);
+	}
+	
+	public static String sha384Encrypt(String srcStr){
+		return encrypt("SHA-384", srcStr);
+	}
+	
+	public static String sha512Encrypt(String srcStr){
+		return encrypt("SHA-512", srcStr);
+	}
+	
+	public static String encrypt(String algorithm, String srcStr) {
+		try {
+			StringBuilder result = new StringBuilder();
+			MessageDigest md = MessageDigest.getInstance(algorithm);
+			byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
+			for (byte b :bytes) {
+				String hex = Integer.toHexString(b&0xFF);
+				if (hex.length() == 1)
+					result.append("0");
+				result.append(hex);
+			}
+			return result.toString();
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
+
+
+
+

+ 1 - 1
src/com/jfinal/kit/FileKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 7 - 1
src/com/jfinal/kit/HandlerKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,12 @@ public class HandlerKit {
 		RenderFactory.me().getRender(view).setContext(request, response).render();
 	}
 	
+	public static void renderError404(HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
+		isHandled[0] = true;
+		
+		RenderFactory.me().getErrorRender(404).setContext(request, response).render();
+	}
+	
 	public static void redirect301(String url, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
 		isHandled[0] = true;
 		

+ 263 - 0
src/com/jfinal/kit/HttpKit.java

@@ -0,0 +1,263 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.kit;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * HttpKit
+ */
+public class HttpKit {
+	
+	private HttpKit() {}
+	
+	/**
+	 * https 域名校验
+	 */
+	private class TrustAnyHostnameVerifier implements HostnameVerifier {
+		public boolean verify(String hostname, SSLSession session) {
+			return true;
+		}
+	}
+	
+	/**
+	 * https 证书管理
+	 */
+	private class TrustAnyTrustManager implements X509TrustManager {
+		public X509Certificate[] getAcceptedIssuers() {
+			return null;  
+		}
+		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+		}
+		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+		}
+	}
+	
+	private static final String GET  = "GET";
+	private static final String POST = "POST";
+	private static final String CHARSET = "UTF-8";
+	
+	private static final SSLSocketFactory sslSocketFactory = initSSLSocketFactory();
+	private static final TrustAnyHostnameVerifier trustAnyHostnameVerifier = new HttpKit().new TrustAnyHostnameVerifier();
+	
+	private static SSLSocketFactory initSSLSocketFactory() {
+		try {
+			TrustManager[] tm = {new HttpKit().new TrustAnyTrustManager() };  
+			SSLContext sslContext = SSLContext.getInstance("TLS", "SunJSSE");  
+			sslContext.init(null, tm, new java.security.SecureRandom());  
+			return sslContext.getSocketFactory();
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+	
+	private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
+		URL _url = new URL(url);
+		HttpURLConnection conn = (HttpURLConnection)_url.openConnection();
+		if (conn instanceof HttpsURLConnection) {
+			((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory);
+			((HttpsURLConnection)conn).setHostnameVerifier(trustAnyHostnameVerifier);
+		}
+		
+		conn.setRequestMethod(method);
+		conn.setDoOutput(true);
+		conn.setDoInput(true);
+		
+		conn.setConnectTimeout(19000);
+		conn.setReadTimeout(19000);
+		
+		conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
+		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
+		
+		if (headers != null && !headers.isEmpty())
+			for (Entry<String, String> entry : headers.entrySet())
+				conn.setRequestProperty(entry.getKey(), entry.getValue());
+		
+		return conn;
+	}
+	
+	/**
+	 * Send GET request
+	 */
+	public static String get(String url, Map<String, String> queryParas, Map<String, String> headers) {
+		HttpURLConnection conn = null;
+		try {
+			conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), GET, headers);
+			conn.connect();
+			return readResponseString(conn);
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		finally {
+			if (conn != null) {
+				conn.disconnect();
+			}
+		}
+	}
+	
+	public static String get(String url, Map<String, String> queryParas) {
+		return get(url, queryParas, null);
+	}
+	
+	public static String get(String url) {
+		return get(url, null, null);
+	}
+	
+	/**
+	 * Send POST request
+	 */
+	public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) {
+		HttpURLConnection conn = null;
+		try {
+			conn = getHttpConnection(buildUrlWithQueryString(url, queryParas), POST, headers);
+			conn.connect();
+			
+			OutputStream out = conn.getOutputStream();
+			out.write(data.getBytes(CHARSET));
+			out.flush();
+			out.close();
+			
+			return readResponseString(conn);
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		finally {
+			if (conn != null) {
+				conn.disconnect();
+			}
+		}
+	}
+	
+	public static String post(String url, Map<String, String> queryParas, String data) {
+		return post(url, queryParas, data, null);
+	}
+	
+	public static String post(String url, String data, Map<String, String> headers) {
+		return post(url, null, data, headers);
+	}
+	
+	public static String post(String url, String data) {
+		return post(url, null, data, null);
+	}
+	
+	private static String readResponseString(HttpURLConnection conn) {
+		StringBuilder sb = new StringBuilder();
+		InputStream inputStream = null;
+		try {
+			inputStream = conn.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
+			String line = null;
+			while ((line = reader.readLine()) != null){
+				sb.append(line).append("\n");
+			}
+			return sb.toString();
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		finally {
+			if (inputStream != null) {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Build queryString of the url
+	 */
+	private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
+		if (queryParas == null || queryParas.isEmpty())
+			return url;
+		
+		StringBuilder sb = new StringBuilder(url);
+		boolean isFirst;
+		if (url.indexOf("?") == -1) {
+			isFirst = true;
+			sb.append("?");
+		}
+		else {
+			isFirst = false;
+		}
+		
+		for (Entry<String, String> entry : queryParas.entrySet()) {
+			if (isFirst) isFirst = false;	
+			else sb.append("&");
+			
+			String key = entry.getKey();
+			String value = entry.getValue();
+			if (StrKit.notBlank(value))
+				try {value = URLEncoder.encode(value, CHARSET);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}
+			sb.append(key).append("=").append(value);
+		}
+		return sb.toString();
+	}
+	
+	public static String readIncommingRequestData(HttpServletRequest request) {
+		BufferedReader br = null;
+		try {
+			StringBuilder result = new StringBuilder();
+			br = request.getReader();
+			for (String line=null; (line=br.readLine())!=null;) {
+				result.append(line).append("\n");
+			}
+			
+			return result.toString();
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		finally {
+			if (br != null)
+				try {br.close();} catch (IOException e) {e.printStackTrace();}
+		}
+	}
+}
+
+
+
+
+
+

+ 11 - 4
src/com/jfinal/kit/JsonKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -62,7 +62,7 @@ public class JsonKit {
 		JsonKit.datePattern = datePattern;
 	}
 	
-	public static String mapToJson(Map map, int depth) {
+	private static String mapToJson(Map map, int depth) {
 		if(map == null)
 			return "null";
 		
@@ -97,7 +97,7 @@ public class JsonKit {
 		return sb.toString();
 	}
 	
-	public static String listToJson(List list, int depth) {
+	private static String listToJson(List list, int depth) {
 		if(list == null)
 			return "null";
 		
@@ -255,7 +255,7 @@ public class JsonKit {
 			return listToJson(list, depth);
 		}
 		if (value instanceof Enum) {
-			return "\"" + ((Enum)value).name() + "\"";
+			return "\"" + ((Enum)value).toString() + "\"";
 		}
 		
 		return beanToJson(value, depth);
@@ -299,6 +299,13 @@ public class JsonKit {
 		}
 		return mapToJson(map, depth);
 	}
+	
+	/**
+	 * TODO
+	public static Map jsonToMap(String jsonStr) {
+		throw new RuntimeException("not finished");
+	}
+	*/
 }
 
 

+ 1 - 1
src/com/jfinal/kit/PathKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 154 - 0
src/com/jfinal/kit/Prop.java

@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.kit;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+import com.jfinal.core.Const;
+
+/**
+ * Prop. Prop can load properties file from CLASSPATH or File object.
+ */
+public class Prop {
+	
+	private Properties properties = null;
+	
+	/**
+	 * Prop constructor.
+	 * @see #Prop(String, String)
+	 */
+	public Prop(String fileName) {
+		this(fileName, Const.DEFAULT_ENCODING);
+	}
+	
+	/**
+	 * Prop constructor
+	 * <p>
+	 * Example:<br>
+	 * Prop prop = new Prop("my_config.txt", "UTF-8");<br>
+	 * String userName = prop.get("userName");<br><br>
+	 * 
+	 * prop = new Prop("com/jfinal/file_in_sub_path_of_classpath.txt", "UTF-8");<br>
+	 * String value = prop.get("key");
+	 * 
+	 * @param fileName the properties file's name in classpath or the sub directory of classpath
+	 * @param encoding the encoding
+	 */
+	public Prop(String fileName, String encoding) {
+		InputStream inputStream = null;
+		try {
+			inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);		// properties.load(Prop.class.getResourceAsStream(fileName));
+			if (inputStream == null)
+				throw new IllegalArgumentException("Properties file not found in classpath: " + fileName);
+			properties = new Properties();
+			properties.load(new InputStreamReader(inputStream, encoding));
+		} catch (IOException e) {
+			throw new RuntimeException("Error loading properties file.", e);
+		}
+		finally {
+			if (inputStream != null) try {inputStream.close();} catch (IOException e) {e.printStackTrace();}
+		}
+	}
+	
+	/**
+	 * Prop constructor.
+	 * @see #Prop(File, String)
+	 */
+	public Prop(File file) {
+		this(file, Const.DEFAULT_ENCODING);
+	}
+	
+	/**
+	 * Prop constructor
+	 * <p>
+	 * Example:<br>
+	 * Prop prop = new Prop(new File("/var/config/my_config.txt"), "UTF-8");<br>
+	 * String userName = prop.get("userName");
+	 * 
+	 * @param file the properties File object
+	 * @param encoding the encoding
+	 */
+	public Prop(File file, String encoding) {
+		if (file == null)
+			throw new IllegalArgumentException("File can not be null.");
+		if (file.isFile() == false)
+			throw new IllegalArgumentException("File not found : " + file.getName());
+		
+		InputStream inputStream = null;
+		try {
+			inputStream = new FileInputStream(file);
+			properties = new Properties();
+			properties.load(new InputStreamReader(inputStream, encoding));
+		} catch (IOException e) {
+			throw new RuntimeException("Error loading properties file.", e);
+		}
+		finally {
+			if (inputStream != null) try {inputStream.close();} catch (IOException e) {e.printStackTrace();}
+		}
+	}
+	
+	public String get(String key) {
+		return properties.getProperty(key);
+	}
+	
+	public String get(String key, String defaultValue) {
+		String value = get(key);
+		return (value != null) ? value : defaultValue;
+	}
+	
+	public Integer getInt(String key) {
+		String value = get(key);
+		return (value != null) ? Integer.parseInt(value) : null;
+	}
+	
+	public Integer getInt(String key, Integer defaultValue) {
+		String value = get(key);
+		return (value != null) ? Integer.parseInt(value) : defaultValue;
+	}
+	
+	public Long getLong(String key) {
+		String value = get(key);
+		return (value != null) ? Long.parseLong(value) : null;
+	}
+	
+	public Long getLong(String key, Long defaultValue) {
+		String value = get(key);
+		return (value != null) ? Long.parseLong(value) : defaultValue;
+	}
+	
+	public Boolean getBoolean(String key) {
+		String value = get(key);
+		return (value != null) ? Boolean.parseBoolean(value) : null;
+	}
+	
+	public Boolean getBoolean(String key, Boolean defaultValue) {
+		String value = get(key);
+		return (value != null) ? Boolean.parseBoolean(value) : defaultValue;
+	}
+	
+	public boolean containsKey(String key) {
+		return properties.containsKey(key);
+	}
+	
+	public Properties getProperties() {
+		return properties;
+	}
+}

+ 158 - 0
src/com/jfinal/kit/PropKit.java

@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.kit;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import com.jfinal.core.Const;
+
+/**
+ * PropKit. PropKit can load properties file from CLASSPATH or File object.
+ */
+public class PropKit {
+	
+	private static Prop prop = null;
+	private static final Map<String, Prop> map = new ConcurrentHashMap<String, Prop>();
+	
+	private PropKit() {}
+	
+	/**
+	 * Using the properties file. It will loading the properties file if not loading.
+	 * @see #use(String, String)
+	 */
+	public static Prop use(String fileName) {
+		return use(fileName, Const.DEFAULT_ENCODING);
+	}
+	
+	/**
+	 * Using the properties file. It will loading the properties file if not loading.
+	 * <p>
+	 * Example:<br>
+	 * PropKit.use("config.txt", "UTF-8");<br>
+	 * PropKit.use("other_config.txt", "UTF-8");<br><br>
+	 * String userName = PropKit.get("userName");<br>
+	 * String password = PropKit.get("password");<br><br>
+	 * 
+	 * userName = PropKit.use("other_config.txt").get("userName");<br>
+	 * password = PropKit.use("other_config.txt").get("password");<br><br>
+	 * 
+	 * PropKit.use("com/jfinal/config_in_sub_directory_of_classpath.txt");
+	 * 
+	 * @param fileName the properties file's name in classpath or the sub directory of classpath
+	 * @param encoding the encoding
+	 */
+	public static Prop use(String fileName, String encoding) {
+		Prop result = map.get(fileName);
+		if (result == null) {
+			result = new Prop(fileName, encoding);
+			map.put(fileName, result);
+			if (PropKit.prop == null)
+				PropKit.prop = result;
+		}
+		return result;
+	}
+	
+	/**
+	 * Using the properties file bye File object. It will loading the properties file if not loading.
+	 * @see #use(File, String)
+	 */
+	public static Prop use(File file) {
+		return use(file, Const.DEFAULT_ENCODING);
+	}
+	
+	/**
+	 * Using the properties file bye File object. It will loading the properties file if not loading.
+	 * <p>
+	 * Example:<br>
+	 * PropKit.use(new File("/var/config/my_config.txt"), "UTF-8");<br>
+	 * Strig userName = PropKit.use("my_config.txt").get("userName");
+	 * 
+	 * @param file the properties File object
+	 * @param encoding the encoding
+	 */
+	public static Prop use(File file, String encoding) {
+		Prop result = map.get(file.getName());
+		if (result == null) {
+			result = new Prop(file, encoding);
+			map.put(file.getName(), result);
+			if (PropKit.prop == null)
+				PropKit.prop = result;
+		}
+		return result;
+	}
+	
+	public static Prop useless(String fileName) {
+		Prop previous = map.remove(fileName);
+		if (PropKit.prop == previous)
+			PropKit.prop = null;
+		return previous;
+	}
+	
+	public static void clear() {
+		prop = null;
+		map.clear();
+	}
+	
+	public static Prop getProp() {
+		if (prop == null)
+			throw new IllegalStateException("Load propties file by invoking PropKit.use(String fileName) method first.");
+		return prop;
+	}
+	
+	public static Prop getProp(String fileName) {
+		return map.get(fileName);
+	}
+	
+	public static String get(String key) {
+		return getProp().get(key);
+	}
+	
+	public static String get(String key, String defaultValue) {
+		return getProp().get(key, defaultValue);
+	}
+	
+	public static Integer getInt(String key) {
+		return getProp().getInt(key);
+	}
+	
+	public static Integer getInt(String key, Integer defaultValue) {
+		return getProp().getInt(key, defaultValue);
+	}
+	
+	public static Long getLong(String key) {
+		return getProp().getLong(key);
+	}
+	
+	public static Long getLong(String key, Long defaultValue) {
+		return getProp().getLong(key, defaultValue);
+	}
+	
+	public static Boolean getBoolean(String key) {
+		return getProp().getBoolean(key);
+	}
+	
+	public static Boolean getBoolean(String key, Boolean defaultValue) {
+		return getProp().getBoolean(key, defaultValue);
+	}
+	
+	public static boolean containsKey(String key) {
+		return getProp().containsKey(key);
+	}
+}
+
+

+ 13 - 7
src/com/jfinal/kit/StrKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,9 +25,12 @@ public class StrKit {
 	 * 首字母变小写
 	 */
 	public static String firstCharToLowerCase(String str) {
-		Character firstChar = str.charAt(0);
-		String tail = str.substring(1);
-		str = Character.toLowerCase(firstChar) + tail;
+		char firstChar = str.charAt(0);
+		if (firstChar >= 'A' && firstChar <= 'Z') {
+			char[] arr = str.toCharArray();
+			arr[0] += ('a' - 'A');
+			return new String(arr);
+		}
 		return str;
 	}
 	
@@ -35,9 +38,12 @@ public class StrKit {
 	 * 首字母变大写
 	 */
 	public static String firstCharToUpperCase(String str) {
-		Character firstChar = str.charAt(0);
-		String tail = str.substring(1);
-		str = Character.toUpperCase(firstChar) + tail;
+		char firstChar = str.charAt(0);
+		if (firstChar >= 'a' && firstChar <= 'z') {
+			char[] arr = str.toCharArray();
+			arr[0] -= ('a' - 'A');
+			return new String(arr);
+		}
 		return str;
 	}
 	

+ 1 - 1
src/com/jfinal/kit/StringKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/ILoggerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/JdkLogger.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/JdkLoggerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/Log4jLogger.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/Log4jLoggerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/Logger.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/log/NullLoggerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/IPlugin.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/ActiveRecordException.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/ActiveRecordPlugin.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/CPI.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/CaseInsensitiveContainerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/Config.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 71 - 71
src/com/jfinal/plugin/activerecord/Db.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,10 +26,10 @@ import java.util.List;
 @SuppressWarnings("rawtypes")
 public class Db {
 	
-	private static DbPro pro = null;
+	private static DbPro dbPro = null;
 	
 	static void init() {
-		pro = DbPro.use();
+		dbPro = DbPro.use();
 	}
 	
 	public static DbPro use(String configName) {
@@ -37,14 +37,14 @@ public class Db {
 	}
 	
 	static <T> List<T> query(Config config, Connection conn, String sql, Object... paras) throws SQLException {
-		return pro.query(config, conn, sql, paras);
+		return dbPro.query(config, conn, sql, paras);
 	}
 	
 	/**
 	 * @see #query(String, String, Object...)
 	 */
 	public static <T> List<T> query(String sql, Object... paras) {
-		return pro.query(sql, paras);
+		return dbPro.query(sql, paras);
 	}
 	
 	/**
@@ -52,7 +52,7 @@ public class Db {
 	 * @param sql an SQL statement
 	 */
 	public static <T> List<T> query(String sql) {
-		return pro.query(sql);
+		return dbPro.query(sql);
 	}
 	
 	/**
@@ -63,7 +63,7 @@ public class Db {
 	 * 			and it return Object if your sql has select only one column.
 	 */
 	public static <T> T queryFirst(String sql, Object... paras) {
-		return pro.queryFirst(sql, paras);
+		return dbPro.queryFirst(sql, paras);
 	}
 	
 	/**
@@ -71,7 +71,7 @@ public class Db {
 	 * @param sql an SQL statement
 	 */
 	public static <T> T queryFirst(String sql) {
-		return pro.queryFirst(sql);
+		return dbPro.queryFirst(sql);
 	}
 	
 	// 26 queryXxx method below -----------------------------------------------
@@ -83,107 +83,107 @@ public class Db {
 	 * @return List<T>
 	 */
 	public static <T> T queryColumn(String sql, Object... paras) {
-		return pro.queryColumn(sql, paras);
+		return dbPro.queryColumn(sql, paras);
 	}
 	
 	public static <T> T queryColumn(String sql) {
-		return pro.queryColumn(sql);
+		return dbPro.queryColumn(sql);
 	}
 	
 	public static String queryStr(String sql, Object... paras) {
-		return pro.queryStr(sql, paras);
+		return dbPro.queryStr(sql, paras);
 	}
 	
 	public static String queryStr(String sql) {
-		return pro.queryStr(sql);
+		return dbPro.queryStr(sql);
 	}
 	
 	public static Integer queryInt(String sql, Object... paras) {
-		return pro.queryInt(sql, paras);
+		return dbPro.queryInt(sql, paras);
 	}
 	
 	public static Integer queryInt(String sql) {
-		return pro.queryInt(sql);
+		return dbPro.queryInt(sql);
 	}
 	
 	public static Long queryLong(String sql, Object... paras) {
-		return pro.queryLong(sql, paras);
+		return dbPro.queryLong(sql, paras);
 	}
 	
 	public static Long queryLong(String sql) {
-		return pro.queryLong(sql);
+		return dbPro.queryLong(sql);
 	}
 	
 	public static Double queryDouble(String sql, Object... paras) {
-		return pro.queryDouble(sql, paras);
+		return dbPro.queryDouble(sql, paras);
 	}
 	
 	public static Double queryDouble(String sql) {
-		return pro.queryDouble(sql);
+		return dbPro.queryDouble(sql);
 	}
 	
 	public static Float queryFloat(String sql, Object... paras) {
-		return pro.queryFloat(sql, paras);
+		return dbPro.queryFloat(sql, paras);
 	}
 	
 	public static Float queryFloat(String sql) {
-		return pro.queryFloat(sql);
+		return dbPro.queryFloat(sql);
 	}
 	
 	public static java.math.BigDecimal queryBigDecimal(String sql, Object... paras) {
-		return pro.queryBigDecimal(sql, paras);
+		return dbPro.queryBigDecimal(sql, paras);
 	}
 	
 	public static java.math.BigDecimal queryBigDecimal(String sql) {
-		return pro.queryBigDecimal(sql);
+		return dbPro.queryBigDecimal(sql);
 	}
 	
 	public static byte[] queryBytes(String sql, Object... paras) {
-		return pro.queryBytes(sql, paras);
+		return dbPro.queryBytes(sql, paras);
 	}
 	
 	public static byte[] queryBytes(String sql) {
-		return pro.queryBytes(sql);
+		return dbPro.queryBytes(sql);
 	}
 	
 	public static java.util.Date queryDate(String sql, Object... paras) {
-		return pro.queryDate(sql, paras);
+		return dbPro.queryDate(sql, paras);
 	}
 	
 	public static java.util.Date queryDate(String sql) {
-		return pro.queryDate(sql);
+		return dbPro.queryDate(sql);
 	}
 	
 	public static java.sql.Time queryTime(String sql, Object... paras) {
-		return pro.queryTime(sql, paras);
+		return dbPro.queryTime(sql, paras);
 	}
 	
 	public static java.sql.Time queryTime(String sql) {
-		return pro.queryTime(sql);
+		return dbPro.queryTime(sql);
 	}
 	
 	public static java.sql.Timestamp queryTimestamp(String sql, Object... paras) {
-		return pro.queryTimestamp(sql, paras);
+		return dbPro.queryTimestamp(sql, paras);
 	}
 	
 	public static java.sql.Timestamp queryTimestamp(String sql) {
-		return pro.queryTimestamp(sql);
+		return dbPro.queryTimestamp(sql);
 	}
 	
 	public static Boolean queryBoolean(String sql, Object... paras) {
-		return pro.queryBoolean(sql, paras);
+		return dbPro.queryBoolean(sql, paras);
 	}
 	
 	public static Boolean queryBoolean(String sql) {
-		return pro.queryBoolean(sql);
+		return dbPro.queryBoolean(sql);
 	}
 	
 	public static Number queryNumber(String sql, Object... paras) {
-		return pro.queryNumber(sql, paras);
+		return dbPro.queryNumber(sql, paras);
 	}
 	
 	public static Number queryNumber(String sql) {
-		return pro.queryNumber(sql);
+		return dbPro.queryNumber(sql);
 	}
 	// 26 queryXxx method under -----------------------------------------------
 	
@@ -191,7 +191,7 @@ public class Db {
 	 * Execute sql update
 	 */
 	static int update(Config config, Connection conn, String sql, Object... paras) throws SQLException {
-		return pro.update(config, conn, sql, paras);
+		return dbPro.update(config, conn, sql, paras);
 	}
 	
 	/**
@@ -203,7 +203,7 @@ public class Db {
      *         that return nothing
 	 */
 	public static int update(String sql, Object... paras) {
-		return pro.update(sql, paras);
+		return dbPro.update(sql, paras);
 	}
 	
 	/**
@@ -211,18 +211,18 @@ public class Db {
 	 * @param sql an SQL statement
 	 */
 	public static int update(String sql) {
-		return pro.update(sql);
+		return dbPro.update(sql);
 	}
 	
 	static List<Record> find(Config config, Connection conn, String sql, Object... paras) throws SQLException {
-		return pro.find(config, conn, sql, paras);
+		return dbPro.find(config, conn, sql, paras);
 	}
 	
 	/**
 	 * @see #find(String, String, Object...)
 	 */
 	public static List<Record> find(String sql, Object... paras) {
-		return pro.find(sql, paras);
+		return dbPro.find(sql, paras);
 	}
 	
 	/**
@@ -230,7 +230,7 @@ public class Db {
 	 * @param sql the sql statement
 	 */
 	public static List<Record> find(String sql) {
-		return pro.find(sql);
+		return dbPro.find(sql);
 	}
 	
 	/**
@@ -240,7 +240,7 @@ public class Db {
 	 * @return the Record object
 	 */
 	public static Record findFirst(String sql, Object... paras) {
-		return pro.findFirst(sql, paras);
+		return dbPro.findFirst(sql, paras);
 	}
 	
 	/**
@@ -248,7 +248,7 @@ public class Db {
 	 * @param sql an SQL statement
 	 */
 	public static Record findFirst(String sql) {
-		return pro.findFirst(sql);
+		return dbPro.findFirst(sql);
 	}
 	
 	/**
@@ -258,7 +258,7 @@ public class Db {
 	 * @param idValue the id value of the record
 	 */
 	public static Record findById(String tableName, Object idValue) {
-		return pro.findById(tableName, idValue);
+		return dbPro.findById(tableName, idValue);
 	}
 	
 	/**
@@ -269,7 +269,7 @@ public class Db {
 	 * @param columns the specific columns separate with comma character ==> ","
 	 */
 	public static Record findById(String tableName, Number idValue, String columns) {
-		return pro.findById(tableName, idValue, columns);
+		return dbPro.findById(tableName, idValue, columns);
 	}
 	
 	/**
@@ -280,7 +280,7 @@ public class Db {
 	 * @param idValue the id value of the record
 	 */
 	public static Record findById(String tableName, String primaryKey, Number idValue) {
-		return pro.findById(tableName, primaryKey, idValue);
+		return dbPro.findById(tableName, primaryKey, idValue);
 	}
 	
 	/**
@@ -292,7 +292,7 @@ public class Db {
 	 * @param columns the specific columns separate with comma character ==> ","
 	 */
 	public static Record findById(String tableName, String primaryKey, Object idValue, String columns) {
-		return pro.findById(tableName, primaryKey, idValue, columns);
+		return dbPro.findById(tableName, primaryKey, idValue, columns);
 	}
 	
 	/**
@@ -303,7 +303,7 @@ public class Db {
 	 * @return true if delete succeed otherwise false
 	 */
 	public static boolean deleteById(String tableName, Object id) {
-		return pro.deleteById(tableName, id);
+		return dbPro.deleteById(tableName, id);
 	}
 	
 	/**
@@ -315,7 +315,7 @@ public class Db {
 	 * @return true if delete succeed otherwise false
 	 */
 	public static boolean deleteById(String tableName, String primaryKey, Object id) {
-		return pro.deleteById(tableName, primaryKey, id);
+		return dbPro.deleteById(tableName, primaryKey, id);
 	}
 	
 	/**
@@ -327,7 +327,7 @@ public class Db {
 	 * @return true if delete succeed otherwise false
 	 */
 	public static boolean delete(String tableName, String primaryKey, Record record) {
-		return pro.delete(tableName, primaryKey, record);
+		return dbPro.delete(tableName, primaryKey, record);
 	}
 	
 	/**
@@ -335,29 +335,29 @@ public class Db {
 	 * @see #delete(String, String, Record)
 	 */
 	public static boolean delete(String tableName, Record record) {
-		return pro.delete(tableName, record);
+		return dbPro.delete(tableName, record);
 	}
 	
 	static Page<Record> paginate(Config config, Connection conn, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) throws SQLException {
-		return pro.paginate(config, conn, pageNumber, pageSize, select, sqlExceptSelect, paras);
+		return dbPro.paginate(config, conn, pageNumber, pageSize, select, sqlExceptSelect, paras);
 	}
 	
 	/**
 	 * @see #paginate(String, int, int, String, String, Object...)
 	 */
 	public static Page<Record> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) {
-		return pro.paginate(pageNumber, pageSize, select, sqlExceptSelect, paras);
+		return dbPro.paginate(pageNumber, pageSize, select, sqlExceptSelect, paras);
 	}
 	
 	/**
 	 * @see #paginate(String, int, int, String, String, Object...)
 	 */
 	public static Page<Record> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect) {
-		return pro.paginate(pageNumber, pageSize, select, sqlExceptSelect);
+		return dbPro.paginate(pageNumber, pageSize, select, sqlExceptSelect);
 	}
 	
 	static boolean save(Config config, Connection conn, String tableName, String primaryKey, Record record) throws SQLException {
-		return pro.save(config, conn, tableName, primaryKey, record);
+		return dbPro.save(config, conn, tableName, primaryKey, record);
 	}
 	
 	/**
@@ -368,18 +368,18 @@ public class Db {
 	 * @param true if save succeed otherwise false
 	 */
 	public static boolean save(String tableName, String primaryKey, Record record) {
-		return pro.save(tableName, primaryKey, record);
+		return dbPro.save(tableName, primaryKey, record);
 	}
 	
 	/**
 	 * @see #save(String, String, Record)
 	 */
 	public static boolean save(String tableName, Record record) {
-		return pro.save(tableName, record);
+		return dbPro.save(tableName, record);
 	}
 	
 	static boolean update(Config config, Connection conn, String tableName, String primaryKey, Record record) throws SQLException {
-		return pro.update(config, conn, tableName, primaryKey, record);
+		return dbPro.update(config, conn, tableName, primaryKey, record);
 	}
 	
 	/**
@@ -390,7 +390,7 @@ public class Db {
 	 * @param true if update succeed otherwise false
 	 */
 	public static boolean update(String tableName, String primaryKey, Record record) {
-		return pro.update(tableName, primaryKey, record);
+		return dbPro.update(tableName, primaryKey, record);
 	}
 	
 	/**
@@ -398,14 +398,14 @@ public class Db {
 	 * @see #update(String, String, Record)
 	 */
 	public static boolean update(String tableName, Record record) {
-		return pro.update(tableName, record);
+		return dbPro.update(tableName, record);
 	}
 	
 	/**
 	 * @see #execute(String, ICallback)
 	 */
 	public static Object execute(ICallback callback) {
-		return pro.execute(callback);
+		return dbPro.execute(callback);
 	}
 	
 	/**
@@ -414,7 +414,7 @@ public class Db {
 	 * @param callback the ICallback interface
 	 */
 	static Object execute(Config config, ICallback callback) {
-		return pro.execute(config, callback);
+		return dbPro.execute(config, callback);
 	}
 	
 	/**
@@ -425,11 +425,11 @@ public class Db {
 	 * @return true if transaction executing succeed otherwise false
 	 */
 	static boolean tx(Config config, int transactionLevel, IAtom atom) {
-		return pro.tx(config, transactionLevel, atom);
+		return dbPro.tx(config, transactionLevel, atom);
 	}
 	
 	public static boolean tx(int transactionLevel, IAtom atom) {
-		return pro.tx(transactionLevel, atom);
+		return dbPro.tx(transactionLevel, atom);
 	}
 	
 	/**
@@ -437,7 +437,7 @@ public class Db {
 	 * @see #tx(int, IAtom)
 	 */
 	public static boolean tx(IAtom atom) {
-		return pro.tx(atom);
+		return dbPro.tx(atom);
 	}
 	
 	/**
@@ -448,14 +448,14 @@ public class Db {
 	 * @return the list of Record
 	 */
 	public static List<Record> findByCache(String cacheName, Object key, String sql, Object... paras) {
-		return pro.findByCache(cacheName, key, sql, paras);
+		return dbPro.findByCache(cacheName, key, sql, paras);
 	}
 	
 	/**
 	 * @see #findByCache(String, Object, String, Object...)
 	 */
 	public static List<Record> findByCache(String cacheName, Object key, String sql) {
-		return pro.findByCache(cacheName, key, sql);
+		return dbPro.findByCache(cacheName, key, sql);
 	}
 	
 	/**
@@ -464,35 +464,35 @@ public class Db {
 	 * @return Page
 	 */
 	public static Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras) {
-		return pro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect, paras);
+		return dbPro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect, paras);
 	}
 	
 	/**
 	 * @see #paginateByCache(String, Object, int, int, String, String, Object...)
 	 */
 	public static Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect) {
-		return pro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect);
+		return dbPro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect);
 	}
 	
 	/**
 	 * @see #batch(String, String, Object[][], int)
      */
     public static int[] batch(String sql, Object[][] paras, int batchSize) {
-    	return pro.batch(sql, paras, batchSize);
+    	return dbPro.batch(sql, paras, batchSize);
     }
 	
 	/**
 	 * @see #batch(String, String, String, List, int)
      */
 	public static int[] batch(String sql, String columns, List modelOrRecordList, int batchSize) {
-		return pro.batch(sql, columns, modelOrRecordList, batchSize);
+		return dbPro.batch(sql, columns, modelOrRecordList, batchSize);
 	}
 	
 	/**
 	 * @see #batch(String, List, int)
      */
     public static int[] batch(List<String> sqlList, int batchSize) {
-    	return pro.batch(sqlList, batchSize);
+    	return dbPro.batch(sqlList, batchSize);
     }
 }
 

+ 1 - 1
src/com/jfinal/plugin/activerecord/DbKit.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 22 - 10
src/com/jfinal/plugin/activerecord/DbPro.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -603,7 +603,7 @@ public class DbPro {
 		Connection conn = null;
 		try {
 			conn = config.getConnection();
-			return callback.run(conn);
+			return callback.call(conn);
 		} catch (Exception e) {
 			throw new ActiveRecordException(e);
 		} finally {
@@ -650,9 +650,9 @@ public class DbPro {
 		} catch (NestedTransactionHelpException e) {
 			if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
 			return false;
-		} catch (Exception e) {
+		} catch (Throwable t) {
 			if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
-			throw e instanceof RuntimeException ? (RuntimeException)e : new ActiveRecordException(e);
+			throw t instanceof RuntimeException ? (RuntimeException)t : new ActiveRecordException(t);
 		} finally {
 			try {
 				if (conn != null) {
@@ -660,8 +660,8 @@ public class DbPro {
 						conn.setAutoCommit(autoCommit);
 					conn.close();
 				}
-			} catch (Exception e) {
-				e.printStackTrace();	// can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
+			} catch (Throwable t) {
+				t.printStackTrace();	// can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
 			} finally {
 				config.removeThreadLocalConnection();	// prevent memory leak
 			}
@@ -738,8 +738,14 @@ public class DbPro {
 		for (int i=0; i<paras.length; i++) {
 			for (int j=0; j<paras[i].length; j++) {
 				Object value = paras[i][j];
-				if (config.dialect.isOracle() && value instanceof java.sql.Date)
-					pst.setDate(j + 1, (java.sql.Date)value);
+				if (config.dialect.isOracle()) {
+					if (value instanceof java.sql.Date)
+						pst.setDate(j + 1, (java.sql.Date)value);
+					else if (value instanceof java.sql.Timestamp)
+						pst.setTimestamp(j + 1, (java.sql.Timestamp)value);
+					else
+						pst.setObject(j + 1, value);
+				}
 				else
 					pst.setObject(j + 1, value);
 			}
@@ -812,8 +818,14 @@ public class DbPro {
 			Map map = isModel ? ((Model)list.get(i)).getAttrs() : ((Record)list.get(i)).getColumns();
 			for (int j=0; j<columnArray.length; j++) {
 				Object value = map.get(columnArray[j]);
-				if (config.dialect.isOracle() && value instanceof java.sql.Date)
-					pst.setDate(j + 1, (java.sql.Date)value);
+				if (config.dialect.isOracle()) {
+					if (value instanceof java.sql.Date)
+						pst.setDate(j + 1, (java.sql.Date)value);
+					else if (value instanceof java.sql.Timestamp)
+						pst.setTimestamp(j + 1, (java.sql.Timestamp)value);
+					else
+						pst.setObject(j + 1, value);
+				}
 				else
 					pst.setObject(j + 1, value);
 			}

+ 1 - 1
src/com/jfinal/plugin/activerecord/IAtom.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 2 - 2
src/com/jfinal/plugin/activerecord/ICallback.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,5 +28,5 @@ public interface ICallback {
 	 * Place codes here that need call back by active record plugin.
 	 * @param conn the JDBC Connection, you need't close this connection after used it, active record plugin will close it automatically
 	 */
-	Object run(Connection conn) throws SQLException;
+	Object call(Connection conn) throws SQLException;
 }

+ 1 - 1
src/com/jfinal/plugin/activerecord/IContainerFactory.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/IDataSourceProvider.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/Model.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/ModelBuilder.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 124 - 0
src/com/jfinal/plugin/activerecord/ModelRecordElResolver.java

@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.plugin.activerecord;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+
+/**
+ * ModelRecordElResolver
+ */
+@SuppressWarnings("rawtypes")
+public class ModelRecordElResolver extends ELResolver {
+	
+	/**
+	 * Compatible for JspRender.setSupportActiveRecord(true);
+	 * Delete it in the future
+	 */
+	private static boolean isWorking = true;
+	
+	public static void setWorking(boolean isWorking) {
+		ModelRecordElResolver.isWorking = isWorking;
+	}
+	
+	public static void init(ServletContext servletContext) {
+	    JspApplicationContext jspApplicationContext = JspFactory.getDefaultFactory().getJspApplicationContext(servletContext);
+	    jspApplicationContext.addELResolver(new ModelRecordElResolver());
+	}
+	
+	public static void init() {
+		init(com.jfinal.core.JFinal.me().getServletContext());
+	}
+	
+	public Object getValue(ELContext context, Object base, Object property) {
+		if (isWorking == false)	return null;
+		
+		if (base instanceof Model) {
+			context.setPropertyResolved(true);
+			if (property == null)
+				return null;
+			return ((Model)base).get(property.toString());
+		}
+		else if (base instanceof Record) {
+			context.setPropertyResolved(true);
+			if (property == null)
+				return null;
+			return ((Record)base).get(property.toString());
+		}
+		return null;
+	}
+	
+	public Class<?> getType(ELContext context, Object base, Object property) {
+		if (isWorking == false)	return null;
+		
+		// return null;
+		return (base == null) ? null : Object.class;
+	}
+	
+	public void setValue(ELContext context, Object base, Object property, Object value) {
+		if (isWorking == false)	return ;
+		
+		if (base instanceof Model) {
+			context.setPropertyResolved(true);
+			if (property == null)
+				return ;
+			try {
+				((Model)base).set(property.toString(), value);
+			} catch (Exception e) {
+				((Model)base).put(property.toString(), value);
+			}
+		}
+		else if (base instanceof Record) {
+			context.setPropertyResolved(true);
+			if (property == null)
+				return ;
+			((Record)base).set(property.toString(), value);
+		}
+	}
+	
+	public boolean isReadOnly(ELContext context, Object base, Object property) {
+		if (isWorking == false)	return false;
+		
+		if (base instanceof Model || base instanceof Record) {
+			context.setPropertyResolved(true);
+			return false;
+		}
+		return false;
+	}
+	
+	// Do not invoke context.setPropertyResolved(true) for this method
+	public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+		return null;
+	}
+	
+	// Do not invoke context.setPropertyResolved(true) for this method
+	public Class<?> getCommonPropertyType(ELContext context, Object base) {
+		if (isWorking == false)	return null;
+		
+		if (base instanceof Model || base instanceof Record)
+			return String.class;
+		return null;
+	}
+}
+
+
+

+ 1 - 1
src/com/jfinal/plugin/activerecord/NestedTransactionHelpException.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/OneConnectionPerThread.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 38 - 0
src/com/jfinal/plugin/activerecord/OrderedFieldContainerFactory.java

@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
+ *
+ * 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 com.jfinal.plugin.activerecord;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class OrderedFieldContainerFactory implements IContainerFactory {
+	
+	public Map<String, Object> getAttrsMap() {
+		return new LinkedHashMap();
+	}
+	
+	public Map<String, Object> getColumnsMap() {
+		return new LinkedHashMap();
+	}
+	
+	public Set<String> getModifyFlagSet() {
+		return new HashSet();
+	}
+}

+ 1 - 1
src/com/jfinal/plugin/activerecord/Page.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/Record.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/RecordBuilder.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/SqlReporter.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 10 - 2
src/com/jfinal/plugin/activerecord/Table.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 
 package com.jfinal.plugin.activerecord;
 
+import java.util.Collections;
 import java.util.Map;
 import com.jfinal.kit.StrKit;
 
@@ -56,6 +57,9 @@ public class Table {
 	
 	void setPrimaryKey(String primaryKey) {
 		String[] keyArr = primaryKey.split(",");
+		if (keyArr.length > 2)
+			throw new IllegalArgumentException("Supports only two primary key for Composite primary key.");
+		
 		if (keyArr.length > 1) {
 			if (StrKit.isBlank(keyArr[0]) || StrKit.isBlank(keyArr[1]))
 				throw new IllegalArgumentException("The composite primary key can not be blank.");
@@ -78,7 +82,7 @@ public class Table {
 		return name;
 	}
 	
-	public void setColumnType(String columnLabel, Class<?> columnType) {
+	void setColumnType(String columnLabel, Class<?> columnType) {
 		columnTypeMap.put(columnLabel, columnType);
 	}
 	
@@ -108,6 +112,10 @@ public class Table {
 	public Class<? extends Model<?>> getModelClass() {
 		return modelClass;
 	}
+	
+	public Map<String, Class<?>> getColumnTypeMap() {
+		return Collections.unmodifiableMap(columnTypeMap);
+	}
 }
 
 

+ 1 - 1
src/com/jfinal/plugin/activerecord/TableBuilder.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/TableMapping.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/cache/EhCache.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
src/com/jfinal/plugin/activerecord/cache/ICache.java

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2011-2014, James Zhan 詹波 (jfinal@126.com).
+ * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com).
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 0 - 0
src/com/jfinal/plugin/activerecord/dialect/AnsiSqlDialect.java


部分文件因为文件数量过多而无法显示