提交 39be7ffd 编写于 作者: M mindless

Use yui treeview to show 17-40 build artifacts on build/project pages.

Added system properties for LIST_CUTOFF/TREE_CUTOFF values.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@22920 71c3de6d-444a-0410-be80-ed276b4c234a
上级 d3c2d485
......@@ -73,6 +73,7 @@ import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
......@@ -718,12 +719,12 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
}
/**
* Gets the first {@value #CUTOFF} artifacts (relative to {@link #getArtifactsDir()}.
* Gets the first {@value #TREE_CUTOFF} artifacts (relative to {@link #getArtifactsDir()}.
*/
@Exported
public List<Artifact> getArtifacts() {
ArtifactList r = new ArtifactList();
addArtifacts(getArtifactsDir(),"","",r);
addArtifacts(getArtifactsDir(),"","",r,null);
r.computeDisplayName();
return r;
}
......@@ -738,26 +739,58 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
return !getArtifacts().isEmpty();
}
private void addArtifacts( File dir, String path, String pathHref, List<Artifact> r ) {
private void addArtifacts( File dir, String path, String pathHref, ArtifactList r, Artifact parent ) {
String[] children = dir.list();
if(children==null) return;
String childPath, childHref;
boolean collapsed;
Artifact a;
for (String child : children) {
if(r.size()>CUTOFF)
if(r.size()>TREE_CUTOFF)
return;
childPath = path + child;
childHref = pathHref + Util.rawEncode(child);
File sub = new File(dir, child);
collapsed = (children.length==1 && parent!=null);
if (collapsed) {
// Collapse single items into parent node where possible:
a = new Artifact(parent.getFileName() + '/' + child, childPath,
sub.isDirectory() ? null : childHref, parent.getTreeNodeId());
r.tree.put(a, r.tree.remove(parent));
} else {
// Use null href for a directory:
a = new Artifact(child, childPath,
sub.isDirectory() ? null : childHref, "n" + ++r.idSeq);
r.tree.put(a, parent!=null ? parent.getTreeNodeId() : null);
}
if (sub.isDirectory()) {
addArtifacts(sub, path + child + '/', pathHref + Util.rawEncode(child) + '/', r);
addArtifacts(sub, childPath + '/', childHref + '/', r, a);
} else {
r.add(new Artifact(path + child, pathHref + Util.rawEncode(child)));
// Don't store collapsed path in ArrayList (for correct data in external API)
r.add(collapsed ? new Artifact(child, a.relativePath, a.href, a.treeNodeId) : a);
}
}
}
private static final int CUTOFF = 17; // 0, 1,... 16, and then "too many"
public static final int
LIST_CUTOFF = Integer.parseInt(System.getProperty("hudson.model.Run.ArtifactList.listCutoff", "16")),
TREE_CUTOFF = Integer.parseInt(System.getProperty("hudson.model.Run.ArtifactList.treeCutoff", "40"));
// ..and then "too many"
public final class ArtifactList extends ArrayList<Artifact> {
/**
* Map of Artifact to treeNodeId of parent node in tree view.
* Contains Artifact objects for directories and files (the ArrayList contains only files).
*/
private LinkedHashMap<Artifact,String> tree = new LinkedHashMap<Artifact,String>();
private int idSeq = 0;
public Map<Artifact,String> getTree() {
return tree;
}
public void computeDisplayName() {
if(size()>CUTOFF) return; // we are not going to display file names, so no point in computing this
if(size()>LIST_CUTOFF) return; // we are not going to display file names, so no point in computing this
int maxDepth = 0;
int[] len = new int[size()];
......@@ -843,11 +876,28 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
*/
/*package*/ String displayPath;
/**
* The filename of the artifact.
* (though when directories with single items are collapsed for tree view, name may
* include multiple path components, like "dist/pkg/mypkg")
*/
private String name;
/**
* Properly encoded relativePath for use in URLs. This field is null for directories.
*/
private String href;
/*package for test*/ Artifact(String relativePath, String href) {
/**
* Id of this node for use in tree view.
*/
private String treeNodeId;
/*package for test*/ Artifact(String name, String relativePath, String href, String treeNodeId) {
this.name = name;
this.relativePath = relativePath;
this.href = href;
this.treeNodeId = treeNodeId;
}
/**
......@@ -862,7 +912,7 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
*/
@Exported(visibility=3)
public String getFileName() {
return getFile().getName();
return name;
}
@Exported(visibility=3)
......@@ -874,6 +924,10 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
return href;
}
public String getTreeNodeId() {
return treeNodeId;
}
@Override
public String toString() {
return relativePath;
......
......@@ -41,7 +41,7 @@ THE SOFTWARE.
<j:if test="${!build.building and !empty(artifacts)}">
<t:summary icon="package.gif">
<j:choose>
<j:when test="${size(artifacts) lt 17}">
<j:when test="${size(artifacts) le build.LIST_CUTOFF}">
<!-- if not too many, just list them -->
${caption}<br />
<ul>
......@@ -54,11 +54,37 @@ THE SOFTWARE.
</j:forEach>
</ul>
</j:when>
<j:when test="${size(artifacts) le build.TREE_CUTOFF}">
<!-- otherwise (unless way too many) use a tree view -->
<l:yui module="treeview"/>
<link rel="stylesheet" href="${resURL}/scripts/yui/treeview/assets/skins/sam/treeview.css" type="text/css"/>
<link rel="stylesheet" href="${resURL}/scripts/yui/fonts/fonts-min.css" type="text/css"/>
<style type="text/css">#artifact-tree td { vertical-align:middle; }</style>
<div id="artifact-tree"></div>
<script language="javascript">// &lt;![CDATA[
YAHOO.util.Event.onContentReady('artifact-tree', function () {
var artifactTree = new YAHOO.widget.TreeView('artifact-tree');
var artifactRoot = new YAHOO.widget.TextNode('${h.jsStringEscape(caption)}',
artifactTree.getRoot(), false);
<j:forEach var="e" items="${artifacts.getTree().entrySet()}">
<j:set var="f" value="${e.key}"/>
var ${f.treeNodeId} = new YAHOO.widget.TextNode(
'${h.jsStringEscape(f.fileName)}', ${e.value?:'artifactRoot'}, false);
<j:if test="${f.href!=null}">
<!-- Assign href property instead of passing to constructor above,
as constructor does urlencoding, but f.href is already encoded -->
${f.treeNodeId}.href = '${baseURL}artifact/${h.jsStringEscape(f.href)}';
</j:if>
</j:forEach>
artifactTree.draw();
});
// ]]&gt;</script>
</j:when>
<j:otherwise>
<!-- otherwise use a tree view -->
<!-- otherwise use a link to directory browser -->
<a href="${baseURL}artifact/">${caption}</a>
</j:otherwise>
</j:choose>
</t:summary>
</j:if>
</j:jelly>
\ No newline at end of file
</j:jelly>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册