From 21020a1a0263905cbc97bbb709cd91ef1494e199 Mon Sep 17 00:00:00 2001 From: kilien Date: Sat, 25 Mar 2017 16:22:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coderising/download/DownloadThread.java | 56 ++-- .../coderising/download/FileDownloader.java | 163 +++++------ .../download/FileDownloaderTest.java | 26 +- .../coderising/download/api/Connection.java | 20 +- .../download/api/ConnectionException.java | 4 +- .../download/api/ConnectionManager.java | 9 +- .../download/api/DownloadListener.java | 4 +- .../download/impl/ConnectionImpl.java | 77 ++--- .../download/impl/ConnectionManagerImpl.java | 36 +-- .../com/coderising/linkedlist/Iterator.java | 7 + .../com/coderising/linkedlist/LinkedList.java | 263 ++++++++++++++++++ .../coderising/linkedlist/LinkedListTest.java | 170 +++++++++++ .../src/com/coderising/linkedlist/List.java | 9 + .../coderising/litestruts/Configuration.java | 113 ++++++++ .../litestruts/ConfigurationException.java | 21 ++ .../litestruts/ConfigurationTest.java | 50 ++++ .../coderising/litestruts/ReflectionUtil.java | 123 ++++++++ .../litestruts/ReflectionUtilTest.java | 113 ++++++++ .../src/com/coderising/litestruts/SAX.java | 30 -- .../com/coderising/litestruts/SAXmain.java | 21 -- .../src/com/coderising/litestruts/Struts.java | 57 +++- 21 files changed, 1116 insertions(+), 256 deletions(-) create mode 100644 group09/790466157/src/com/coderising/linkedlist/Iterator.java create mode 100644 group09/790466157/src/com/coderising/linkedlist/LinkedList.java create mode 100644 group09/790466157/src/com/coderising/linkedlist/LinkedListTest.java create mode 100644 group09/790466157/src/com/coderising/linkedlist/List.java create mode 100644 group09/790466157/src/com/coderising/litestruts/Configuration.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ConfigurationException.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java create mode 100644 group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java delete mode 100644 group09/790466157/src/com/coderising/litestruts/SAX.java delete mode 100644 group09/790466157/src/com/coderising/litestruts/SAXmain.java diff --git a/group09/790466157/src/com/coderising/download/DownloadThread.java b/group09/790466157/src/com/coderising/download/DownloadThread.java index a1f93a1134..efd5f9f70f 100644 --- a/group09/790466157/src/com/coderising/download/DownloadThread.java +++ b/group09/790466157/src/com/coderising/download/DownloadThread.java @@ -1,42 +1,46 @@ package com.coderising.download; - +import com.coderising.download.api.Connection; +import java.io.File; +import java.io.IOException; import java.io.RandomAccessFile; +import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; - -//import org.omg.CORBA.portable.InputStream; - -import com.coderising.download.api.Connection; - public class DownloadThread extends Thread{ Connection conn; int startPos; int endPos; - CyclicBarrier barrier ; - String filePath; + String fileName; + CyclicBarrier barrier; - public DownloadThread(CyclicBarrier barrier , Connection conn, int startPos, int endPos , String filePath){ - - this.barrier = barrier; + public DownloadThread(String name, Connection conn, int startPos, int endPos, String fileName, CyclicBarrier barrier){ + super(name); this.conn = conn; this.startPos = startPos; this.endPos = endPos; - this.filePath = filePath; - } - public void run(){ - try{ - System.out.println("begin download startPos="+startPos+",endPos="+endPos); - byte[] buffer = conn.read(startPos , endPos); - RandomAccessFile file = new RandomAccessFile(filePath, "rw"); - file.seek(startPos); - file.write(buffer, 0, buffer.length); - file.close(); - barrier.await(); - }catch(Exception e){ - System.out.println("download error:startPos="+startPos+",endPos="+endPos); - } + this.fileName = fileName; + this.barrier = barrier; } - + public void run(){ + try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { + raf.seek(startPos); + byte[] buf = conn.read(startPos, endPos); +// String desc = Thread.currentThread().getName()+"startPos:"+startPos+",length:"+length + "buf size:"+buf.length; +// System.out.println(desc); + raf.write(buf, 0, buf.length); + if (null != barrier) { + barrier.await(); + } + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } finally { + conn.close(); + } + } } diff --git a/group09/790466157/src/com/coderising/download/FileDownloader.java b/group09/790466157/src/com/coderising/download/FileDownloader.java index 107e4cc433..9c2a9df7ac 100644 --- a/group09/790466157/src/com/coderising/download/FileDownloader.java +++ b/group09/790466157/src/com/coderising/download/FileDownloader.java @@ -1,104 +1,111 @@ package com.coderising.download; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.concurrent.CyclicBarrier; - import com.coderising.download.api.Connection; import com.coderising.download.api.ConnectionException; import com.coderising.download.api.ConnectionManager; import com.coderising.download.api.DownloadListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + public class FileDownloader { - String url; - - DownloadListener listener; + private String url; + private String fileName; + private DownloadListener listener; + private ConnectionManager cm; + private int threadNum = 5; + private int length = 0; + private Connection conn; - ConnectionManager cm; - - private static final int THREAD_NUM = 3; - - private static final String BASE_PATH = "C:/Users/Liner/Desktop/Document/Doc"; - boolean isFinished = false; - - public FileDownloader(String _url) { + public FileDownloader(String _url, String _fileName) { this.url = _url; - File baseFile = new File(BASE_PATH); - if(!baseFile.exists()){ - baseFile.mkdirs(); - } + this.fileName = _fileName; + } public void execute(){ - - CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM, new Runnable() { - - @Override - public void run() { - listener.notifyFinished(); - } - }); - - Connection conn = null; - try { - - conn = cm.open(this.url); + // 在这里实现你的代码, 注意: 需要用多线程实现下载 + // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码 + // (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定) + // (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有 + // 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。 + // 具体的实现思路: + // 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度 + // 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法 + // 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组 + // 3. 把byte数组写入到文件中 + // 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法 - int length = conn.getContentLength(); - String filePath = BASE_PATH + "download."+getFileType(this.url); - //System.out.println(filePath); - - File file = new File(filePath); - if(!file.exists()){ - try { - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - try{ - FileOutputStream fos = new FileOutputStream(file); - fos.write(new byte[length], 0, length);//占位 - fos.close(); - } - catch (IOException e) { - System.out.println(e.getMessage()); - } + try (RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd")) { + conn = cm.open(this.url); + length = conn.getContentLength(); + raf.setLength(length); + threadPoolDownload(); +// oneThreadDownload(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ConnectionException e) { + e.printStackTrace(); + } - int blockSize = (length % THREAD_NUM == 0 ) ? length / THREAD_NUM : (length / THREAD_NUM + 1); - for (int i = 0; i < THREAD_NUM; i++) { - int startPos = i * blockSize; - int endPos = startPos + blockSize - 1; - if(endPos >= length - 1){ - endPos = length - 1; - } - new DownloadThread(barrier , conn, startPos, endPos , filePath).start(); - } + } - } catch (ConnectionException e) { - System.out.println(e.getMessage()); - } finally{ - if(conn != null){ - conn.close(); - } - } + public void oneThreadDownload() { + final CyclicBarrier barrier = new CyclicBarrier(1 ,new Runnable() { + @Override + public void run() { + getListener().notifyFinished(); + } + }); + try { + Thread thread = new DownloadThread("oneThread", conn,0,length, fileName, barrier); + thread.start(); + } finally { + if (conn != null) { + conn.close(); + } + } + } - } - - private String getFileType(String url) { - int index = url.lastIndexOf("."); - return url.substring(index + 1 , url.length()); - } + public void threadPoolDownload() throws ConnectionException { + final CyclicBarrier barrier = new CyclicBarrier(threadNum ,new Runnable() { + @Override + public void run() { + getListener().notifyFinished(); // 栅栏 + } + }); + ExecutorService threadPool = Executors.newCachedThreadPool(); + int len = conn.getContentLength(); + for(int i = 0; i< threadNum; i++) + { + int start=i*len/ threadNum; + int end = (i+1)*len/ threadNum -1; + conn = cm.open(this.url); + if(i== threadNum -1) + { + end =len; + } + Thread thread = new DownloadThread("thread"+i, conn, start, end, fileName, barrier); + threadPool.execute(thread); + } + if (conn != null) { + conn.close(); + } + } public void setListener(DownloadListener listener) { this.listener = listener; } - - public void setConnectionManager(ConnectionManager ucm){ this.cm = ucm; @@ -108,4 +115,4 @@ public DownloadListener getListener(){ return this.listener; } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/FileDownloaderTest.java b/group09/790466157/src/com/coderising/download/FileDownloaderTest.java index a79d23d9c5..66d6455036 100644 --- a/group09/790466157/src/com/coderising/download/FileDownloaderTest.java +++ b/group09/790466157/src/com/coderising/download/FileDownloaderTest.java @@ -10,6 +10,7 @@ public class FileDownloaderTest { boolean downloadFinished = false; + private double time = 0; @Before public void setUp() throws Exception { } @@ -21,39 +22,34 @@ public void tearDown() throws Exception { @Test public void testDownload() { - String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1488796402240&di=8ca9322617d5338cad61232a06f6ed7a&imgtype=0&src=http%3A%2F%2Fjiangsu.china.com.cn%2Fuploadfile%2F2017%2F0212%2F1486868426284307.jpg"; - - FileDownloader downloader = new FileDownloader(url); + String url = "http://inews.gtimg.com/newsapp_bt/0/1209438116/1000"; +// String url = "https://www.baidu.com/img/bd_logo.png"; + FileDownloader downloader = new FileDownloader(url, "test.png"); ConnectionManager cm = new ConnectionManagerImpl(); downloader.setConnectionManager(cm); - downloader.setListener(new DownloadListener() { @Override public void notifyFinished() { downloadFinished = true; } - }); - downloader.execute(); - // �ȴ����߳����س���ִ����� + // 等待多线程下载程序执行完毕 while (!downloadFinished) { try { - System.out.println("��û��������ɣ���������"); - //����5�� - Thread.sleep(5000); + System.out.println("还没有下载完成,休眠0.01秒"); + time += 0.01; + //休眠0.01秒 + Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } - System.out.println("������ɣ�"); - - + System.out.println("下载完成!耗时"+time+"秒"); } - -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/api/Connection.java b/group09/790466157/src/com/coderising/download/api/Connection.java index fe772d969c..d370d27c68 100644 --- a/group09/790466157/src/com/coderising/download/api/Connection.java +++ b/group09/790466157/src/com/coderising/download/api/Connection.java @@ -4,23 +4,21 @@ public interface Connection { /** - * ʼͽλã ȡݣ ֵֽ - * @param startPos ʼλã 0ʼ - * @param endPos λ + * 给定开始和结束位置, 读取数据, 返回值是字节数组 + * @param startPos 开始位置, 从0开始 + * @param endPos 结束位置 * @return */ - public byte[] read(int startPos,int endPos) throws IOException; + byte[] read(int startPos, int endPos) throws IOException; + /** - * õݵij + * 得到数据内容的长度 * @return */ - public int getContentLength(); + int getContentLength(); /** - * ر + * 关闭连接 */ - public void close(); - public Connection open(Object url); + void close(); } - - diff --git a/group09/790466157/src/com/coderising/download/api/ConnectionException.java b/group09/790466157/src/com/coderising/download/api/ConnectionException.java index 132bf8fbdd..1551a80b3d 100644 --- a/group09/790466157/src/com/coderising/download/api/ConnectionException.java +++ b/group09/790466157/src/com/coderising/download/api/ConnectionException.java @@ -1,5 +1,5 @@ package com.coderising.download.api; public class ConnectionException extends Exception { - -} \ No newline at end of file + +} diff --git a/group09/790466157/src/com/coderising/download/api/ConnectionManager.java b/group09/790466157/src/com/coderising/download/api/ConnectionManager.java index e6a9811662..e3759c46ce 100644 --- a/group09/790466157/src/com/coderising/download/api/ConnectionManager.java +++ b/group09/790466157/src/com/coderising/download/api/ConnectionManager.java @@ -1,10 +1,13 @@ package com.coderising.download.api; +import java.io.IOException; +import java.net.ProtocolException; + public interface ConnectionManager { /** - * һurl , һ + * 给定一个url , 打开一个连接 * @param url * @return */ - public Connection open(String url) throws ConnectionException; -} \ No newline at end of file + Connection open(String url) throws ConnectionException; +} diff --git a/group09/790466157/src/com/coderising/download/api/DownloadListener.java b/group09/790466157/src/com/coderising/download/api/DownloadListener.java index 64ac13231b..de81b7607d 100644 --- a/group09/790466157/src/com/coderising/download/api/DownloadListener.java +++ b/group09/790466157/src/com/coderising/download/api/DownloadListener.java @@ -1,5 +1,5 @@ package com.coderising.download.api; public interface DownloadListener { - public void notifyFinished(); -} \ No newline at end of file + void notifyFinished(); +} diff --git a/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java b/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java index a0bea92f06..ba27ce6c9a 100644 --- a/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java +++ b/group09/790466157/src/com/coderising/download/impl/ConnectionImpl.java @@ -1,51 +1,64 @@ package com.coderising.download.impl; - +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; - - -import org.omg.CORBA.portable.InputStream; - +import com.basic.ArrayList; import com.coderising.download.api.Connection; +public class ConnectionImpl implements Connection{ + private HttpURLConnection downLoadConn; + private HttpURLConnection getLengthConn; -import java.net.URLConnection; + public ConnectionImpl(URL urlObject) { + HttpURLConnection conn = null; + try { + downLoadConn = (HttpURLConnection) urlObject.openConnection(); + downLoadConn.setRequestMethod("GET"); -import com.coderising.download.api.Connection; + getLengthConn = (HttpURLConnection) urlObject.openConnection(); + getLengthConn.setRequestMethod("GET"); + } catch (IOException e) { + e.printStackTrace(); + } + + } -public class ConnectionImpl implements Connection{ - -private URLConnection connection; - @Override public byte[] read(int startPos, int endPos) throws IOException { -// connection.setAllowUserInteraction(true); -// connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); - InputStream inputstream = (InputStream) connection.getInputStream(); - byte[] buffer = new byte[endPos - startPos + 1]; - inputstream.skip(startPos); - inputstream.read(buffer); - inputstream.close(); - return buffer; - } + downLoadConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); + + InputStream in = downLoadConn.getInputStream(); + byte[] buf = new byte[endPos-startPos+1]; + byte[] tempBuf = new byte[1024]; + BufferedInputStream bis = new BufferedInputStream(in); + int len = 0; + int totalLen = 0; + while((len=bis.read(tempBuf,0,tempBuf.length))!=-1){ + System.arraycopy(tempBuf, 0, buf, totalLen, len); + totalLen += len; + } + String desc = " bytes=" + startPos + "-" + endPos + " "; + System.out.println(Thread.currentThread().getName()+desc+totalLen); + in.close(); + bis.close(); + return Arrays.copyOf(buf, totalLen); + } @Override - public int getContentLength(){ - return connection.getContentLength(); + public int getContentLength() { + int len = getLengthConn.getContentLength(); + return len; } @Override public void close() { + downLoadConn.disconnect(); + getLengthConn.disconnect(); } - public void setConnection(URLConnection connection) { - this.connection = connection; - } - - @Override - public Connection open(Object url) { - // TODO Auto-generated method stub - return null; - } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java index 99bdec847f..b66bb996be 100644 --- a/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java +++ b/group09/790466157/src/com/coderising/download/impl/ConnectionManagerImpl.java @@ -1,35 +1,23 @@ package com.coderising.download.impl; - - - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - - - - import com.coderising.download.api.Connection; -import com.coderising.download.impl.ConnectionImpl; import com.coderising.download.api.ConnectionException; import com.coderising.download.api.ConnectionManager; +import java.io.IOException; +import java.net.URL; + public class ConnectionManagerImpl implements ConnectionManager { @Override public Connection open(String url) throws ConnectionException { - URL urlObj ; - ConnectionImpl connection = null; - try { - urlObj = new URL(url); - connection = new ConnectionImpl(); - } catch (MalformedURLException e) { - throw new ConnectionException(); - } - return connection; + URL urlObject; + try { + urlObject = new URL(url); + return new ConnectionImpl(urlObject); + } catch (IOException e) { + e.printStackTrace(); + throw new ConnectionException(); + } } -} \ No newline at end of file +} diff --git a/group09/790466157/src/com/coderising/linkedlist/Iterator.java b/group09/790466157/src/com/coderising/linkedlist/Iterator.java new file mode 100644 index 0000000000..b09016ee94 --- /dev/null +++ b/group09/790466157/src/com/coderising/linkedlist/Iterator.java @@ -0,0 +1,7 @@ +package com.coderising.linkedlist; + +public interface Iterator { + public boolean hasNext(); + public Object next(); + +} diff --git a/group09/790466157/src/com/coderising/linkedlist/LinkedList.java b/group09/790466157/src/com/coderising/linkedlist/LinkedList.java new file mode 100644 index 0000000000..7530d105e9 --- /dev/null +++ b/group09/790466157/src/com/coderising/linkedlist/LinkedList.java @@ -0,0 +1,263 @@ +package com.coderising.linkedlist; + +public class LinkedList implements List { + + private Node head; + private int size = 0; + + public void add(Object o){ + if(head == null){ + head = new Node(o); + }else{ + Node pos = head; + while(pos.next != null){ + pos = pos.next; + } + pos.next = new Node(o); + } + size++; + } + + public void add(int index , Object o){ + checkIndex(index); + if(index == 0) { + Node node = new Node(o); + node.next = head; + head = node; + } + else{ + Node pos = head; + for(int i = 0;i < index-1;i++){ + pos = pos.next; + } + Node node = new Node(o); + node.next = pos.next; + pos.next = node; + } + size++; + } + + private void checkIndex(int index) { + if(index < 0 || index >size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); + } + + public Object get(int index){ + checkIndexPosition(index); + Node pos = head; + for(int i = 0;i < index;i++){ + pos = pos.next; + } + return pos.data; + } + + public Object remove(int index){ + checkIndexPosition(index); + Node element = head; + if(index == 0){ + head = head.next; + }else{ + Node pos = head; + for(int i = 0;i < index - 1;i++){ + pos = pos.next; + } + element = pos.next; + pos.next = pos.next.next; + } + size--; + return element.data; + } + + private void checkIndexPosition(int index) { + if(index < 0 || index >=size ) throw new IndexOutOfBoundsException("Index:"+index+",Size"+size); + } + + + public int size(){ + return size; + } + + public void addFirst(Object o){ + add(0,o); + } + + public void addLast(Object o){ + add(size,o); + } + + public Object removeFirst(){ + return remove(0); + } + + public Object removeLast(){ + return remove(size-1); + } + + public Iterator iterator(){ + return new LinkedListIterator(); + } + + class LinkedListIterator implements Iterator{ + + private Node node = head; + private int pos = 0; + @Override + public boolean hasNext() { + return pos < size; + } + + @Override + public Object next() { + pos++; + if(pos != 1){ + node = node.next; + } + return node.data; + } + } + + private static class Node{ + Object data; + Node next; + public Node(Object data){ + this.data = data; + next = null; + } + } + /** + * 把该链表逆置 + * 例如链表为 3->7->10 , 逆置后变为 10->7->3 + */ + public void reverse(){ + if(size == 0) return; + + for(int i=1;i5->7->8 , 删除以后的值为 7->8 + * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10 + + */ + public void removeFirstHalf(){ + if(size == 0) return; + + int removeNum = size/2; + for(int i=0;i size || i<0 || i>=size) return; + + for(int k=i;k<(length+i);k++){ + remove(i); + } + } + /** + * 假定当前链表和list均包含已升序排列的整数 + * 从当前链表中取出那些list所指定的元素 + * 例如当前链表 = 11->101->201->301->401->501->601->701 + * listB = 1->3->4->6 + * 返回的结果应该是[101,301,401,601] + * @param list + */ + public int[] getElements(LinkedList list){ + if(list == null) return new int[0]; + + int[] targetList = new int[list.size]; + for(int i=0;i min && (int)get(i) < max){ + remove(i--); + } + } + */ + + //遍历到最小值和最大值处并记录位置,最后调用remove(int i,int length)进行范围内的删除。 + int minPos = 0; + int maxPos = 0; + boolean exec = true; + for(int i=0;i min) { + minPos = i; + exec = false; + } else if((int)get(i) >max){ + maxPos = i; + break; + } + } + remove(minPos, maxPos - minPos); + } + + /** + * 假设当前链表和参数list指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同) + * 现要求生成新链表C,其元素为当前链表和list中元素的交集,且表C中的元素有依值递增有序排列 + * @param list + */ + public LinkedList intersection( LinkedList list){ + LinkedList newList = new LinkedList(); + for(int i=0;i actions = new HashMap<>(); + + public Configuration(String fileName) { + + String packageName = this.getClass().getPackage().getName(); + + packageName = packageName.replace('.', '/'); + + InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName); + + parseXML(is); + + try { + is.close(); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + private void parseXML(InputStream is){ + + SAXBuilder builder = new SAXBuilder(); + + try { + + Document doc = builder.build(is); + + Element root = doc.getRootElement(); + + for(Element actionElement : root.getChildren("action")){ + + String actionName = actionElement.getAttributeValue("name"); + String clzName = actionElement.getAttributeValue("class"); + + ActionConfig ac = new ActionConfig(actionName, clzName); + + for(Element resultElement : actionElement.getChildren("result")){ + + String resultName = resultElement.getAttributeValue("name"); + String viewName = resultElement.getText().trim(); + + ac.addViewResult(resultName, viewName); + + } + + this.actions.put(actionName, ac); + } + + + } catch (JDOMException e) { + throw new ConfigurationException(e); + + } catch (IOException e) { + throw new ConfigurationException(e); + + } + + + } + + public String getClassName(String action) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getClassName(); + } + + public String getResultView(String action, String resultName) { + ActionConfig ac = this.actions.get(action); + if(ac == null){ + return null; + } + return ac.getViewName(resultName); + } + + private static class ActionConfig{ + + String name; + String clzName; + Map viewResult = new HashMap<>(); + + + public ActionConfig(String actionName, String clzName) { + this.name = actionName; + this.clzName = clzName; + } + public String getClassName(){ + return clzName; + } + public void addViewResult(String name, String viewName){ + viewResult.put(name, viewName); + } + public String getViewName(String resultName){ + return viewResult.get(resultName); + } + } + +} diff --git a/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java b/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java new file mode 100644 index 0000000000..97e286827f --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ConfigurationException.java @@ -0,0 +1,21 @@ +package com.coderising.litestruts; + +import java.io.IOException; + +import org.jdom2.JDOMException; + +public class ConfigurationException extends RuntimeException { + + public ConfigurationException(String msg) { + super(msg); + } + + public ConfigurationException(JDOMException e) { + super(e); + } + + public ConfigurationException(IOException e) { + super(e); + } + +} diff --git a/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java b/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java new file mode 100644 index 0000000000..734649f37a --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ConfigurationTest.java @@ -0,0 +1,50 @@ +package com.coderising.litestruts; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ConfigurationTest { + + + Configuration cfg = new Configuration("struts.xml"); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetClassName() { + + String clzName = cfg.getClassName("login"); + Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName); + + + clzName = cfg.getClassName("logout"); + Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName); + } + + @Test + public void testGetResultView(){ + String jsp = cfg.getResultView("login","success"); + Assert.assertEquals("/jsp/homepage.jsp", jsp); + + jsp = cfg.getResultView("login","fail"); + Assert.assertEquals("/jsp/showLogin.jsp", jsp); + + jsp = cfg.getResultView("logout","success"); + Assert.assertEquals("/jsp/welcome.jsp", jsp); + + jsp = cfg.getResultView("logout","error"); + Assert.assertEquals("/jsp/error.jsp", jsp); + + } + +} diff --git a/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java b/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java new file mode 100644 index 0000000000..0bd53fea93 --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ReflectionUtil.java @@ -0,0 +1,123 @@ +package com.coderising.litestruts; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReflectionUtil { + + public static List getSetterMethods(Class clz) { + + return getMethods(clz,"set"); + + } + + public static void setParameters(Object o, Map params) { + + List methods = getSetterMethods(o.getClass()); + + for(String name : params.keySet() ){ + + String methodName = "set" + name; + + for(Method m: methods){ + + if(m.getName().equalsIgnoreCase(methodName)){ + try { + m.invoke(o, params.get(name)); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + + } + + public static List getGetterMethods(Class clz) { + return getMethods(clz,"get"); + } + + private static List getMethods(Class clz, String startWithName){ + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith(startWithName)){ + + methods.add(m); + + } + + } + + return methods; + } + + public static Map getParamterMap(Object o) { + + Map params = new HashMap<>(); + + List methods = getGetterMethods(o.getClass()); + + for(Method m : methods){ + + String methodName = m.getName(); + String name = methodName.replaceFirst("get", "").toLowerCase(); + try { + Object value = m.invoke(o); + params.put(name, value); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + + e.printStackTrace(); + } + } + + return params; + } + + ////////////////////////Backup /////////////////////////////////// + + public static List getGetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("get")){ + + methods.add(m); + + } + + } + + return methods; + } + + public static List getSetterMethods_V1(Class clz) { + + List methods = new ArrayList<>(); + + for(Method m : clz.getDeclaredMethods()){ + + if(m.getName().startsWith("set")){ + + methods.add(m); + + } + + } + + return methods; + + } + + + + +} diff --git a/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java b/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java new file mode 100644 index 0000000000..cbe732d83f --- /dev/null +++ b/group09/790466157/src/com/coderising/litestruts/ReflectionUtilTest.java @@ -0,0 +1,113 @@ +package com.coderising.litestruts; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class ReflectionUtilTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetSetterMethod() throws Exception { + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getSetterMethods(clz); + + Assert.assertEquals(2, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("setName"); + expectedNames.add("setPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testSetParameters() throws Exception{ + + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + Object o = clz.newInstance(); + + Map params = new HashMap(); + params.put("name","test"); + params.put("password","1234"); + + ReflectionUtil.setParameters(o,params); + + + + Field f = clz.getDeclaredField("name"); + f.setAccessible(true); + Assert.assertEquals("test", f.get(o)); + + f = clz.getDeclaredField("password"); + f.setAccessible(true); + Assert.assertEquals("1234", f.get(o)); + } + @Test + public void testGetGetterMethod() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + List methods = ReflectionUtil.getGetterMethods(clz); + + Assert.assertEquals(3, methods.size()); + + List expectedNames = new ArrayList<>(); + expectedNames.add("getMessage"); + expectedNames.add("getName"); + expectedNames.add("getPassword"); + + Set acctualNames = new HashSet<>(); + for(Method m : methods){ + acctualNames.add(m.getName()); + } + + Assert.assertTrue(acctualNames.containsAll(expectedNames)); + } + + @Test + public void testGetParamters() throws Exception{ + String name = "com.coderising.litestruts.LoginAction"; + Class clz = Class.forName(name); + LoginAction action = (LoginAction)clz.newInstance(); + action.setName("test"); + action.setPassword("123456"); + + + + + Map params = ReflectionUtil.getParamterMap(action); + + Assert.assertEquals(3, params.size()); + + Assert.assertEquals(null, params.get("messaage") ); + Assert.assertEquals("test", params.get("name") ); + Assert.assertEquals("123456", params.get("password") ); + } +} diff --git a/group09/790466157/src/com/coderising/litestruts/SAX.java b/group09/790466157/src/com/coderising/litestruts/SAX.java deleted file mode 100644 index ab3f0c1044..0000000000 --- a/group09/790466157/src/com/coderising/litestruts/SAX.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.coderising.litestruts; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.Attributes; -public class SAX extends DefaultHandler { - //ĵʼ¼ - public void startDocument() { - System.out.println("ĵʼ "); - } - //ĵ¼ - public void endDocument() { - System.out.println("ĵ"); - } - //Ԫؿʼ¼ - public void startElement(String uri, String localName, String qname, Attributes attr) - { System.out.println("Ԫؿʼ: : " + localName + " ޶: " + qname + " ռURI: "+uri); - int attrCount = attr.getLength(); - if(attrCount>0) { - System.out.println(":"); - for(int i = 0 ; i parameters) { - /* - - 0. ȡļstruts.xml + /* + + 0. 读取配置文件struts.xml - 1. actionNameҵӦclass LoginAction, ͨʵ - parametersеݣösetter parametersе + 1. 根据actionName找到相对应的class , 例如LoginAction, 通过反射实例化(创建对象) + 据parameters中的数据,调用对象的setter方法, 例如parameters中的数据是 ("name"="test" , "password"="1234") , - ǾӦõ setNamesetPassword + 那就应该调用 setName和setPassword方法 - 2. ͨöexectue ÷ֵ"success" + 2. 通过反射调用对象的exectue 方法, 并获得返回值,例如"success" - 3. ͨҵgetter getMessage, - ͨã ֵγһHashMap , {"message": "¼ɹ"} , - ŵViewparameters + 3. 通过反射找到对象的所有getter方法(例如 getMessage), + 通过反射来调用, 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} , + 放到View对象的parameters - 4. struts.xmlе ,Լexecuteķֵ ȷһjsp - ŵViewjspֶС + 4. 根据struts.xml中的 配置,以及execute的返回值, 确定哪一个jsp, + 放到View对象的jsp字段中。 */ + + + String clzName = cfg.getClassName(actionName); + + if(clzName == null){ + return null; + } + try { + + Class clz = Class.forName(clzName); + Object action = clz.newInstance(); + + ReflectionUtil.setParameters(action, parameters); + + Method m = clz.getDeclaredMethod("execute"); + String resultName = (String)m.invoke(action); + + Map params = ReflectionUtil.getParamterMap(action); + String resultView = cfg.getResultView(actionName, resultName); + View view = new View(); + view.setParameters(params); + view.setJsp(resultView); + return view; + + + + } catch (Exception e) { + + e.printStackTrace(); + } return null; }