
Alfresco was seen as the "low entry cost" solution, Grails requiring more work but being more flexible.
Obviously my main requirement was to be able to upload large files (>10 GB). Obviously this can not be done using the browser and a specific (but simple) client had to be designed. Testing this with Grails took me one day, many tutorials being available [1][2]. With Alfresco despite many post to the forum, I am still stuck to the 2GB limit ...
I decided to go on with Grails. My next step was to be able to visualize the data being stored on the server. For this I decided to use the YUI Treeview component. Here is the controller I used:
// show.gsp will be used
def show = {
}
def dir = {
def cmsId = params.cms
def dir = params.dir?:"/"
// Removing some characters from the path
dir = dir.replaceAll("\\.\\./","")
// Get the root dir for the CMS
String configDir = grailsApplication.config.cmsdata.dir
String target = configDir + cmsId + dir
def files = []
File d = new File(target)
if (d.exists() && d.isDirectory()){
files = d.listFiles()
}
// return back a JSON structure
response.setHeader("Cache-Control", "no-store")
render(contentType: "text/json") {
nodes {
for (f in files) {
node(name: f.name, isDir: f.isDirectory())
}
}
}
}
The view is really simple. When you click on a tree node, the path is constructed the controller is called, the JSON is parsed and new tree nodes are created dynamically differentiating leaf nodes. (Here is the jscript part).
(function(){
// Creating the tree
function buildTree() {
var tree;
tree = new YAHOO.widget.TreeView("treeDiv");
tree.setDynamicLoad(loadNodeData);
var root = tree.getRoot();
var tempNode = new YAHOO.widget.TextNode("/", root, false);
tree.draw();
}
// Processing new nodes
function loadNodeData(node, fnLoadComplete) {
var path = "";
var leafNode = node;
while (!leafNode.isRoot()) {
path = leafNode.label + "/" + path;
leafNode = leafNode.parent;
}
var nodelabel = encodeURI(path);
var sUrl = "${params.cms}/dir?dir="+nodelabel;
var callback = {
success: function(oResponse){
var oResults = YAHOO.lang.JSON.parse(oResponse.responseText);
if ((oResults.nodes)&&(oResults.nodes.length)){
if (YAHOO.lang.isArray(oResults.nodes)) {
for (var i=0; i < oResults.nodes.length; i++){
var tempNode = new YAHOO.widget.TextNode(oResults.nodes[i].name, node, false);
tempNode.isLeaf = !oResults.nodes[i].isDir;
}
}
}
oResponse.argument.fnLoadComplete();
},
failure: function(oResponse){
oResponse.argument.fnLoadComplete();
},
argument:{
"node": node,
"fnLoadComplete":fnLoadComplete
},
timeout:5000
}
YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
};
YAHOO.util.Event.onDOMReady(buildTree);
}());
If you want to work offline (as I did), you have to install the excellent YUI Plugin.
The next step for me is to package this in a YUI panel :)