package com.gitblit.wicket.panels; import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.PageParameters; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.RepeatingView; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Keys; import com.gitblit.models.RepositoryModel; import com.gitblit.models.TreeNodeModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.ModelUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.pages.BasePage; import com.gitblit.wicket.pages.ProjectPage; import com.gitblit.wicket.pages.SummaryPage; import com.gitblit.wicket.pages.UserPage; public class NestedRepositoryTreePanel extends BasePanel { private static final long serialVersionUID = 1L; public NestedRepositoryTreePanel(final String wicketId, final IModel model, final Map accessRestrictionTranslations, final boolean linksActive) { super(wicketId); final boolean showSize = app().settings().getBoolean(Keys.web.showRepositorySizes, true); final boolean showSwatch = app().settings().getBoolean(Keys.web.repositoryListSwatches, true); final TreeNodeModel node = model.getObject(); Fragment nodeHeader = new Fragment("nodeHeader", "groupRepositoryRow", this); add(nodeHeader); WebMarkupContainer firstColumn = new WebMarkupContainer("firstColumn"); nodeHeader.add(firstColumn); RepeatingView depth = new RepeatingView("depth"); for(int i=0; i("repositories", node.getRepositories()) { private static final long serialVersionUID = 1L; int counter = 0; @Override public boolean isVisible() { return super.isVisible() && !node.getRepositories().isEmpty(); } @Override protected void populateItem(ListItem item) { RepositoryModel entry = item.getModelObject(); WebMarkupContainer rowContent = new WebMarkupContainer("rowContent"); item.add(rowContent); addChildOfNodeIdCssClassesToRow(rowContent, node); WebMarkupContainer firstColumn = new WebMarkupContainer("firstColumn"); rowContent.add(firstColumn); RepeatingView depth = new RepeatingView("depth"); for(int i=0; i linkPage = SummaryPage.class; PageParameters pp = WicketUtils.newRepositoryParameter(entry.name); firstColumn.add(new LinkPanel("repositoryName", "list", repoName, linkPage, pp)); rowContent.add(new LinkPanel("repositoryDescription", "list", entry.description, linkPage, pp)); } else { // no links like on a federation page firstColumn.add(new Label("repositoryName", repoName)); rowContent.add(new Label("repositoryDescription", entry.description)); } if (entry.hasCommits) { // Existing repository rowContent.add(new Label("repositorySize", entry.size).setVisible(showSize)); } else { // New repository rowContent.add(new Label("repositorySize", "(" + getString("gb.empty") + ")").setEscapeModelStrings(false)); } if (entry.isSparkleshared()) { rowContent.add(WicketUtils.newImage("sparkleshareIcon", "star_16x16.png", getString("gb.isSparkleshared"))); } else { rowContent.add(WicketUtils.newClearPixel("sparkleshareIcon").setVisible(false)); } if (!entry.isMirror && entry.isFrozen) { rowContent.add(WicketUtils.newImage("frozenIcon", "cold_16x16.png", getString("gb.isFrozen"))); } else { rowContent.add(WicketUtils.newClearPixel("frozenIcon").setVisible(false)); } if (entry.isFederated) { rowContent.add(WicketUtils.newImage("federatedIcon", "federated_16x16.png", getString("gb.isFederated"))); } else { rowContent.add(WicketUtils.newClearPixel("federatedIcon").setVisible(false)); } if (entry.isMirror) { rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "mirror_16x16.png", getString("gb.isMirror"))); } else { switch (entry.accessRestriction) { case NONE: rowContent.add(WicketUtils.newBlankImage("accessRestrictionIcon")); break; case PUSH: rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); break; case CLONE: rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); break; case VIEW: rowContent.add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", accessRestrictionTranslations.get(entry.accessRestriction))); break; default: rowContent.add(WicketUtils.newBlankImage("accessRestrictionIcon")); } } String owner = ""; if (!ArrayUtils.isEmpty(entry.owners)) { // display first owner for (String username : entry.owners) { UserModel ownerModel = app().users().getUserModel(username); if (ownerModel != null) { owner = ownerModel.getDisplayName(); break; } } if (entry.owners.size() > 1) { owner += ", ..."; } } Label ownerLabel = new Label("repositoryOwner", owner); WicketUtils.setHtmlTooltip(ownerLabel, ArrayUtils.toString(entry.owners)); rowContent.add(ownerLabel); String lastChange; if (entry.lastChange.getTime() == 0) { lastChange = "--"; } else { lastChange = getTimeUtils().timeAgo(entry.lastChange); } Label lastChangeLabel = new Label("repositoryLastChange", lastChange); rowContent.add(lastChangeLabel); WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange)); if (!StringUtils.isEmpty(entry.lastChangeAuthor)) { WicketUtils.setHtmlTooltip(lastChangeLabel, getString("gb.author") + ": " + entry.lastChangeAuthor); } String clazz = counter % 2 == 0 ? "light" : "dark"; WicketUtils.addCssClass(rowContent, clazz); counter++; } }); add(new ListView("subFolders", node.getSubFolders()) { private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem item) { item.add(new NestedRepositoryTreePanel("rowContent", item.getModel(), accessRestrictionTranslations, linksActive)); } @Override public boolean isVisible() { return super.isVisible() && !node.getSubFolders().isEmpty(); } }); } private void addChildOfNodeIdCssClassesToRow(Component row, TreeNodeModel parentNode) { row.add(new AttributeAppender("class", Model.of("child-of-"+ parentNode.hashCode()), " ")); if(parentNode.getParent() != null) { addChildOfNodeIdCssClassesToRow(row, parentNode.getParent()); } } }