package hudson.plugins.campfire; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.StringRequestEntity; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; import java.io.IOException; import java.util.List; import java.util.ArrayList; import com.gargoylesoftware.htmlunit.WebClient; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.apache.commons.httpclient.methods.GetMethod; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class Campfire { private HttpClient client; private WebClient webClient; private String subdomain; private String token; private boolean ssl; public Campfire(String subdomain, String token, boolean ssl) { super(); this.subdomain = subdomain; this.token = token; this.ssl = ssl; client = new HttpClient(); Credentials defaultcreds = new UsernamePasswordCredentials(token, "x"); client.getState().setCredentials(new AuthScope(getHost(), -1, AuthScope.ANY_REALM), defaultcreds); client.getParams().setAuthenticationPreemptive(true); client.getParams().setParameter("http.useragent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"); webClient = new WebClient(); webClient.setWebConnection(new HttpClientBackedWebConnection(webClient, client)); webClient.setJavaScriptEnabled(true); webClient.setCookiesEnabled(true); } protected String getHost() { return this.subdomain + ".campfirenow.com"; } protected String getProtocol() { if (this.ssl) { return "https://"; } return "http://"; } public int post(String url, String body) throws IOException { PostMethod post = new PostMethod(getProtocol() + getHost() + "/" + url); post.setRequestHeader("Content-Type", "application/xml"); post.setRequestEntity(new StringRequestEntity(body, "application/xml", "UTF8")); try { return client.executeMethod(post); } finally { post.releaseConnection(); } } public String get(String url) throws IOException { GetMethod get = new GetMethod(getProtocol() + getHost() + "/" + url); get.setRequestHeader("Content-Type", "application/xml"); try { client.executeMethod(get); return get.getResponseBodyAsString(); } finally { get.releaseConnection(); } } public boolean verify(int returnCode) { return (returnCode == 200 || (returnCode > 301 && returnCode < 399)); } private List<Room> getRooms() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException { String body = get("rooms.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); StringReader reader = new StringReader(body); InputSource inputSource = new InputSource( reader ); Document doc = builder.parse(inputSource); XPath xpath = XPathFactory.newInstance().newXPath(); XPathExpression roomExpr = xpath.compile("//room"); XPathExpression nameExpr = xpath.compile(".//name"); XPathExpression idExpr = xpath.compile(".//id"); NodeList roomNodeList = (NodeList) roomExpr.evaluate(doc, XPathConstants.NODESET); List<Room> rooms = new ArrayList<Room>(); for (int i = 0; i < roomNodeList.getLength(); i++) { Node roomNode = roomNodeList.item(i); String name = ((NodeList) nameExpr.evaluate(roomNode, XPathConstants.NODESET)).item(0).getFirstChild().getNodeValue(); String id = ((NodeList) idExpr.evaluate(roomNode, XPathConstants.NODESET)).item(0).getFirstChild().getNodeValue(); rooms.add(new Room(this, name.trim(), id.trim())); } return rooms; } private Room findRoomByName(String name) throws IOException, ParserConfigurationException, XPathExpressionException, SAXException { for (Room room : getRooms()) { if (room.getName().equals(name)) { return room; } } return null; } private Room createRoom(String name) throws IOException, ParserConfigurationException, XPathExpressionException, SAXException { verify(post("rooms.xml", "<request><room><name>" + name + "</name><topic></topic></room></request>")); return findRoomByName(name); } public Room findOrCreateRoomByName(String name) throws IOException, ParserConfigurationException, XPathExpressionException, SAXException { Room room = findRoomByName(name); if (room != null) { return room; } return createRoom(name); } }