@Override protected synchronized JSON data() { JSONArray r = new JSONArray(); for (User u : modified) { UserInfo i = users.get(u); JSONObject entry = new JSONObject() .accumulate("id", u.getId()) .accumulate("fullName", u.getFullName()) .accumulate("url", u.getUrl()) .accumulate( "avatar", i.avatar != null ? i.avatar : Stapler.getCurrentRequest().getContextPath() + Functions.getResourcePath() + "/images/" + iconSize + "/user.png") .accumulate("timeSortKey", i.getTimeSortKey()) .accumulate("lastChangeTimeString", i.getLastChangeTimeString()); AbstractProject<?, ?> p = i.getProject(); if (p != null) { entry .accumulate("projectUrl", p.getUrl()) .accumulate("projectFullDisplayName", p.getFullDisplayName()); } r.add(entry); } modified.clear(); return r; }
@Override protected void compute() throws Exception { int itemCount = 0; for (Item item : items) { for (Job<?, ?> job : item.getAllJobs()) { if (job instanceof AbstractProject) { AbstractProject<?, ?> p = (AbstractProject) job; RunList<? extends AbstractBuild<?, ?>> builds = p.getBuilds(); int buildCount = 0; for (AbstractBuild<?, ?> build : builds) { if (canceled()) { return; } for (ChangeLogSet.Entry entry : build.getChangeSet()) { User user = entry.getAuthor(); UserInfo info = users.get(user); if (info == null) { UserInfo userInfo = new UserInfo(user, p, build.getTimestamp()); userInfo.avatar = UserAvatarResolver.resolveOrNull(user, iconSize); synchronized (this) { users.put(user, userInfo); modified.add(user); } } else if (info.getLastChange().before(build.getTimestamp())) { synchronized (this) { info.project = p; info.lastChange = build.getTimestamp(); modified.add(user); } } } // TODO consider also adding the user of the UserCause when applicable buildCount++; progress((itemCount + 1.0 * buildCount / builds.size()) / (items.size() + 1)); } } } itemCount++; progress(1.0 * itemCount / (items.size() + /* handling User.getAll */ 1)); } if (unknown != null) { if (canceled()) { return; } for (User u : User.getAll()) { // TODO nice to have a method to iterate these lazily if (u == unknown) { continue; } if (!users.containsKey(u)) { UserInfo userInfo = new UserInfo(u, null, null); userInfo.avatar = UserAvatarResolver.resolveOrNull(u, iconSize); synchronized (this) { users.put(u, userInfo); modified.add(u); } } } } }
public int compareTo(UserInfo that) { long rhs = that.ordinal(); long lhs = this.ordinal(); if (rhs > lhs) return 1; if (rhs < lhs) return -1; return 0; }
private Map<User, UserInfo> getUserInfo(Collection<? extends Item> items) { Map<User, UserInfo> users = new HashMap<User, UserInfo>(); for (Item item : items) { for (Job job : item.getAllJobs()) { if (job instanceof AbstractProject) { AbstractProject<?, ?> p = (AbstractProject) job; for (AbstractBuild<?, ?> build : p.getBuilds()) { for (Entry entry : build.getChangeSet()) { User user = entry.getAuthor(); UserInfo info = users.get(user); if (info == null) users.put(user, new UserInfo(user, p, build.getTimestamp())); else if (info.getLastChange().before(build.getTimestamp())) { info.project = p; info.lastChange = build.getTimestamp(); } } } } } } return users; }
@Override protected void compute() throws Exception { int itemCount = 0; for (Item item : items) { for (Job<?, ?> job : item.getAllJobs()) { if (job instanceof AbstractProject) { AbstractProject<?, ?> p = (AbstractProject) job; RunList<? extends AbstractBuild<?, ?>> builds = p.getBuilds(); int buildCount = 0; for (AbstractBuild<?, ?> build : builds) { if (canceled()) { return; } for (ChangeLogSet.Entry entry : build.getChangeSet()) { User user = entry.getAuthor(); UserInfo info = users.get(user); if (info == null) { UserInfo userInfo = new UserInfo(user, p, build.getTimestamp()); userInfo.avatar = UserAvatarResolver.resolveOrNull(user, iconSize); synchronized (this) { users.put(user, userInfo); modified.add(user); } } else if (info.getLastChange().before(build.getTimestamp())) { synchronized (this) { info.project = p; info.lastChange = build.getTimestamp(); modified.add(user); } } } // TODO consider also adding the user of the UserCause when applicable buildCount++; // TODO this defeats lazy-loading. Should rather do a breadth-first search, as in // hudson.plugins.view.dashboard.builds.LatestBuilds // (though currently there is no quick implementation of RunMap.size() ~ // idOnDisk.size(), which would be needed for proper progress) progress((itemCount + 1.0 * buildCount / builds.size()) / (items.size() + 1)); } } } itemCount++; progress(1.0 * itemCount / (items.size() + /* handling User.getAll */ 1)); } if (unknown != null) { if (canceled()) { return; } for (User u : User.getAll()) { // TODO nice to have a method to iterate these lazily if (canceled()) { return; } if (u == unknown) { continue; } if (!users.containsKey(u)) { UserInfo userInfo = new UserInfo(u, null, null); userInfo.avatar = UserAvatarResolver.resolveOrNull(u, iconSize); synchronized (this) { users.put(u, userInfo); modified.add(u); } } } } }