@Restricted(DoNotUse.class) // accessed via REST API public HttpResponse doGenerateSnippet(StaplerRequest req, @QueryParameter String json) throws Exception { // TODO JENKINS-31458 is there not an easier way to do this? JSONObject jsonO = JSONObject.fromObject(json); Jenkins j = Jenkins.getActiveInstance(); Class<?> c = j.getPluginManager().uberClassLoader.loadClass(jsonO.getString("stapler-class")); StepDescriptor descriptor = (StepDescriptor) j.getDescriptor(c.asSubclass(Step.class)); Object o; try { o = descriptor.newInstance(req, jsonO); } catch (RuntimeException x) { // e.g. IllegalArgumentException return HttpResponses.plainText(Functions.printThrowable(x)); } try { String groovy = object2Groovy(o); if (descriptor.isAdvanced()) { String warning = Messages.Snippetizer_this_step_should_not_normally_be_used_in(); groovy = "// " + warning + "\n" + groovy; } return HttpResponses.plainText(groovy); } catch (UnsupportedOperationException x) { Logger.getLogger(CpsFlowExecution.class.getName()) .log(Level.WARNING, "failed to render " + json, x); return HttpResponses.plainText(x.getMessage()); } }
private static void generateStepHelp(StepDescriptor d, PrintWriter pw) throws Exception { pw.println("<h2><code>" + d.getFunctionName() + "</code>: " + d.getDisplayName() + "</h2>"); try { generateHelp(DescribableHelper.schemaFor(d.clazz), pw, 3); } catch (Exception x) { pw.println("<pre><code>" + /*Util.escape(Functions.printThrowable(x))*/ x + "</code></pre>"); } }
@Restricted(DoNotUse.class) public Collection<? extends StepDescriptor> getStepDescriptors(boolean advanced) { TreeSet<StepDescriptor> t = new TreeSet<StepDescriptor>(new StepDescriptorComparator()); for (StepDescriptor d : StepDescriptor.all()) { if (d.isAdvanced() == advanced) { t.add(d); } } return t; }
static String object2Groovy(Object o) throws UnsupportedOperationException { Class<? extends Object> clazz = o.getClass(); for (StepDescriptor d : StepDescriptor.all()) { if (d.clazz.equals(clazz)) { StringBuilder b = new StringBuilder(d.getFunctionName()); Step step = (Step) o; Map<String, Object> args = new TreeMap<String, Object>(d.defineArguments(step)); boolean first = true; boolean singleMap = args.size() == 1 && args.values().iterator().next() instanceof Map; for (Map.Entry<String, Object> entry : args.entrySet()) { if (first) { first = false; if (d.takesImplicitBlockArgument() || singleMap) { b.append('('); } else { b.append(' '); } } else { b.append(", "); } String key = entry.getKey(); if (args.size() > 1 || !isDefaultKey(step, key)) { b.append(key).append(": "); } render(b, entry.getValue()); } if (d.takesImplicitBlockArgument()) { if (!args.isEmpty()) { b.append(')'); } b.append(" {\n // some block\n}"); } else if (singleMap) { b.append(')'); } else if (args.isEmpty()) { b.append("()"); } return b.toString(); } } throw new UnsupportedOperationException("Unknown step " + clazz); }
@Override public int compare(StepDescriptor o1, StepDescriptor o2) { return o1.getFunctionName().compareTo(o2.getFunctionName()); }