r1550 - in xwiki/trunk: core/src/main/java/com/xpn/xwiki/plugin/zipexplorer src/test/java/com/xpn/xwiki/plugin/zipexplorer
Vincent Massol
vmassol at users.forge.objectweb.org
Tue Nov 14 16:44:03 CET 2006
Author: vmassol
Date: 2006-11-14 16:44:02 +0100 (Tue, 14 Nov 2006)
New Revision: 1550
Modified:
xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java
xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPluginAPI.java
xwiki/trunk/src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java
Log:
Refactoring for the ZipExplorerPlugin class and its tests:
* finished adding javadocs
* finished refactoring unit tests so that they are executed in isolation
* added usage of commons-io for copying stream in memory and added warning
Modified: xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java
===================================================================
--- xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java 2006-11-14 11:24:11 UTC (rev 1549)
+++ xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPlugin.java 2006-11-14 15:44:02 UTC (rev 1550)
@@ -34,8 +34,6 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.List;
@@ -45,6 +43,8 @@
import java.util.Vector;
import java.util.HashMap;
+import org.apache.commons.io.IOUtils;
+
public class ZipExplorerPlugin extends XWikiDefaultPlugin {
/**
@@ -92,15 +92,9 @@
}
/**
- * For ZIP URLs of the format <code>http://[...]/zipfile.zip/SomeDirectory/SomeFile.txt</code> return a new
- * attachment containing the file pointed to inside the ZIP. If the original attachment does not point to a ZIP
- * file or if it doesn't specify a location inside the ZIP then do nothing and return the original attachment.
- *
- * @return a new attachment pointing to the file pointed to by the URL inside the ZIP or the original attachment
- * if the requested URL doesn't specify a file inside a ZIP
- * @param attachment the original attachment
- * @param context the XWiki context object containing the requested URL
- * @see com.xpn.xwiki.plugin.XWikiDefaultPlugin#downloadAttachment(com.xpn.xwiki.doc.XWikiAttachment, com.xpn.xwiki.XWikiContext)
+ * See {@link com.xpn.xwiki.plugin.zipexplorer.ZipExplorerPluginAPI#downloadAttachment(com.xpn.xwiki.doc.XWikiAttachment)}
+ * for documentation. In addition the context parameter represents the XWiki context object containing the
+ * requested URL.
*/
public XWikiAttachment downloadAttachment(XWikiAttachment attachment, XWikiContext context) {
String url = context.getRequest().getRequestURI();
@@ -138,7 +132,12 @@
if (entryName.equals(filename)) {
newAttachment.setFilename(entryName);
- byte[] data = readFromInputStream(zis);
+
+ // Note: We're copying the content of the file in the ZIP in memory. This is potentially going to
+ // cause an error if the file's size is greater than the maximum size of a byte[] array in Java
+ // or if there's not enough memomry.
+ byte[] data = IOUtils.toByteArray(zis);
+
newAttachment.setFilesize(data.length);
newAttachment.setContent(data);
break;
@@ -154,34 +153,16 @@
}
/**
- * @return the content of an entry in the zip file
+ * See {@link com.xpn.xwiki.plugin.zipexplorer.ZipExplorerPluginAPI#getFileList(com.xpn.xwiki.api.Document, String)}
+ * for documentation. In addition the context parameter is not used for now.
*/
- private byte[] readFromInputStream(InputStream is) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] data = new byte[4096];
- int count;
- while ((count = is.read(data, 0, 4096)) != -1) {
- baos.write(data, 0, count);
- }
- return baos.toByteArray();
- }
-
- public List getFileList(Document doc, String attachmentName, XWikiContext context) {
+ public List getFileList(Document document, String attachmentName, XWikiContext context) {
List zipList = null;
if (attachmentName.endsWith(".zip")) {
- Attachment attachment = null;
- List attachList = doc.getAttachmentList();
- Iterator itr = attachList.iterator();
+ Attachment attachment = document.getAttachment(attachmentName);
- while (itr.hasNext()) {
- attachment = (Attachment)itr.next();
- if (attachment.getFilename().equals(attachmentName)) {
- break;
- }
- }
-
zipList = new ArrayList();
byte[] stream;
try {
@@ -204,8 +185,12 @@
return zipList;
}
- public Vector getFileTreeList(Document doc, String attachmentName, XWikiContext context) {
- List flatList = getFileList(doc, attachmentName, context);
+ /**
+ * See {@link com.xpn.xwiki.plugin.zipexplorer.ZipExplorerPluginAPI#getFileTreeList(com.xpn.xwiki.api.Document, String)}
+ * for documentation. In addition the context parameter is not used for now.
+ */
+ public Vector getFileTreeList(Document document, String attachmentName, XWikiContext context) {
+ List flatList = getFileList(document, attachmentName, context);
Map fileTree = new HashMap();
Iterator it = flatList.iterator();
Vector res = new Vector();
@@ -229,8 +214,11 @@
return res;
}
- String getFileLink(Document doc, String attachmentName, String fileName, XWikiContext context) {
- String link = doc.getAttachmentURL(attachmentName);
- return link + "/" + fileName;
+ /**
+ * See {@link com.xpn.xwiki.plugin.zipexplorer.ZipExplorerPluginAPI#getFileLink(com.xpn.xwiki.api.Document, String, String)}
+ * for documentation. In addition the context parameter is not used for now.
+ */
+ String getFileLink(Document document, String attachmentName, String fileName, XWikiContext context) {
+ return document.getAttachmentURL(attachmentName) + "/" + fileName;
}
}
Modified: xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPluginAPI.java
===================================================================
--- xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPluginAPI.java 2006-11-14 11:24:11 UTC (rev 1549)
+++ xwiki/trunk/core/src/main/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerPluginAPI.java 2006-11-14 15:44:02 UTC (rev 1550)
@@ -29,29 +29,73 @@
import java.util.List;
import java.util.Vector;
-
public class ZipExplorerPluginAPI extends Api {
- ZipExplorerPlugin plugin;
+ private ZipExplorerPlugin plugin;
public ZipExplorerPluginAPI(ZipExplorerPlugin plugin, XWikiContext context) {
super(context);
this.plugin = plugin;
}
+ /**
+ * For ZIP URLs of the format <code>http://[...]/zipfile.zip/SomeDirectory/SomeFile.txt</code> return a new
+ * attachment containing the file pointed to inside the ZIP. If the original attachment does not point to a ZIP
+ * file or if it doesn't specify a location inside the ZIP then do nothing and return the original attachment.
+ *
+ * @return a new attachment pointing to the file pointed to by the URL inside the ZIP or the original attachment
+ * if the requested URL doesn't specify a file inside a ZIP
+ * @param attachment the original attachment
+ * @see com.xpn.xwiki.plugin.XWikiDefaultPlugin#downloadAttachment(com.xpn.xwiki.doc.XWikiAttachment, com.xpn.xwiki.XWikiContext)
+ */
public XWikiAttachment downloadAttachment(XWikiAttachment attachment) {
return this.plugin.downloadAttachment(attachment, context);
}
- public List getFileList(Document doc, String attachmentName) {
- return this.plugin.getFileList(doc, attachmentName, context);
+ /**
+ * @return the list of file entries in the ZIP file attached under the passed attachment name inside the passed
+ * document
+ * @param document the document containing the ZIP file as an attachment
+ * @param attachmentName the name under which the ZIP file is attached in the document
+ */
+ public List getFileList(Document document, String attachmentName) {
+ return this.plugin.getFileList(document, attachmentName, context);
}
- public Vector getFileTreeList(Document doc, String attachmentName) {
- return this.plugin.getFileTreeList(doc, attachmentName, context);
+ /**
+ * Finds the ZIP attachement with passed name from the passed document matching and parse the ZIP to generate
+ * a list of {@link com.xpn.xwiki.objects.classes.ListItem} elements representing a tree view of all directories
+ * and files in the ZIP. For example the following zip:
+ * </p>
+ * <code><pre>
+ * zipfile.zip:
+ * Directory/File.txt
+ * File2.txt
+ * </per></code>
+ * generates the following ListItem list:
+ * <code><pre>
+ * { id = "Directory/", value = "Directory", parent = ""}
+ * { id = "Directory/File.txt", value = "File.txt", parent = "Directory/"}
+ * { id = "File2.txt", value = "File2.txt", parent = ""}
+ * </per></code>
+ *
+ * @return a tree view list of {@link com.xpn.xwiki.objects.classes.ListItem} elements representing the content of
+ * the ZIP file
+ * @param document the document containing the ZIP file as an attachment
+ * @param attachmentName the name under which the ZIP file is attached in the document
+ */
+ public Vector getFileTreeList(Document document, String attachmentName) {
+ return this.plugin.getFileTreeList(document, attachmentName, context);
}
- public String getFileLink(Document doc, String attachmentName, String fileName) {
- return this.plugin.getFileLink(doc, attachmentName, fileName, context);
+ /**
+ * @return the attachment URL of the passed attachement located in the passed document to which the passed filename
+ * has been suffixed.
+ * @param document the document containing the ZIP file as an attachment
+ * @param attachmentName the name under which the ZIP file is attached in the document
+ * @param fileName the filename to concatenate at the end of the attachment URL
+ */
+ public String getFileLink(Document document, String attachmentName, String fileName) {
+ return this.plugin.getFileLink(document, attachmentName, fileName, context);
}
}
Modified: xwiki/trunk/src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java
===================================================================
--- xwiki/trunk/src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java 2006-11-14 11:24:11 UTC (rev 1549)
+++ xwiki/trunk/src/test/java/com/xpn/xwiki/plugin/zipexplorer/ZipExplorerTest.java 2006-11-14 15:44:02 UTC (rev 1550)
@@ -21,121 +21,147 @@
*/
package com.xpn.xwiki.plugin.zipexplorer;
-import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.objects.classes.ListItem;
import com.xpn.xwiki.api.Document;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;
-import com.xpn.xwiki.test.HibernateTestCase;
-import com.xpn.xwiki.web.XWikiServletURLFactory;
+import com.xpn.xwiki.web.XWikiRequest;
+import org.jmock.Mock;
-import java.io.ByteArrayOutputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Date;
import java.util.List;
+import java.util.Vector;
+import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
+import java.io.ByteArrayOutputStream;
-public class ZipExplorerTest extends HibernateTestCase {
+public class ZipExplorerTest extends org.jmock.cglib.MockObjectTestCase {
- String zipfilename = "test.zip";
- String author = "XWiki.LudovicDubost";
- String parent = "Main.WebHome";
- String content = "Hello 1\n" + "<Hello> 2\n" + "Hello 3";
+ private ZipExplorerPlugin plugin;
- String filename1 = "test.doc";
- String filename2 = "test.txt";
+ protected void setUp() {
+ this.plugin = new ZipExplorerPlugin("zipexplorer", ZipExplorerPlugin.class.getName(), null);
+ }
- XWikiAttachment attachment;
- XWikiDocument doc;
- Document maindoc;
+ public void testDownloadAttachmentWithInvalidZipURL() throws Exception {
+ XWikiAttachment originalAttachment = createAttachment("someFile.txt", "Some text".getBytes(),
+ (XWikiDocument) mock(XWikiDocument.class).proxy());
+ XWikiContext context = createXWikiContext("http://server/xwiki/bin/download/Main/Document/someFile.txt");
- List myExpectedList;
+ XWikiAttachment newAttachment = this.plugin.downloadAttachment(originalAttachment, context);
- protected void setUp() throws Exception {
- super.setUp();
- getXWiki().getPluginManager().addPlugin("zipexplorer", "com.xpn.xwiki.plugin.zipexplorer.ZipExplorerPlugin", getXWikiContext());
- getXWikiContext().setURLFactory(new XWikiServletURLFactory(new URL("http://www.xwiki.org/"), "xwiki/", "bin/"));
+ assertSame(originalAttachment, newAttachment);
}
- public void init() {
- doc = new XWikiDocument("Main", "ZipExplorerTest");
- doc.setContent(content);
- doc.setAuthor(author);
- doc.setParent(parent);
+ public void testDownloadAttachment() throws Exception {
+ String zipFileContent = "File.txt content";
+ XWikiAttachment originalAttachment = createAttachment("zipfile.zip", createZipFile(zipFileContent),
+ (XWikiDocument) mock(XWikiDocument.class).proxy());
+
+ XWikiContext context = createXWikiContext(
+ "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/File.txt");
- myExpectedList = new ArrayList();
- myExpectedList.add(filename1);
- myExpectedList.add(filename2);
+ XWikiAttachment newAttachment = this.plugin.downloadAttachment(originalAttachment, context);
- try {
+ assertEquals("Directory/File.txt", newAttachment.getFilename());
+ assertEquals(zipFileContent.length(), newAttachment.getFilesize());
+ assertEquals(zipFileContent, new String(newAttachment.getContent(context)));
+ }
- attachment = new XWikiAttachment(doc, zipfilename);
+ public void testGetFileList() throws Exception {
+ XWikiDocument document = createXWikiDocumentWithZipFileAttachment();
- String attachcontent1 = "Hi i'm here";
- byte[] stream = attachcontent1.getBytes();
+ List entries = this.plugin.getFileList(new Document(document, null), "zipfile.zip", null);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ZipOutputStream zos = new ZipOutputStream(baos);
+ assertEquals(2, entries.size());
+ assertEquals("Directory/File.txt", (String) entries.get(0));
+ assertEquals("File2.txt", (String) entries.get(1));
+ }
- /* Each is the entry to the zip file */
+ public void testGetFileTreeList() throws Exception {
+ XWikiDocument document = createXWikiDocumentWithZipFileAttachment();
- ZipEntry zipe = new ZipEntry(filename1);
- zos.putNextEntry(zipe);
- zos.write(stream, 0, stream.length);
+ Vector entries = this.plugin.getFileTreeList(new Document(document, null), "zipfile.zip", null);
- zipe = new ZipEntry(filename2);
- zos.putNextEntry(zipe);
- zos.write(stream, 0, stream.length);
+ assertEquals(3, entries.size());
- zos.closeEntry();
+ assertEquals("Directory/", ((ListItem) entries.get(0)).getId());
+ assertEquals("Directory", ((ListItem) entries.get(0)).getValue());
+ assertEquals("", ((ListItem) entries.get(0)).getParent());
- attachment.setContent(baos.toByteArray());
- doc.saveAttachmentContent(attachment, context);
+ assertEquals("Directory/File.txt", ((ListItem) entries.get(1)).getId());
+ assertEquals("File.txt", ((ListItem) entries.get(1)).getValue());
+ assertEquals("Directory/", ((ListItem) entries.get(1)).getParent());
- doc.getAttachmentList().add(attachment);
- xwiki.saveDocument(doc, context);
- maindoc = new Document(doc, context);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
+ assertEquals("File2.txt", ((ListItem) entries.get(2)).getId());
+ assertEquals("File2.txt", ((ListItem) entries.get(2)).getValue());
+ assertEquals("", ((ListItem) entries.get(2)).getParent());
}
- public void testZipExplorerTest() throws XWikiException {
- init();
- ZipExplorerPluginAPI zpa = (ZipExplorerPluginAPI) xwiki.getPluginApi("zipexplorer", context);
- compareList(myExpectedList, zpa.getFileList(maindoc, attachment.getFilename()));
- assertEquals("/xwiki/bin/download/Main/ZipExplorerTest/" + filename1,zpa.getFileLink(maindoc, attachment.getFilename(), filename1));
+ public void testGetFileLink() throws Exception {
+ Mock mockDocument = mock(XWikiDocument.class);
+ mockDocument.expects(once()).method("getAttachmentURL").will(
+ returnValue("http://server/xwiki/bin/download/Main/Document/zipfile.zip"));
+ Document document = new Document((XWikiDocument) mockDocument.proxy(), null);
+
+ String link = this.plugin.getFileLink(document, "zipfile.zip", "filename", null);
+
+ assertEquals("http://server/xwiki/bin/download/Main/Document/zipfile.zip/filename", link);
}
- public void testGetFileNameFromZipURL()
+ public void testGetFileLocationFromZipURL()
{
- ZipExplorerPlugin plugin = new ZipExplorerPlugin("zipexplorer",
- ZipExplorerPlugin.class.getName(), new XWikiContext());
- String fileName = plugin.getFileLocationFromZipURL(
- "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/File.txt",
- "download");
+ String fileName = this.plugin.getFileLocationFromZipURL(
+ "http://server/xwiki/bin/download/Main/Document/zipfile.zip/Directory/File.txt", "download");
assertEquals("Directory/File.txt", fileName);
}
- public void testGetFileNameFromZipURLWhenInvalidURL()
+ public void testGetFileLocationFromZipURLWhenInvalidURL()
{
- ZipExplorerPlugin plugin = new ZipExplorerPlugin("zipexplorer",
- ZipExplorerPlugin.class.getName(), new XWikiContext());
- String fileName = plugin.getFileLocationFromZipURL(
- "http://server/xwiki/bin/download/Main/Document/zipfile.zip",
- "download");
+ String fileName = this.plugin.getFileLocationFromZipURL(
+ "http://server/xwiki/bin/download/Main/Document/zipfile.zip", "download");
assertEquals("", fileName);
}
- private void compareList(List myExpectedList, List myResult){
- assertEquals(myExpectedList.size(), myResult.size());
- Iterator it = myResult.iterator();
- while(it.hasNext()){
- Object value = it.next();
- assertTrue(myExpectedList.contains(value));
- }
+ private XWikiDocument createXWikiDocumentWithZipFileAttachment() throws Exception {
+ Mock mockDocument = mock(XWikiDocument.class);
+ XWikiDocument document = (XWikiDocument) mockDocument.proxy();
+ XWikiAttachment attachment = createAttachment("zipfile.zip", createZipFile("Some content"), document);
+ mockDocument.stubs().method("clone").will(returnValue(mockDocument.proxy()));
+ mockDocument.stubs().method("getAttachment").will(returnValue(attachment));
+ return document;
}
+
+ private XWikiContext createXWikiContext(String url) {
+ Mock mockRequest = mock(XWikiRequest.class);
+ mockRequest.expects(once()).method("getRequestURI").will(returnValue(url));
+ XWikiContext context = new XWikiContext();
+ context.setRequest((XWikiRequest) mockRequest.proxy());
+ context.setAction("download");
+ return context;
+ }
+
+ private XWikiAttachment createAttachment(String filename, byte[] content, XWikiDocument document) throws Exception {
+ Mock mockAttachment = mock(XWikiAttachment.class);
+ mockAttachment.stubs().method("getFilename").will(returnValue(filename));
+ mockAttachment.stubs().method("getDoc").will(returnValue(document));
+ mockAttachment.stubs().method("getAuthor").will(returnValue("Vincent"));
+ mockAttachment.stubs().method("getDate").will(returnValue(new Date()));
+ mockAttachment.stubs().method("getContent").will(returnValue(content));
+ return (XWikiAttachment) mockAttachment.proxy();
+ }
+
+ private byte[] createZipFile(String content) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(baos);
+ ZipEntry zipe = new ZipEntry("Directory/File.txt");
+ zos.putNextEntry(zipe);
+ zos.write(content.getBytes());
+ ZipEntry zipe2 = new ZipEntry("File2.txt");
+ zos.putNextEntry(zipe2);
+ zos.write(content.getBytes());
+ zos.closeEntry();
+ return baos.toByteArray();
+ }
}
More information about the Xwiki-notifications
mailing list