[MRM-1620] add a tab to browse artifact content in artifact detail view

start displaying content

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1339396 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Olivier Lamy 2012-05-16 22:18:05 +00:00
parent ff8de40f52
commit a1dc0ff5ab
32 changed files with 296 additions and 38 deletions

View File

@ -29,32 +29,40 @@ import java.io.Serializable;
public class ArtifactContentEntry
implements Serializable
{
private String name;
private String text;
private boolean file;
private int depth;
private boolean hasChildren;
public ArtifactContentEntry()
{
// no op
}
public ArtifactContentEntry( String name, boolean file, int depth )
public ArtifactContentEntry( String text, boolean file, int depth, boolean hasChildren )
{
this.name = name;
this.text = text;
this.file = file;
this.depth = depth;
this.hasChildren = hasChildren;
}
public String getName()
public String getText()
{
return name;
return text;
}
public void setName( String name )
public String getId()
{
this.name = name;
return text;
}
public void setText( String text )
{
this.text = text;
}
public boolean isFile()
@ -77,18 +85,18 @@ public class ArtifactContentEntry
this.depth = depth;
}
@Override
public String toString()
public boolean isHasChildren()
{
final StringBuilder sb = new StringBuilder();
sb.append( "ArtifactContentEntry" );
sb.append( "{name='" ).append( name ).append( '\'' );
sb.append( ", file=" ).append( file );
sb.append( ", depth=" ).append( depth );
sb.append( '}' );
return sb.toString();
return hasChildren;
}
public void setHasChildren( boolean hasChildren )
{
this.hasChildren = hasChildren;
}
@Override
public boolean equals( Object o )
{
@ -103,6 +111,10 @@ public class ArtifactContentEntry
ArtifactContentEntry that = (ArtifactContentEntry) o;
if ( hasChildren != that.hasChildren )
{
return false;
}
if ( depth != that.depth )
{
return false;
@ -111,7 +123,7 @@ public class ArtifactContentEntry
{
return false;
}
if ( !name.equals( that.name ) )
if ( text != null ? !text.equals( that.text ) : that.text != null )
{
return false;
}
@ -122,9 +134,23 @@ public class ArtifactContentEntry
@Override
public int hashCode()
{
int result = name.hashCode();
int result = text != null ? text.hashCode() : 0;
result = 31 * result + ( file ? 1 : 0 );
result = 31 * result + depth;
result = 31 * result + ( hasChildren ? 1 : 0 );
return result;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "ArtifactContentEntry" );
sb.append( "{text='" ).append( text ).append( '\'' );
sb.append( ", file=" ).append( file );
sb.append( ", depth=" ).append( depth );
sb.append( ", children=" ).append( hasChildren );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -660,10 +660,10 @@ public class DefaultBrowseService
{
Map<String, ArtifactContentEntry> artifactContentEntryMap = new HashMap<String, ArtifactContentEntry>();
int filterDepth = StringUtils.countMatches( filterPath, "/" );
if ( filterDepth == 0 )
/*if ( filterDepth == 0 )
{
filterDepth = 1;
}
}*/
JarFile jarFile = new JarFile( file );
try
{
@ -676,7 +676,8 @@ public class DefaultBrowseService
currentEntry.getName(), "/" ) : currentEntry.getName();
String entryRootPath = getRootPath( cleanedEntryName );
int depth = StringUtils.countMatches( cleanedEntryName, "/" );
if ( StringUtils.isEmpty( filterPath ) && !artifactContentEntryMap.containsKey( entryRootPath ) )
if ( StringUtils.isEmpty( filterPath ) && !artifactContentEntryMap.containsKey( entryRootPath )
&& depth == filterDepth )
{
artifactContentEntryMap.put( entryRootPath,
@ -685,7 +686,7 @@ public class DefaultBrowseService
}
else
{
if ( StringUtils.startsWith( cleanedEntryName, filterPath ) && ( depth >= filterDepth || (
if ( StringUtils.startsWith( cleanedEntryName, filterPath ) && ( depth == filterDepth || (
!currentEntry.isDirectory() && depth == filterDepth ) ) )
{
artifactContentEntryMap.put( cleanedEntryName, new ArtifactContentEntry( cleanedEntryName,

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

View File

@ -0,0 +1,91 @@
UL.jqueryFileTree {
font-family: Verdana, sans-serif;
font-size: 11px;
line-height: 18px;
padding: 0px;
margin: 0px;
}
UL.jqueryFileTree LI {
list-style: none;
padding: 0px;
padding-left: 20px;
margin: 0px;
white-space: nowrap;
}
UL.jqueryFileTree A {
color: #333;
text-decoration: none;
display: block;
padding: 0px 2px;
}
UL.jqueryFileTree A:hover {
background: #BDF;
}
/* Core Styles */
.jqueryFileTree LI.directory { background: url(images/directory.png) left top no-repeat; }
.jqueryFileTree LI.expanded { background: url(images/folder_open.png) left top no-repeat; }
.jqueryFileTree LI.file { background: url(images/file.png) left top no-repeat; }
.jqueryFileTree LI.wait { background: url(images/spinner.gif) left top no-repeat; }
/* File Extensions*/
.jqueryFileTree LI.ext_3gp { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_afp { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_afpa { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_asp { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_aspx { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_avi { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_bat { background: url(images/application.png) left top no-repeat; }
.jqueryFileTree LI.ext_bmp { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_c { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_cfm { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_cgi { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_com { background: url(images/application.png) left top no-repeat; }
.jqueryFileTree LI.ext_cpp { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_css { background: url(images/css.png) left top no-repeat; }
.jqueryFileTree LI.ext_doc { background: url(images/doc.png) left top no-repeat; }
.jqueryFileTree LI.ext_exe { background: url(images/application.png) left top no-repeat; }
.jqueryFileTree LI.ext_gif { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_fla { background: url(images/flash.png) left top no-repeat; }
.jqueryFileTree LI.ext_h { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_htm { background: url(images/html.png) left top no-repeat; }
.jqueryFileTree LI.ext_html { background: url(images/html.png) left top no-repeat; }
.jqueryFileTree LI.ext_jar { background: url(images/java.png) left top no-repeat; }
.jqueryFileTree LI.ext_jpg { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_jpeg { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_js { background: url(images/script.png) left top no-repeat; }
.jqueryFileTree LI.ext_lasso { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_log { background: url(images/txt.png) left top no-repeat; }
.jqueryFileTree LI.ext_m4p { background: url(images/music.png) left top no-repeat; }
.jqueryFileTree LI.ext_mov { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_mp3 { background: url(images/music.png) left top no-repeat; }
.jqueryFileTree LI.ext_mp4 { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_mpg { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_mpeg { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_ogg { background: url(images/music.png) left top no-repeat; }
.jqueryFileTree LI.ext_pcx { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_pdf { background: url(images/pdf.png) left top no-repeat; }
.jqueryFileTree LI.ext_php { background: url(images/php.png) left top no-repeat; }
.jqueryFileTree LI.ext_png { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_ppt { background: url(images/ppt.png) left top no-repeat; }
.jqueryFileTree LI.ext_psd { background: url(images/psd.png) left top no-repeat; }
.jqueryFileTree LI.ext_pl { background: url(images/script.png) left top no-repeat; }
.jqueryFileTree LI.ext_py { background: url(images/script.png) left top no-repeat; }
.jqueryFileTree LI.ext_rb { background: url(images/ruby.png) left top no-repeat; }
.jqueryFileTree LI.ext_rbx { background: url(images/ruby.png) left top no-repeat; }
.jqueryFileTree LI.ext_rhtml { background: url(images/ruby.png) left top no-repeat; }
.jqueryFileTree LI.ext_rpm { background: url(images/linux.png) left top no-repeat; }
.jqueryFileTree LI.ext_ruby { background: url(images/ruby.png) left top no-repeat; }
.jqueryFileTree LI.ext_sql { background: url(images/db.png) left top no-repeat; }
.jqueryFileTree LI.ext_swf { background: url(images/flash.png) left top no-repeat; }
.jqueryFileTree LI.ext_tif { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_tiff { background: url(images/picture.png) left top no-repeat; }
.jqueryFileTree LI.ext_txt { background: url(images/txt.png) left top no-repeat; }
.jqueryFileTree LI.ext_vb { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_wav { background: url(images/music.png) left top no-repeat; }
.jqueryFileTree LI.ext_wmv { background: url(images/film.png) left top no-repeat; }
.jqueryFileTree LI.ext_xls { background: url(images/xls.png) left top no-repeat; }
.jqueryFileTree LI.ext_xml { background: url(images/code.png) left top no-repeat; }
.jqueryFileTree LI.ext_zip { background: url(images/zip.png) left top no-repeat; }

View File

@ -2,6 +2,7 @@
<html>
<head>
<link rel="stylesheet" href="css/jquery.fileupload-ui.css"/>
<link rel="stylesheet" href="css/jqueryFileTree.css"/>
<link rel="stylesheet" href="css/chosen-0.9.7.css"/>
<link rel="stylesheet" href="css/jquery-ui-1.8.16.custom.css"/>
<link rel="stylesheet" href="css/bootstrap.2.0.3.css">
@ -101,6 +102,10 @@
"jquery.fileupload.ip":"jquery.fileupload-ip-1.0.6",
"jquery.fileupload.ui":"jquery.fileupload-ui-6.6.3",
"tmpl": "tmpl.min",
"treeview": "jquery.treeview-1.5-pre",
"treeview.async":"jquery.treeview.async-0.1",
"jquery.treeview.edit": "jquery.treeview.edit",
"jqueryFileTree": "jqueryFileTree-1.0.1",
"redback": "redback/redback",
"redback.roles": "redback/roles",
"redback.user": "redback/user",

View File

@ -16,7 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knockout.simpleGrid"], function() {
define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knockout.simpleGrid","treeview"
,"treeview.async","jquery.treeview.edit","jqueryFileTree"], function() {
@ -272,6 +273,20 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
if ($(e.target).attr("href")=="#artifact-details-file-content") {
$.log("file content:"+self.groupId+":"+self.artifactId+":"+self.version);
var entriesUrl = "restServices/archivaServices/browseService/artifactContentEntries/"+encodeURIComponent(self.groupId);
entriesUrl+="/"+encodeURIComponent(self.artifactId)+"/"+encodeURIComponent(self.version);
entriesUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository());
//entriesUrl+="&p="+encodeURIComponent(artifactContentEntry.name);
$("#main-content #artifact_content_tree").fileTree({
script: entriesUrl,
root: ""
},function(file) {
alert(file);
});
return;
var entriesUrl = "restServices/archivaServices/browseService/artifactContentEntries/"+encodeURIComponent(self.groupId);
entriesUrl+="/"+encodeURIComponent(self.artifactId)+"/"+encodeURIComponent(self.version);
entriesUrl+="?repositoryId="+encodeURIComponent(self.repositoryId);
@ -279,10 +294,12 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
type: "GET",
dataType: 'json',
success: function(data) {
//$("#artifact-details-file-content").html($("#artifact_content_tmpl").tmpl());//{artifactContentEntries:mapArtifactContentEntries(data)}));
//artifact_content_tmpl
var artifactContentEntryViewModel=
new ArtifactContentEntryViewModel(self.groupId,self.artifactId,self.version,mapArtifactContentEntries(data));
$("#artifact-details-file-content").html($("#artifact_content_main_tmpl").tmpl());
ko.applyBindings(artifactContentEntryViewModel,mainContent.find("#artifact_file_content_div").get(0));
new ArtifactContentEntryViewModel(self.groupId,self.artifactId,self.version,[]);
artifactContentEntryViewModel.show();
//ko.applyBindings(artifactContentEntryViewModel,mainContent.find("#artifact_file_content_div").get(0));
}
});
}
@ -386,10 +403,11 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
}
ArtifactContentEntry=function(name,file,depth){
this.name=name;
ArtifactContentEntry=function(text,file,depth,id){
this.text=text;
this.file=file;
this.depth=depth;
this.id=id;
}
mapArtifactContentEntries=function(data){
@ -398,10 +416,10 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
}
if ( $.isArray(data)){
return $.map(data,function(e){
return new ArtifactContentEntry(e.name,e.file,e.depth);
return new ArtifactContentEntry(e.text,e.file,e.depth,e.id);
})
}
return new ArtifactContentEntry(data.name,data.file,data.depth);
return new ArtifactContentEntry(data.text,data.file,data.depth,e.id);
}
ArtifactContentEntryViewModel=function(groupId,artifactId,version,artifactContentEntries){
@ -410,7 +428,20 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
this.artifactId=artifactId;
this.version=version;
this.artifactContentEntries=ko.observableArray(artifactContentEntries);
$.log("size:"+this.artifactContentEntries().length);
this.currentPath=ko.observable();
this.show=function(){
var entriesUrl = "restServices/archivaServices/browseService/artifactContentEntries/"+encodeURIComponent(self.groupId);
entriesUrl+="/"+encodeURIComponent(self.artifactId)+"/"+encodeURIComponent(self.version);
entriesUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository());
//entriesUrl+="&p="+encodeURIComponent(artifactContentEntry.name);
$("#main-content #artifact_content_tree").fileTree({
script: entriesUrl
},function(file) {
alert(file);
});
}
entries=function(){
return self.artifactContentEntries;
@ -423,6 +454,7 @@ define("search",["jquery","i18n","jquery.tmpl","choosen","order!knockout","knock
entriesUrl+="/"+encodeURIComponent(self.artifactId)+"/"+encodeURIComponent(self.version);
entriesUrl+="?repositoryId="+encodeURIComponent(getSelectedBrowsingRepository());
entriesUrl+="&p="+encodeURIComponent(artifactContentEntry.name);
self.currentPath(artifactContentEntry.name);
$.ajax(entriesUrl,{
type: "GET",
dataType: 'json',

View File

@ -0,0 +1,96 @@
// jQuery File Tree Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
//
// Usage: $('.fileTreeDemo').fileTree( options, callback )
//
// Options: root - root folder to display; default = /
// script - location of the serverside AJAX file to use; default = jqueryFileTree.php
// folderEvent - event to trigger expand/collapse; default = click
// expandSpeed - default = 500 (ms); use -1 for no animation
// collapseSpeed - default = 500 (ms); use -1 for no animation
// expandEasing - easing function to use on expand (optional)
// collapseEasing - easing function to use on collapse (optional)
// multiFolder - whether or not to limit the browser to one subfolder at a time
// loadMessage - Message to display while initial tree loads (can be HTML)
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
// 1.00 - released (24 March 2008)
//
// TERMS OF USE
//
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC.
//
if(jQuery) (function($){
$.extend($.fn, {
fileTree: function(o, h) {
// Defaults
if( !o ) var o = {};
if( o.root == undefined ) o.root = '/';
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
if( o.folderEvent == undefined ) o.folderEvent = 'click';
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
if( o.expandEasing == undefined ) o.expandEasing = null;
if( o.collapseEasing == undefined ) o.collapseEasing = null;
if( o.multiFolder == undefined ) o.multiFolder = true;
if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';
$(this).each( function() {
function showTree(c, t) {
$(c).addClass('wait');
$(".jqueryFileTree.start").remove();
$.get(o.script, { p: t }, function(data) {
$(c).find('.start').html('');
var htmlContent = $("#artifact_content_tree_partial" ).tmpl({artifactContentEntries:mapArtifactContentEntries(data)});
$(c).removeClass('wait').append(htmlContent);
if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });
bindTree(c);
});
}
function bindTree(t) {
$(t).find('LI A').bind(o.folderEvent, function() {
if( $(this).parent().hasClass('directory') ) {
if( $(this).parent().hasClass('collapsed') ) {
// Expand
if( !o.multiFolder ) {
$(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
}
$(this).parent().find('UL').remove(); // cleanup
showTree( $(this).parent(), escape($(this).attr('rel')) );//.match( /.*\// )
$(this).parent().removeClass('collapsed').addClass('expanded');
} else {
// Collapse
$(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().removeClass('expanded').addClass('collapsed');
}
} else {
h($(this).attr('rel'));
}
return false;
});
// Prevent A from triggering the # on non-click events
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
}
// Loading message
$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
// Get the initial file list
showTree( $(this), escape(o.root) );
});
}
});
})(jQuery);

View File

@ -629,6 +629,8 @@
</div>
<div id="artifact-details-file-content" class="tab-pane">
<div id="artifact_content_tree">
</div>
</div>
<div id="artifact-details-used-by-content" class="tab-pane"></div>
@ -796,10 +798,15 @@
</script>
<script id="artifact_content_tmpl" type="text/html">
<ul>
{{each(i, artifactContentEntry) artifactContentEntries()}}
<li data-bind="css: { 'browse-list': artifactContentEntry.file==false }">
<a href="#" data-bind="click: function(){displayPath(artifactContentEntry)}">${artifactContentEntry.name}</a>
<div id="artifact_content_tree">
</div>
</script>
<script id="artifact_content_tree_partial" type="text/html">
<ul class="jqueryFileTree" style="display: none;">
{{each artifactContentEntries}}
<li class="directory collapsed">
<a href="#" rel="${$value.text}/">${$value.text}</a>
</li>
{{/each}}
</ul>