File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\jenkins\model\ModelObjectWithContextMenu.java.html

1 package jenkins.model;
2
3 import hudson.Functions;
4 import hudson.Util;
5 import hudson.model.Action;
6 import hudson.model.Actionable;
7 import hudson.model.ModelObject;
8 import org.apache.commons.jelly.JellyContext;
9 import org.apache.commons.jelly.JellyException;
10 import org.apache.commons.jelly.JellyTagException;
11 import org.apache.commons.jelly.Script;
12 import org.apache.commons.jelly.XMLOutput;
13 import org.kohsuke.stapler.HttpResponse;
14 import org.kohsuke.stapler.Stapler;
15 import org.kohsuke.stapler.StaplerRequest;
16 import org.kohsuke.stapler.StaplerResponse;
17 import org.kohsuke.stapler.WebApp;
18 import org.kohsuke.stapler.export.Exported;
19 import org.kohsuke.stapler.export.ExportedBean;
20 import org.kohsuke.stapler.export.Flavor;
21 import org.kohsuke.stapler.jelly.JellyClassTearOff;
22 import org.kohsuke.stapler.jelly.JellyFacet;
23 import org.xml.sax.helpers.DefaultHandler;
24
25 import javax.servlet.ServletException;
26 import java.io.IOException;
27 import java.net.URI;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.List;
31
32 /**
33 * {@link ModelObject} that has context menu in the breadcrumb.
34 *
35 * <p>
36 * When the user is visiting a particular page, all the ancestor objects that has {@link ModelObject}
37 * appears in the breadcrumbs. Among those which that also implements {@link ModelObjectWithContextMenu}
38 * shows the drop-down menu for providing quicker access to the actions to those objects.
39 *
40 * @author Kohsuke Kawaguchi
41 */
42 public interface ModelObjectWithContextMenu extends ModelObject {
43 /**
44 * Generates the context menu.
45 *
46 * The typical implementation is {@code return new ContextMenu().from(this,request,response);},
47 * which implements the default behaviour. See {@link ContextMenu#from(ModelObjectWithContextMenu, StaplerRequest, StaplerResponse)}
48 * for more details of what it does. This should suit most implementations.
49 */
50 public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception;
51
52 /**
53 * Data object that represents the context menu.
54 *
55 * Via {@link HttpResponse}, this class is capable of converting itself to JSON that &lt;l:breadcrumb/> understands.
56 */
57 @ExportedBean
58 public class ContextMenu implements HttpResponse {
59 /**
60 * The actual contents of the menu.
61 */
62 @Exported(inline=true)
63 public final List<MenuItem> items = new ArrayList<MenuItem>();
64
65 public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException {
66 rsp.serveExposedBean(req,this,Flavor.JSON);
67 }
68
69 public ContextMenu add(String url, String text) {
70 items.add(new MenuItem(url,null,text));
71 return this;
72 }
73
74 public ContextMenu addAll(Collection<? extends Action> actions) {
75 for (Action a : actions)
76 add(a);
77 return this;
78 }
79
80 public ContextMenu add(Action a) {
81 StaplerRequest req = Stapler.getCurrentRequest();
82 String text = a.getDisplayName();
83 String base = Functions.getIconFilePath(a);
84 if (base==null) return this;
85 String icon = Stapler.getCurrentRequest().getContextPath()+(base.startsWith("images/")?Functions.getResourcePath():"")+'/'+base;
86
87 String url = Functions.getActionUrl(req.findAncestor(ModelObject.class).getUrl(),a);
88
89 return add(url,icon,text);
90 }
91
92 public ContextMenu add(String url, String icon, String text) {
93 if (text != null && icon != null && url != null)
94 items.add(new MenuItem(url,icon,text));
95 return this;
96 }
97
98 /** @since 1.504 */
99 public ContextMenu add(String url, String icon, String text, boolean post) {
100 if (text != null && icon != null && url != null) {
101 MenuItem item = new MenuItem(url,icon,text);
102 item.post = post;
103 items.add(item);
104 }
105 return this;
106 }
107
108 /**
109 * Default implementation of the context menu generation.
110 *
111 * <p>
112 * This method uses {@code sidepanel.groovy} to run the side panel generation, captures
113 * the use of &lt;l:task> tags, and then converts those into {@link MenuItem}s. This is
114 * supposed to make this work with most existing {@link ModelObject}s that follow the standard
115 * convention.
116 *
117 * <p>
118 * Unconventional {@link ModelObject} implementations that do not use {@code sidepanel.groovy}
119 * can override {@link ModelObjectWithContextMenu#doContextMenu(StaplerRequest, StaplerResponse)}
120 * directly to provide alternative semantics.
121 */
122 public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest request, StaplerResponse response) throws JellyException, IOException {
123 return from(self,request,response,"sidepanel");
124 }
125
126 public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest request, StaplerResponse response, String view) throws JellyException, IOException {
127 WebApp webApp = WebApp.getCurrent();
128 final Script s = webApp.getMetaClass(self).getTearOff(JellyClassTearOff.class).findScript(view);
129 if (s!=null) {
130 JellyFacet facet = webApp.getFacet(JellyFacet.class);
131 request.setAttribute("taskTags",this); // <l:task> will look for this variable and populate us
132 request.setAttribute("mode","side-panel");
133 // run sidepanel but ignore generated HTML
134 facet.scriptInvoker.invokeScript(request,response,new Script() {
135 public Script compile() throws JellyException {
136 return this;
137 }
138
139 public void run(JellyContext context, XMLOutput output) throws JellyTagException {
140 Functions.initPageVariables(context);
141 s.run(context,output);
142 }
143 },self,new XMLOutput(new DefaultHandler()));
144 } else
145 if (self instanceof Actionable) {
146 // fallback
147 this.addAll(((Actionable)self).getActions());
148 }
149
150 return this;
151 }
152 }
153
154 /**
155 * Menu item in {@link ContextMenu}
156 */
157 @ExportedBean
158 public class MenuItem {
159 /**
160 * Target of the link.
161 *
162 * This can start with '/', but it must not be a relative URL, since
163 * you cannot really tell which page this context menu is used.
164 */
165 @Exported
166 public String url;
167
168 /**
169 * Human readable caption of the menu item. Do not use HTML.
170 */
171 @Exported
172 public String displayName;
173
174 /**
175 * Optional URL to the icon image. Rendered as 24x24.
176 */
177 @Exported
178 public String icon;
179
180 /**
181 * True to make a POST request rather than GET.
182 * @since 1.504
183 */
184 @Exported public boolean post;
185
186 /**
187 * If this is a submenu, definition of subitems.
188 */
189 @Exported(inline=true)
190 public ContextMenu subMenu;
191
192 public MenuItem(String url, String icon, String displayName) {
193 this.url = URI.create(Stapler.getCurrentRequest().getRequestURI()).resolve(url).toString();
194 this.icon = icon;
195 this.displayName = Util.escape(displayName);
196 }
197 }
198 }
199