Skip to content
Permalink
Browse files

Merge pull request #74 from jenkinsci/jenkins-39213

[JENKINS-39213] Add ability for computed folders to control the views in the folder
  • Loading branch information...
stephenc committed Dec 5, 2016
2 parents c95e459 + 863dc35 commit 0d9318d1ecfd3f36d2691e3245731be5b29b8d50

Large diffs are not rendered by default.

@@ -25,16 +25,49 @@
package com.cloudbees.hudson.plugins.folder;

import com.cloudbees.hudson.plugins.folder.health.FolderHealthMetricDescriptor;
import hudson.model.DescriptorVisibilityFilter;
import hudson.model.TopLevelItemDescriptor;
import hudson.views.ViewsTabBar;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;
import org.jenkins.ui.icon.IconSpec;
import org.kohsuke.stapler.MetaClass;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.WebApp;
import org.kohsuke.stapler.jelly.DefaultScriptInvoker;
import org.kohsuke.stapler.jelly.JellyClassTearOff;

/**
* Category of {@link AbstractFolder}.
* @since 4.11-beta-1
*/
public abstract class AbstractFolderDescriptor extends TopLevelItemDescriptor {

public abstract class AbstractFolderDescriptor extends TopLevelItemDescriptor implements IconSpec {

/**
* Explicit constructor.
*
* @param clazz the explicit {@link AbstractFolder} sub-class that this descriptor is for.
* @see TopLevelItemDescriptor#TopLevelItemDescriptor(Class)
*/
protected AbstractFolderDescriptor(Class<? extends AbstractFolder> clazz) {
super(clazz);
}

/**
* Default constructor.
*
* @see TopLevelItemDescriptor#TopLevelItemDescriptor()
*/
protected AbstractFolderDescriptor() {
}

@Override
public String getDisplayName() {
return Messages.Folder_DisplayName();
@@ -72,4 +105,82 @@ public String getCategoryId() {
return r;
}

/**
* Gets the {@link FolderIconDescriptor}s applicable for this folder type.
*
* @since FIXME
*/
public List<FolderIconDescriptor> getIconDescriptors() {
List<FolderIconDescriptor> r = new ArrayList<FolderIconDescriptor>();
for (FolderIconDescriptor p : FolderIconDescriptor.all()) {
if (p.isApplicable(clazz.asSubclass(AbstractFolder.class))) {
r.add(p);
}
}
StaplerRequest request = Stapler.getCurrentRequest();
if (request != null) {
AbstractFolder folder = request.findAncestorObject(AbstractFolder.class);
if (folder != null) {
return DescriptorVisibilityFilter.apply(folder, r);
}
}
return r;
}

// TODO remove once baseline 2.0
public String getDescription() {
Stapler stapler = Stapler.getCurrent();
if (stapler != null) {
try {
WebApp webapp = WebApp.getCurrent();
MetaClass meta = webapp.getMetaClass(this);
Script s = meta.loadTearOff(JellyClassTearOff.class).findScript("newInstanceDetail");
if (s == null) {
return "";
}
DefaultScriptInvoker dsi = new DefaultScriptInvoker();
StringWriter sw = new StringWriter();
XMLOutput xml = dsi.createXMLOutput(sw, true);
dsi.invokeScript(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), s, this, xml);
return sw.toString();
} catch (Exception e) {
Logger.getLogger(clazz.getName()).log(Level.WARNING, e.getMessage(), e);
return "";
}
} else {
return "";
}
}

/**
* Needed if it wants Folder are categorized in Jenkins 2.x.
*
* TODO: Override when the baseline is upgraded to 2.x
*
* @return A string it represents a URL pattern to get the Item icon in different sizes.
*/
public String getIconFilePathPattern() {
return "plugin/cloudbees-folder/images/:size/folder.png";
}

/**
* {@inheritDoc}
*/
@Override
public String getIconClassName() {
return "icon-folder";
}

public boolean isIconConfigurable() {
return getIconDescriptors().size() > 1;
}

public boolean isTabBarConfigurable() {
return Jenkins.getActiveInstance().getDescriptorList(ViewsTabBar.class).size() > 1;
}

public boolean isLookAndFeelConfigurable(AbstractFolder<?> folder) {
return isIconConfigurable() || (isTabBarConfigurable() && folder.getFolderViews().isTabBarModifiable()) || (folder.getViews().size() > 1 && folder.getFolderViews().isPrimaryModifiable());
}

}
@@ -340,7 +340,7 @@ public DescriptorImpl getDescriptor() {
}

@Extension
public static class DescriptorImpl extends AbstractFolderDescriptor implements IconSpec {
public static class DescriptorImpl extends AbstractFolderDescriptor {

/**
* Needed if it wants Folders are categorized in Jenkins 2.x.
@@ -353,22 +353,6 @@ public String getDescription() {
return Messages.Folder_Description();
}

/**
* Needed if it wants Folder are categorized in Jenkins 2.x.
*
* TODO: Override when the baseline is upgraded to 2.x
*
* @return A string it represents a URL pattern to get the Item icon in different sizes.
*/
public String getIconFilePathPattern() {
return "plugin/cloudbees-folder/images/:size/folder.png";
}

@Override
public String getIconClassName() {
return "icon-folder";
}

@Override
public TopLevelItem newInstance(ItemGroup parent, String name) {
return new Folder(parent, name);
@@ -32,5 +32,16 @@
public static DescriptorExtensionList<FolderIcon, FolderIconDescriptor> all() {
return Jenkins.getActiveInstance().<FolderIcon, FolderIconDescriptor>getDescriptorList(FolderIcon.class);
}
// TODO consider adding an isApplicable method

/**
* Returns true if this {@link FolderIcon} type is applicable to the
* given job type.
*
* @param folderType the type of folder.
* @return true to indicate applicable, in which case the icon will be
* displayed in the configuration screen of this folder.
*/
public boolean isApplicable(Class<? extends AbstractFolder> folderType) {
return true;
}
}
@@ -25,13 +25,18 @@
package com.cloudbees.hudson.plugins.folder.computed;

import hudson.model.Item;
import hudson.model.TaskListener;
import hudson.model.TopLevelItem;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import javax.annotation.CheckForNull;

/**
* Callback for {@link ComputedFolder}.
* Methods may be called only inside the scope of {@link ComputedFolder#computeChildren}.
* Methods may be called only inside the scope of {@link ComputedFolder#computeChildren} or an out-of-band event handler.
* @see ComputedFolder#computeChildren(ChildObserver, TaskListener)
* @see ComputedFolder#createEventsChildObserver()
*/
public abstract class ChildObserver<I extends TopLevelItem> {

@@ -58,4 +63,20 @@
*/
public abstract void created(I child);

/**
* Returns a copy of the item names that have been observed.
*
* @return a copy of the item names that have been observed.
* @since FIXME
*/
public abstract Set<String> observed();

/**
* Returns a copy of the map of orphaned items keyed by name.
*
* @return a copy of the map of orphaned items keyed by name.
* @since FIXME
*/
public abstract Map<String,I> orphaned();

}

0 comments on commit 0d9318d

Please sign in to comment.
You can’t perform that action at this time.