Skip to content

Commit

Permalink
Fix JENKINS-12742
Browse files Browse the repository at this point in the history
Added new XML macro based on joshua_niehus's tree
  • Loading branch information
slide committed Jun 20, 2015
1 parent e74bf1c commit c6d4ae5
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ work
.project
.classpath
.settings
.idea
@@ -0,0 +1,92 @@
package org.jenkinsci.plugins.tokenmacro.impl;

import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.TaskListener;
import hudson.remoting.Callable;
import java.io.Closeable;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import org.w3c.dom.*;
import javax.xml.xpath.*;
import javax.xml.parsers.*;
import org.xml.sax.SAXException;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;

/**
* Expands to a xml value(s) from a xml file relative to the workspace root.
* If xpath evaluates to more than one value then a semicolon separted string is returned.
*/
@Extension
public class XmlFileMacro extends DataBoundTokenMacro {

@Parameter(required=true)
public String file = null;

@Parameter(required=true)
public String xpath = null;

@Override
public boolean acceptsMacroName(String macroName) {
return macroName.equals("XML");
}

@Override
public String evaluate(AbstractBuild<?, ?> context, TaskListener listener, String macroName) throws MacroEvaluationException, IOException, InterruptedException {
String root = context.getWorkspace().getRemote();
return context.getWorkspace().act(new ReadXML(root,file,xpath));
}

private static class ReadXML implements Callable<String,IOException> {

private String root;
private String filename;
private String xpathexpression;

public ReadXML(String root, String filename, String xpath){
this.root=root;
this.filename=filename;
this.xpathexpression=xpath;
}

public String call() throws IOException {
File file = new File(root, filename);
String result = "";
if (file.exists()) {
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc = builder.parse(file.toString());
XPath xpathInstance = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpathInstance.compile(xpathexpression);

Object res = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) res;
for (int i = 0; i < nodes.getLength(); i++) {
result = result.concat(nodes.item(i).getNodeValue().toString()).concat(";");
}

result = result.substring(0, result.length() - 1); // trim the last ';'
}
catch (IOException e) {
result = "Error: ".concat(filename).concat(" - Could not read XML file.");
}
catch (SAXException e) {
result = "Error: ".concat(filename).concat(" - XML not well formed.");
}
catch (Exception e) {
result = "Error: ".concat(filename).concat(" - '").concat(xpathexpression).concat("' invalid syntax or path maybe?");
}
}
else {
result = "Error: ".concat(filename).concat(" not found");
}

return result;
}
}
}
@@ -0,0 +1,39 @@
package org.jenkinsci.plugins.tokenmacro.impl;

import hudson.Launcher;
import hudson.model.*;
import hudson.util.StreamTaskListener;
import org.jenkinsci.plugins.tokenmacro.TokenMacro;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestBuilder;

import java.io.IOException;

import static junit.framework.TestCase.assertEquals;

/**
* @author Kohsuke Kawaguchi
*/
public class XmlFileMacroTest {
private TaskListener listener;

@Rule
public final JenkinsRule j = new JenkinsRule();

@Test
public void testXmlFromFileExpansion() throws Exception {
FreeStyleProject project = j.createFreeStyleProject("foo");
project.getBuildersList().add(new TestBuilder() {
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
build.getWorkspace().child("test.xml").write("<project><version>1.2.3</version></project>","UTF-8");
return true;
}
});
FreeStyleBuild b = project.scheduleBuild2(0).get();
assertEquals("1.2.3",TokenMacro.expand(b, StreamTaskListener.fromStdout(),
"${XML,file=\"test.xml\",xpath=\"/project/version/text()\"}"));
}
}

0 comments on commit c6d4ae5

Please sign in to comment.