diff --git a/group04/821655640/learning_projects/project_basic_001/pom.xml b/group04/821655640/learning_projects/project_basic_001/pom.xml
index 6675a5d76d..1f93bf44e0 100644
--- a/group04/821655640/learning_projects/project_basic_001/pom.xml
+++ b/group04/821655640/learning_projects/project_basic_001/pom.xml
@@ -19,7 +19,13 @@
junit
junit
4.10
- test
+
+
+ jaxen
+ jaxen
+ 1.1-beta-7
+
+
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/array/ArrayUtil.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..6b5b877a7b
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,228 @@
+package com.coderising.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class ArrayUtil {
+
+ /**
+ * 给定一个整形数组a , 对该数组的值进行置换
+ 例如: a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7]
+ 如果 a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+ * @param origin
+ * @return
+ * 11 01 11|
+ */
+ public void reverseArray(int[] origin){
+ int len = origin.length-1;
+
+ for (int i = 0; i <((0 == len%2) ? len/2 :(len+1)/2) ; i++) {
+ origin[i] = origin[i]^origin[len-i];
+ origin[len-i] = origin[len-i]^origin[i];
+ origin[i] = origin[i]^origin[len-i];
+ }
+ }
+
+ /**
+ * 现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+ * 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为:
+ * {1,3,4,5,6,6,5,4,7,6,7,5}
+ * @param oldArray
+ * @return
+ */
+
+ public int[] removeZero(int[] oldArray){
+ //get count
+ int count = 0;
+ for (int i : oldArray) {
+ if(0 != i) {
+ count++;
+ }
+ }
+
+ //remove zero
+ int newArray[] = new int[count];
+ int j=0;
+ for (int i : oldArray) {
+ if(0 != i) {
+ newArray[j++] = i;
+ }
+ }
+ return newArray;
+ }
+
+ /**
+ * 给定两个已经排序好的整形数组, a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素, 并且仍然是有序的
+ * 例如 a1 = [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意: 已经消除了重复
+ * @param array1
+ * @param array2
+ * @return
+ */
+
+ public Integer[] merge(int[] array1, int[] array2){
+
+ if (null==array1 || null == array2 || 0 == array1.length || 0 == array2.length) {
+ new IllegalArgumentException("参数不允许为空数组!");
+ }
+
+ int i=0,j=0;
+ ArrayList mergedList = new ArrayList();
+ while (true) {
+ if (j == array2.length-1 || i == array1.length-1) {
+ break;
+ }
+ if (array1[i] < array2[j]) {
+ mergedList.add(array1[i]);
+ i++;
+ }else if (array1[i] > array2[j]) {
+ mergedList.add(array2[j]);
+ j++;
+ }else {
+ mergedList.add(array2[j]);
+ i++;
+ j++;
+ }
+
+ }
+
+ //put the least part of one array into list
+ if (i == array1.length) {
+ for (int k = j; k < array2.length; k++) {
+ mergedList.add(array2[k]);
+ }
+ }else {
+ for (int k = i; k < array1.length; k++) {
+ mergedList.add(array1[k]);
+ }
+ }
+
+ return arrayListToInteger(mergedList);
+ }
+
+ private Integer[] arrayListToInteger(ArrayList arrayList) {
+ Integer tempArray[] = new Integer[arrayList.size()];
+ int i=0;
+ for (Integer integer : arrayList) {
+ tempArray[i++] = integer;
+ }
+
+ return tempArray;
+ }
+ /**
+ * 把一个已经存满数据的数组 oldArray的容量进行扩展, 扩展后的新数据大小为oldArray.length + size
+ * 注意,老数组的元素在新数组中需要保持
+ * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+ * [2,3,6,0,0,0]
+ * @param oldArray
+ * @param size
+ * @return
+ */
+ public int[] grow(int [] oldArray, int size){
+
+ if (null == oldArray || size<= 0) {
+ new IllegalArgumentException("数组为空或者长度非法!!");
+ }
+
+ int newArray[] = new int[oldArray.length + size];
+ System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
+ return newArray;
+ }
+
+ /**
+ * 斐波那契数列为:1,1,2,3,5,8,13,21...... ,给定一个最大值, 返回小于该值的数列
+ * 例如, max = 15 , 则返回的数组应该为 [1,1,2,3,5,8,13]
+ * max = 1, 则返回空数组 []
+ * @param max
+ * @return
+ */
+ public Integer[] fibonacci(int max){
+ if ( 1 == max ) {
+ return new Integer[0];
+ }
+ ArrayList arrayList = new ArrayList();
+ arrayList.add(1);
+ arrayList.add(1);
+
+ int i=0,j=1;
+ while (arrayList.get(i)+arrayList.get(j) < max) {
+ arrayList.add(arrayList.get(i)+arrayList.get(j));
+ i++;
+ j++;
+ }
+
+ return arrayListToInteger(arrayList);
+ }
+
+ /**
+ * 返回小于给定最大值max的所有素数数组
+ * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+ * @param max
+ * @return
+ */
+ public Integer[] getPrimes(int max){
+ ArrayList arrayList = new ArrayList();
+ boolean isPrimes = true;
+ for (int i = 2; i < max; i++) {
+ isPrimes = true;
+ for (int j = 2; j <= Math.sqrt(i) ; j++) {
+ if (0 == i % j) {
+ isPrimes = false;
+ break;
+ }
+ }
+
+ if (isPrimes) {
+ arrayList.add(i);
+ }
+
+ }
+ return arrayListToInteger(arrayList);
+ }
+
+ /**
+ * 所谓“完数”, 是指这个数恰好等于它的因子之和,例如6=1+2+3
+ * 给定一个最大值max, 返回一个数组, 数组中是小于max 的所有完数
+ * @param max
+ * @return
+ */
+ public Integer[] getPerfectNumbers(int max){
+ ArrayList arrayList = new ArrayList();
+ int sum = 0;
+ for (int i = 2; i < max; i++) {
+ sum = 0;
+ //the factor is less than half of a number
+ for (int j = 1; j <= (i+1)/2; j++) {
+ if (0 == i%j) {
+ sum += j;
+ }
+ }
+
+ if (sum == i) {
+ arrayList.add(i);
+ }
+ }
+ return arrayListToInteger(arrayList);
+ }
+
+ /**
+ * 用seperator 把数组 array给连接起来
+ * 例如array= [3,8,9], seperator = "-"
+ * 则返回值为"3-8-9"
+ * @param array
+ * @param s
+ * @return
+ */
+ public String join(int[] array, String seperator){
+ StringBuilder sb = new StringBuilder();
+ for (int i : array) {
+ sb.append(i).append(seperator);
+ }
+
+ sb.deleteCharAt(sb.length()-1);
+ return sb.toString();
+ }
+
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/LoginAction.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..1005f35a29
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类, 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+ private String name ;
+ private String password;
+ private String message;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String execute(){
+ if("test".equals(name) && "1234".equals(password)){
+ this.message = "login successful";
+ return "success";
+ }
+ this.message = "login failed,please check your user/pwd";
+ return "fail";
+ }
+
+ public void setName(String name){
+ this.name = name;
+ }
+ public void setPassword(String password){
+ this.password = password;
+ }
+ public String getMessage(){
+ return this.message;
+ }
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/Struts.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..544f5ac082
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/Struts.java
@@ -0,0 +1,86 @@
+package com.coderising.litestruts;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+
+
+
+public class Struts {
+
+ public static View runAction(String actionName, Map parameters) {
+
+
+ //0. 读取配置文件struts.xml
+ Document xmlDoc = null;
+ View view = null;
+ try {
+ xmlDoc = getXMLDocument("./src/main/java/com/coderising/litestruts/struts.xml");
+
+ /*1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象)
+ 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是
+ ("name"="test" , "password"="1234") ,
+ 那就应该调用 setName和setPassword方法*/
+
+ String classStr = xmlDoc.selectSingleNode("struts/action[@name='"+actionName+"']/@class").getText();
+ Class> actionClass = Class.forName(classStr);
+ Object action = actionClass.newInstance();
+
+ Iterator> itr = parameters.entrySet().iterator();
+ Entry entry = null;
+ String key = "";
+ String value = "";
+ while(itr.hasNext()) {
+ entry = itr.next();
+ key = entry.getKey();
+ value = entry.getValue();
+ Method setter = actionClass.getMethod("set"+key.substring(0, 1).toUpperCase()+key.substring(1),String.class);
+ setter.invoke(action, value);
+ }
+
+
+ // 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success"
+ Method exeMethod = actionClass.getMethod("execute");
+ String result = exeMethod.invoke(action).toString();
+// System.out.println(result);
+
+ /*3. 通过反射找到对象的所有getter方法(例如 getMessage),
+ 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+ 放到View对象的parameters*/
+
+ Map viewDataMap = new HashMap();
+ String methodName = "";
+ for (Method md : actionClass.getMethods()) {
+ methodName = md.getName();
+ if (methodName.startsWith("get")) {
+ viewDataMap.put(methodName.substring(3, 4).toLowerCase()+methodName.substring(4), md.invoke(action).toString());
+ }
+ }
+
+// System.out.println(viewDataMap);
+
+ /**
+ 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp,
+ 放到View对象的jsp字段中。
+ */
+ String jspRet = xmlDoc.selectSingleNode("struts/action[@name='"+actionName+"']/result[@name='"+result+"']").getText();
+ view = new View();
+ view.setJsp(jspRet);
+ view.setParameters(viewDataMap);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return view;
+ }
+
+ private static Document getXMLDocument(String filePath) throws DocumentException {
+ return new SAXReader().read(filePath);
+ }
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/View.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..0194c681f6
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+ private String jsp;
+ private Map parameters;
+
+ public String getJsp() {
+ return jsp;
+ }
+ public View setJsp(String jsp) {
+ this.jsp = jsp;
+ return this;
+ }
+ public Map getParameters() {
+ return parameters;
+ }
+ public View setParameters(Map parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/struts.xml b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/struts.xml
new file mode 100644
index 0000000000..867faed126
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/litestruts/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+ /jsp/homepage.jsp
+ /jsp/showLogin.jsp
+
+
+ /jsp/welcome.jsp
+ /jsp/error.jsp
+
+
\ No newline at end of file
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/sunline/project_basic_001/App.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/sunline/project_basic_001/App.java
deleted file mode 100644
index 48b5e72dc2..0000000000
--- a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/sunline/project_basic_001/App.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.sunline.project_basic_001;
-
-import javax.swing.tree.TreeNode;
-
-
-/**
- * Hello world!
- *
- */
-public class App {
- public static void main(String[] args) {
- System.out.println("Hello World!");
- TreeNode a;
- }
-}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/array/ArrayUtilTest.java b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/array/ArrayUtilTest.java
new file mode 100644
index 0000000000..66ea66f645
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/array/ArrayUtilTest.java
@@ -0,0 +1,85 @@
+package com.coderising.array;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ArrayUtilTest {
+ ArrayUtil arrayUtil = null;
+ @Before
+ public void setUp() {
+ arrayUtil = new ArrayUtil();
+ }
+
+ @Test
+ public void testReverseArray() {
+ int origin[] = {7, 9, 30, 3, 4};
+ int expecteds[] = {4,3, 30 , 9,7};
+ arrayUtil.reverseArray(origin);
+
+ Assert.assertArrayEquals(expecteds, origin);
+ }
+
+ @Test
+ public void testRemoveZero() {
+ int oldArray[] = {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
+ int expecteds[] = {1,3,4,5,6,6,5,4,7,6,7,5};
+ int newArray[] = arrayUtil.removeZero(oldArray);
+
+ Assert.assertArrayEquals(expecteds, newArray);
+ }
+
+ @Test
+ public void testMerge() {
+ int array1[] = {3, 5, 7,8};
+ int array2[] = {4, 5, 6,7};
+ Integer expecteds[] = {3,4,5,6,7,8};
+ Integer newArray[] = arrayUtil.merge(array1, array2);
+ Assert.assertArrayEquals(expecteds, newArray);
+ }
+
+ @Test
+ public void testGrow() {
+ int oldArray[] = {2,3,6};
+ int expecteds[] = {2,3,6,0,0,0};
+ int newArray[] = arrayUtil.grow(oldArray,3);
+
+ Assert.assertArrayEquals(expecteds, newArray);
+ }
+
+ @Test
+ public void testFibonacci() {
+ Integer expecteds[] = {1,1,2,3,5,8,13};
+ Integer newArray[] = arrayUtil.fibonacci(18);
+
+ Assert.assertArrayEquals(arrayUtil.fibonacci(1), new Integer[0]);
+ Assert.assertArrayEquals(expecteds, newArray);
+ }
+
+ @Test
+ public void testGetPrimes() {
+ Integer expecteds[] = {2,3,5,7,11,13,17,19};
+ Integer newArray[] = arrayUtil.getPrimes(23);
+
+ Assert.assertArrayEquals(expecteds, newArray);
+ }
+
+ @Test
+ public void testGetPerfectNumbers() {
+ Integer array[] = arrayUtil.getPerfectNumbers(100);
+ System.out.println(Arrays.toString(array));
+ }
+
+ @Test
+ public void testJoin() {
+ int dealedArray[] = {3,8,9};
+ String expectedStr = "3-8-9";
+ String resultStr = arrayUtil.join(dealedArray, "-");
+ Assert.assertEquals("", expectedStr, resultStr);
+ }
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/litestruts/StrutsTest.java b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..760a991195
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,41 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class StrutsTest {
+
+ @Test
+ public void testLoginActionSuccess() {
+
+ String actionName = "login";
+
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","1234");
+
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+ Assert.assertEquals("login successful", view.getParameters().get("message"));
+ }
+
+ @Test
+ public void testLoginActionFailed() {
+ String actionName = "login";
+ Map params = new HashMap();
+ params.put("name","test");
+ params.put("password","123456"); //密码和预设的不一致
+
+ View view = Struts.runAction(actionName,params);
+
+ Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+ Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+ }
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/sunline/project_basic_001/AppTest.java b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/sunline/project_basic_001/AppTest.java
deleted file mode 100644
index 57fc7ea596..0000000000
--- a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/sunline/project_basic_001/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.sunline.project_basic_001;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}