[Code review] ZipExplorer plugin
Hi, In order to understand better the code I have reviewed the ZipExplorer plugin. Here's my code review: * There are 2 unused fields that should be removed: capacity and log * The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin. * There are no javadocs... The minimum would be to have a class javadoc explaining what the plugin is doing and putting an example of how to use it. * readFromInputStream() is a generic method to read an input stream in memory. Note that this method should be moved in some generic place as it would be useful for other portion of the code and is completely generic. Even better this method is already implemented in commons-io [http://jakarta.apache.org/commons/io/api-release/org/apache/commons/io/File Utils.html#readFileToByteArray(java.io.File)]. Also note that it's a dangerous method as it's limited by the size of the memory and the size of of a byte[] array in Java... If the zip is large it's going to fail... It would be better to implement it with streaming instead, if possible. * getFileTreeList(). By reading this method's name I don't understand what it does. I also don't understand what is the difference with getFileList() (I haven't analyzed the code). * Exception handling is very very poor :-) For example: } catch (XWikiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } * The unit tests seem to be lacking. In any case they're hard to read. I haven't fully understood them yet... I believe they shouldn't test XWiki's core but only the plugin. Let me know what you think and I'll create some jira issues to fix it. Thanks -Vincent ___________________________________________________________________________ D�couvrez une nouvelle fa�on d'obtenir des r�ponses � toutes vos questions ! Profitez des connaissances, des opinions et des exp�riences des internautes sur Yahoo! Questions/R�ponses http://fr.answers.yahoo.com
On 11/13/06, Vincent Massol <[email protected]> wrote:
Hi,
In order to understand better the code I have reviewed the ZipExplorer plugin. Here's my code review:
* There are 2 unused fields that should be removed: capacity and log for sure.
* The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin.
yes, it's not good, but the zip explorer plugin is doing something special, not standart on xwiki, so we just have this to do it. I know this plugin is not working for exemple in exo.
* There are no javadocs... The minimum would be to have a class javadoc explaining what the plugin is doing and putting an example of how to use it.
it could be good.
* readFromInputStream() is a generic method to read an input stream in memory. Note that this method should be moved in some generic place as it would be useful for other portion of the code and is completely generic. Even better this method is already implemented in commons-io [http://jakarta.apache.org/commons/io/api-release/org/apache/commons/io/File Utils.html#readFileToByteArray(java.io.File)]. Also note that it's a dangerous method as it's limited by the size of the memory and the size of of a byte[] array in Java... If the zip is large it's going to fail... It would be better to implement it with streaming instead, if possible.
The first problem is that attachments us an array of bytes and not a stream. If I remember well what ludovic tells me about it is that hibernate does not support it.
* getFileTreeList(). By reading this method's name I don't understand what it does. I also don't understand what is the difference with getFileList() (I haven't analyzed the code).
the first one return a list which is for generating a tree, and the second one just the flat file list.
* Exception handling is very very poor :-) For example:
} catch (XWikiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
In velocity there is no way to catch the exception, so if we send an exception to the page, it brake all the page, so I prefer to not raise the exception. Maybe the best sould be to set a variable with the error and be able to read the list of error.
* The unit tests seem to be lacking. In any case they're hard to read. I haven't fully understood them yet... I believe they shouldn't test XWiki's core but only the plugin.
Not everything is tested because it's too long to write a test for some of this functions(cactus test). We have junit test, but not cactus test. jeremi
-----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of jeremi joslin Sent: lundi 13 novembre 2006 17:51 To: [email protected] Subject: Re: [xwiki-dev] [Code review] ZipExplorer plugin
[snip]
* The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin. yes, it's not good, but the zip explorer plugin is doing something special, not standart on xwiki, so we just have this to do it. I know this plugin is not working for exemple in exo.
I don't understand this. Apparently the algorithm is: - find the string after the action - count 4 "/" and return the remaining portion But if I take a standard XWiki URL such as http://mavenbook.xwiki.com/xwiki/bin/download/Main/Source/mavenbook-1.0.zip then what is it supposed to return? The action is "download" and there aren't 4 "/" after it. BTW if there were some unit tests for this method it would have been easier to understand. Also if it's not working in exo I think it should be documented in the javadoc of the plugin and/or a jira issue opened, don't you think? [snip]
* There are no javadocs... The minimum would be to have a class javadoc explaining what the plugin is doing and putting an example of how to use it. it could be good.
If you could explain to me what the plugin does then I'll add it.
* readFromInputStream() is a generic method to read an input stream in memory. Note that this method should be moved in some generic place as it would be useful for other portion of the code and is completely generic. Even better this method is already implemented in commons-io [http://jakarta.apache.org/commons/io/api- release/org/apache/commons/i o/File Utils.html#readFileToByteArray(java.io.File)]. Also note that it's a dangerous method as it's limited by the size of the memory and the size of of a byte[] array in Java... If the zip is large it's going to fail... It would be better to implement it with streaming instead, if possible. The first problem is that attachments us an array of bytes and not a stream. If I remember well what ludovic tells me about it is that hibernate does not support it.
Ok. At least we could use commons-io, no? And then we should definitely document in the javadoc why we're not using a stream and the ensuing limitation. I can do this.
* getFileTreeList(). By reading this method's name I don't understand what it does. I also don't understand what is the difference with getFileList() (I haven't analyzed the code). the first one return a list which is for generating a tree, and the second one just the flat file list.
So both return a list. I still don’t understand what's different in both method calls... If you have an example then I could possibly write unit tests with it.
* Exception handling is very very poor :-) For example:
} catch (XWikiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } In velocity there is no way to catch the exception, so if we send an exception to the page, it brake all the page, so I prefer to not raise the exception. Maybe the best sould be to set a variable with the error and be able to read the list of error.
Hmm... So you're saying that in all xwiki code we're not handling exceptions because of this? I think we should definitely have some error page with the description of the error.
* The unit tests seem to be lacking. In any case they're hard to read. I haven't fully understood them yet... I believe they shouldn't test XWiki's core but only the plugin. Not everything is tested because it's too long to write a test for some of this functions(cactus test). We have junit test, but not cactus test.
I don't think we should do cactus tests at all actually. Unit tests are the best for plugins as when we test a plugin the goal is not to test the xwiki core. We should also have functional tests for general tests but the majority of tests should be unit tests (i.e. in isolation from the environment - no container, not database and when possible no files). I'm happy to help define how to right unit tests for xwiki. We could use ZipExplorerPlugin as a trial for writing them. It's probably going to require some modifications to the core to some degree. That's the good point of unit tests: they do improve design. Only problem is that xwiki technical debt is quite high at the moment, so it'll cost a lot for the first tests. It'll get better afterwards. Thanks -Vincent ___________________________________________________________________________ D�couvrez une nouvelle fa�on d'obtenir des r�ponses � toutes vos questions ! Profitez des connaissances, des opinions et des exp�riences des internautes sur Yahoo! Questions/R�ponses http://fr.answers.yahoo.com
On 11/13/06, Vincent Massol <[email protected]> wrote:
-----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of jeremi joslin Sent: lundi 13 novembre 2006 17:51 To: [email protected] Subject: Re: [xwiki-dev] [Code review] ZipExplorer plugin
[snip]
* The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin. yes, it's not good, but the zip explorer plugin is doing something special, not standart on xwiki, so we just have this to do it. I know this plugin is not working for exemple in exo.
I don't understand this. Apparently the algorithm is: - find the string after the action - count 4 "/" and return the remaining portion
yes beacause we are using an URL like : http://mavenbook.xwiki.com/xwiki/bin/download/Main/Source/mavenbook-1.0.zip/... we want to get Directory/File.txt
But if I take a standard XWiki URL such as http://mavenbook.xwiki.com/xwiki/bin/download/Main/Source/mavenbook-1.0.zip then what is it supposed to return? The action is "download" and there aren't 4 "/" after it. BTW if there were some unit tests for this method it would have been easier to understand.
Also if it's not working in exo I think it should be documented in the javadoc of the plugin and/or a jira issue opened, don't you think?
Yes, we should have add a javadoc about this.
[snip]
* There are no javadocs... The minimum would be to have a class javadoc explaining what the plugin is doing and putting an example of how to use it. it could be good.
If you could explain to me what the plugin does then I'll add it.
I'll do it later, I don't have time now.
* readFromInputStream() is a generic method to read an input stream in memory. Note that this method should be moved in some generic place as it would be useful for other portion of the code and is completely generic. Even better this method is already implemented in commons-io [http://jakarta.apache.org/commons/io/api- release/org/apache/commons/i o/File Utils.html#readFileToByteArray(java.io.File)]. Also note that it's a dangerous method as it's limited by the size of the memory and the size of of a byte[] array in Java... If the zip is large it's going to fail... It would be better to implement it with streaming instead, if possible. The first problem is that attachments us an array of bytes and not a stream. If I remember well what ludovic tells me about it is that hibernate does not support it.
Ok. At least we could use commons-io, no? And then we should definitely document in the javadoc why we're not using a stream and the ensuing limitation. I can do this.
Yes, it's just I didn't know that was in this lib. Yes, it should be done maybe not on the plugin, but on XWikiAttachement.
* getFileTreeList(). By reading this method's name I don't understand what it does. I also don't understand what is the difference with getFileList() (I haven't analyzed the code). the first one return a list which is for generating a tree, and the second one just the flat file list.
So both return a list. I still don't understand what's different in both method calls... If you have an example then I could possibly write unit tests with it.
* Exception handling is very very poor :-) For example:
} catch (XWikiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } In velocity there is no way to catch the exception, so if we send an exception to the page, it brake all the page, so I prefer to not raise the exception. Maybe the best sould be to set a variable with the error and be able to read the list of error.
Hmm... So you're saying that in all xwiki code we're not handling exceptions because of this? I think we should definitely have some error page with the description of the error.
No it's not. We don't have defined rules for this. so some code we are doing like this, some code no. We know we should work on this to define a generic way to handle this, it's more a time issue.
* The unit tests seem to be lacking. In any case they're hard to read. I haven't fully understood them yet... I believe they shouldn't test XWiki's core but only the plugin. Not everything is tested because it's too long to write a test for some of this functions(cactus test). We have junit test, but not cactus test.
I don't think we should do cactus tests at all actually. Unit tests are the best for plugins as when we test a plugin the goal is not to test the xwiki core. We should also have functional tests for general tests but the majority of tests should be unit tests (i.e. in isolation from the environment - no container, not database and when possible no files).
Yes, but for the moment we can't. So it's more an issue of time. If we had more time, we can improve this.
I'm happy to help define how to right unit tests for xwiki. We could use ZipExplorerPlugin as a trial for writing them. It's probably going to require some modifications to the core to some degree. That's the good point of unit tests: they do improve design. Only problem is that xwiki technical debt is quite high at the moment, so it'll cost a lot for the first tests. It'll get better afterwards.
let's go. jeremi
-----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of jeremi joslin Sent: lundi 13 novembre 2006 18:30 To: [email protected] Subject: Re: [xwiki-dev] [Code review] ZipExplorer plugin
[snip]
I don't understand this. Apparently the algorithm is: - find the string after the action - count 4 "/" and return the remaining portion
yes beacause we are using an URL like : http://mavenbook.xwiki.com/xwiki/bin/download/Main/Source/mavenbook- 1.0.zip/Directory/File.txt we want to get Directory/File.txt
One more question: do you think the getFileName() algorithm could be modified so that it looks for a ".zip" string instead of "/"+action? That would simplify the algorithm and remove the dependency on the xwiki action.
But if I take a standard XWiki URL such as http://mavenbook.xwiki.com/xwiki/bin/download/Main/Source/mavenbook- 1.0.zip then what is it supposed to return? The action is "download" and there aren't 4 "/" after it. BTW if there were some unit tests for this method it would have been easier to understand.
Also if it's not working in exo I think it should be documented in the javadoc of the plugin and/or a jira issue opened, don't you think?
Yes, we should have add a javadoc about this.
Done + unit tests added for this getFileName() method. BTW what do you think about naming the method getFileNameFromZipURL()? It looks more explicit to me.
* There are no javadocs... The minimum would be to have a class javadoc explaining what the plugin is doing and putting an example of how to use it. it could be good.
If you could explain to me what the plugin does then I'll add it. I'll do it later, I don't have time now.
Ok
* readFromInputStream() is a generic method to read an input stream in memory. Note that this method should be moved in some generic place as it would be useful for other portion of the code and is completely generic. Even better this method is already implemented in commons-io [http://jakarta.apache.org/commons/io/api- release/org/apache/commons/i o/File Utils.html#readFileToByteArray(java.io.File)]. Also note that it's a dangerous method as it's limited by the size of the memory and the size of of a byte[] array in Java... If the zip is large it's going to fail... It would be better to implement it with streaming instead, if possible. The first problem is that attachments us an array of bytes and not a stream. If I remember well what ludovic tells me about it is that hibernate does not support it.
Ok. At least we could use commons-io, no? And then we should definitely document in the javadoc why we're not using a stream and the ensuing limitation. I can do this. Yes, it's just I didn't know that was in this lib. Yes, it should be done maybe not on the plugin, but on XWikiAttachement.
I'll do it a bit later once I understand more about the plugin.
* getFileTreeList(). By reading this method's name I don't understand what it does. I also don't understand what is the difference with getFileList() (I haven't analyzed the code). the first one return a list which is for generating a tree, and the second one just the flat file list.
So both return a list. I still don't understand what's different in both method calls... If you have an example then I could possibly write unit tests with it.
Any example?
* Exception handling is very very poor :-) For example:
} catch (XWikiException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } In velocity there is no way to catch the exception, so if we send
an
exception to the page, it brake all the page, so I prefer to not raise the exception. Maybe the best sould be to set a variable with the error and be able to read the list of error.
Hmm... So you're saying that in all xwiki code we're not handling exceptions because of this? I think we should definitely have some error page with the description of the error. No it's not. We don't have defined rules for this. so some code we are doing like this, some code no. We know we should work on this to define a generic way to handle this, it's more a time issue.
Ok. I've created an issue for this: http://jira.xwiki.org/jira/browse/XWIKI-412
* The unit tests seem to be lacking. In any case they're hard to read. I haven't fully understood them yet... I believe they shouldn't test XWiki's core but only the plugin. Not everything is tested because it's too long to write a test for some of this functions(cactus test). We have junit test, but not cactus test.
I don't think we should do cactus tests at all actually. Unit tests are the best for plugins as when we test a plugin the goal is not to test the xwiki core. We should also have functional tests for general tests but the majority of tests should be unit tests (i.e. in isolation from the environment - no container, not database and when possible no files).
Yes, but for the moment we can't. So it's more an issue of time. If we had more time, we can improve this.
The problem is that it gets harder and harder if you don't look into this and funnily in the end it takes more time not to handle it as you then have to handle more manual tests, more bug fixes, you have to explain it to others, others are loosing time when trying to understand the code, etc. Actually for example I've spent about 2-3 hours on the zipexplorer plugin today. If there had been javadoc and tests, I would have spent about 10 minutes to look at it. Multiply this time by the number of people who'll ever look at it and the figure gets huge quickly. Of course this doesn't even taken into account the fact that because of no javadoc and no tests people will help less, etc. :-) Anyway I know how hard it is when you have delivery deadlines... Let's just try to climb back the slope now ;-) I'll be very happy to help as much as I can.
I'm happy to help define how to right unit tests for xwiki. We could use ZipExplorerPlugin as a trial for writing them. It's probably going to require some modifications to the core to some degree. That's the good point of unit tests: they do improve design. Only problem is that xwiki technical debt is quite high at the moment, so it'll cost a lot for the first tests. It'll get better afterwards. let's go.
Cool! -Vincent ___________________________________________________________________________ D�couvrez une nouvelle fa�on d'obtenir des r�ponses � toutes vos questions ! Profitez des connaissances, des opinions et des exp�riences des internautes sur Yahoo! Questions/R�ponses http://fr.answers.yahoo.com
-----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of jeremi joslin Sent: lundi 13 novembre 2006 17:51 To: [email protected] Subject: Re: [xwiki-dev] [Code review] ZipExplorer plugin
[snip]
* The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin.
yes, it's not good, but the zip explorer plugin is doing something special, not standart on xwiki, so we just have this to do it. I know this plugin is not working for exemple in exo.
I have thought more about this and I still believe the best would be to create a XWikiURL class. The reason is that I was looking at randome at the code and noticed the following in downloadAction: public String getFileName(String path, String action) { path = path.substring(path.indexOf("/" + action)); int pos = 0; for (int i = 0; i < 3; i++) { pos = path.indexOf("/", pos + 1); } if (path.indexOf("/", pos + 1) > 0) return path.substring(pos + 1, path.indexOf("/", pos + 1)); return path.substring(pos + 1); } Thus the code in the zipexplorer plugin is actually very close to being a copy paste... :-) What it suggest to me is that there's a domain in xwiki which is URL management and we need a class for it. I'd suggest a XWikiURL class and a XWikiZipURL one for managing Zip URLs which are an extension of standard xwiki URLs. Note that this would remove the copy paste as XWikiZipURL.getFileName() could share the code with XWikiURL.getFileName(). WDYT? [snip] Thanks -Vincent ___________________________________________________________________________ D�couvrez une nouvelle fa�on d'obtenir des r�ponses � toutes vos questions ! Profitez des connaissances, des opinions et des exp�riences des internautes sur Yahoo! Questions/R�ponses http://fr.answers.yahoo.com
Hi, As we talk yesterday, it can be done in XWikiURLFactory. We should add functions to parse an URL and return as you said an XWikiURI. It will fix some problems of JSR168 integration. jeremi On 11/14/06, Vincent Massol <[email protected]> wrote:
-----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of jeremi joslin Sent: lundi 13 novembre 2006 17:51 To: [email protected] Subject: Re: [xwiki-dev] [Code review] ZipExplorer plugin
[snip]
* The getFileName() method can be improved: - first parameter variable must not be modified (the path one in this case). There should always be a local variable created. - I don't think XWiki URI manipulation should be done in this class at all! I'd recommend creating a XWikiURI class in charge of performing all actions on XWiki URI: creation, getting the different part, etc. In this manner is XWiki decides to change the URI format, it'll only be done in one place. This would also remove completely the need for getFileName() from ZipExplorerPlugin.
yes, it's not good, but the zip explorer plugin is doing something special, not standart on xwiki, so we just have this to do it. I know this plugin is not working for exemple in exo.
I have thought more about this and I still believe the best would be to create a XWikiURL class. The reason is that I was looking at randome at the code and noticed the following in downloadAction:
public String getFileName(String path, String action) { path = path.substring(path.indexOf("/" + action)); int pos = 0; for (int i = 0; i < 3; i++) { pos = path.indexOf("/", pos + 1); } if (path.indexOf("/", pos + 1) > 0) return path.substring(pos + 1, path.indexOf("/", pos + 1)); return path.substring(pos + 1); }
Thus the code in the zipexplorer plugin is actually very close to being a copy paste... :-)
What it suggest to me is that there's a domain in xwiki which is URL management and we need a class for it. I'd suggest a XWikiURL class and a XWikiZipURL one for managing Zip URLs which are an extension of standard xwiki URLs. Note that this would remove the copy paste as XWikiZipURL.getFileName() could share the code with XWikiURL.getFileName().
WDYT?
[snip]
Thanks -Vincent
___________________________________________________________________________ Découvrez une nouvelle façon d'obtenir des réponses à toutes vos questions ! Profitez des connaissances, des opinions et des expériences des internautes sur Yahoo! Questions/Réponses http://fr.answers.yahoo.com
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
-- jeremi
participants (2)
-
jeremi joslin -
Vincent Massol