Skip to content

Instantly share code, notes, and snippets.

@cfalzone
Last active November 30, 2015 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cfalzone/c64ecf3b4f024312e8f7 to your computer and use it in GitHub Desktop.
Save cfalzone/c64ecf3b4f024312e8f7 to your computer and use it in GitHub Desktop.
A soap client example for dotCMS. PostedJob and LocalizePostingDetails are just POJOs that represent the objects being returned by the soap client.
package com.aquent.jobs;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.reficio.ws.builder.SoapBuilder;
import org.reficio.ws.builder.SoapOperation;
import org.reficio.ws.builder.core.Wsdl;
import org.reficio.ws.client.core.SoapClient;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.aquent.AquentUtil;
import com.dotmarketing.util.Logger;
/**
* This is a soap client for CW's JobPostingService.
*
* @author cfalzone
*
*/
public final class JobPostingServiceClient {
public static final JobPostingServiceClient INSTANCE = new JobPostingServiceClient();
private String baseSoapRequest = null;
private XPath xpath = null;
private String serviceUri = null;
private SimpleDateFormat soapdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
/**
* Private Constructor because singleton.
*/
private JobPostingServiceClient() {
}
/**
* Returns and instance of the client.
*
* @return an instance of JobPostingServiceClient
*/
public static JobPostingServiceClient getInstance() {
return INSTANCE;
}
/**
* Setup the request to the soap client here.
* This method has to be called by your activator, or osgi will not be happy.
*/
public void initializeRequest() {
String cwDomain = AquentUtil.INSTANCE.getCWDomain();
// Note: due to a bug in soap-ws, when using https you have to specify the port
serviceUri = "https://" + cwDomain + ":443/AQWS/JobPostingService";
// initialize the base request.
try {
URL u = new URL(serviceUri + "?wsdl");
Wsdl w = Wsdl.parse(u);
SoapBuilder builder = w.binding()
.name("{ws.aquent.com}JobPostingServiceSoapBinding").find();
SoapOperation operation = builder.operation().name("getAllPostedJobs").find();
baseSoapRequest = builder.buildInputMessage(operation);
} catch (Exception e) {
Logger.error(this, "Unable to parse WSDL from CW", e);
}
//Initialize the XPAthFactory
xpath = XPathFactory.newInstance().newXPath();
}
/**
* Gets the jobs from CW for the past hours hours.
*
* @param cwDomain The CWDomain to pull from
* @param hours The number of hours to pull for
* @return a list of jobs
* @throws Exception when there is an error getting the feed.
*/
public List<PostedJob> getPostedJobs(int hours) throws Exception {
// PostedJob is just a POJO that represents the object returned by the soap service
List<PostedJob> postedJobs = new ArrayList<PostedJob>();
if(baseSoapRequest == null) {
throw new Exception("I do not have a base soap request");
}
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, hours * -1);
String modifiedSinceDate = soapdf.format(cal.getTime());
Logger.debug(this, "Getting jobs for the past " + hours + " hours");
// This soap client does not take parameters so you have add them in after the fact.
String request = addModifiedSinceDate(baseSoapRequest, modifiedSinceDate);
String response = "";
try {
SoapClient client = SoapClient.builder().endpointUri(serviceUri).build();
response = client.post(request);
} catch (Exception e) {
Logger.error(this, "Unabel to get response from CW SOAP Service", e);
throw new Exception(e);
}
postedJobs = parseSoapResponse(response);
return postedJobs;
}
/**
* Updates the modifiedSinceDate in the soap envelope for the request to CW.
*
* @param request The initial soap request
* @param modifiedSinceDate the new modifiedSinceDate
* @return The modified soap request
* @throws Exception when it cannot parse the xml request
*/
private String addModifiedSinceDate(String request, String modifiedSinceDate) throws Exception {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new InputSource(new ByteArrayInputStream(request.getBytes("utf-8"))));
NodeList nodes = (NodeList) xpath.evaluate(
"//Body/getAllPostedJobs/modifiedSinceDate", doc, XPathConstants.NODESET);
for (int idx = 0; idx < nodes.getLength(); idx++) {
nodes.item(idx).setTextContent(modifiedSinceDate);
}
Transformer xformer = TransformerFactory.newInstance().newTransformer();
StringWriter writer = new StringWriter();
xformer.transform(new DOMSource(doc), new StreamResult(writer));
return writer.getBuffer().toString();
}
/**
* Parses the soap request into a list of jobs.
*
* @param response The soap response from CW
* @return A list of jobs
* @throws Exception when there is an error parsing the xml response
*/
private List<PostedJob> parseSoapResponse(String response) throws Exception {
List<PostedJob> postedJobs = new ArrayList<PostedJob>();
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new InputSource(new ByteArrayInputStream(response.getBytes("utf-8"))));
NodeList nodes = (NodeList) xpath.evaluate(
"//Body/getAllPostedJobsResponse/PostedJobs", doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.item(0).getChildNodes().getLength(); i++) {
Node node = nodes.item(0).getChildNodes().item(i);
if (node.getNodeName().equals("PostedJob")) {
postedJobs.add(parseNodeAsPostedJob(node));
}
}
return postedJobs;
}
/**
* Parses an XML node as a PostedJob Object.
*
* @param node the xml node to parse
* @return the PostedJob Object
*/
private PostedJob parseNodeAsPostedJob(Node node) {
NodeList children = node.getChildNodes();
int agentId = 0;
String city = null;
boolean considerRelocation = false;
boolean isFeatured = false;
boolean isPosted = false;
int jobId = 0;
int locationId = 0;
int marketId = 0;
int minorSegmentId = 0;
Date modDate = null;
int offSitePreferenceId = 0;
int placementTypeId = 0;
List<LocalizedPostingDetails> localizedPostingDetails = new ArrayList<LocalizedPostingDetails>();
String startDate = null;
int websiteIndustryTypeId = 0;
for (int i = 0; i < children.getLength(); i++) {
Node item = children.item(i);
if (item.getNodeName().equals("agentId")) {
agentId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("city")) {
city = item.getTextContent();
} else if (item.getNodeName().equals("isPosted")) {
isPosted = Boolean.parseBoolean(item.getTextContent());
} else if (item.getNodeName().equals("considerRelocation")) {
considerRelocation = Boolean.parseBoolean(item.getTextContent());
} else if (item.getNodeName().equals("isFeatured")) {
isFeatured = Boolean.parseBoolean(item.getTextContent());
} else if (item.getNodeName().equals("isFeatured")) {
isFeatured = Boolean.parseBoolean(item.getTextContent());
} else if (item.getNodeName().equals("jobId")) {
jobId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("locationId")) {
locationId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("marketId")) {
marketId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("minorSegmentId")) {
minorSegmentId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("modDate")) {
try {
modDate = soapdf.parse(item.getTextContent());
} catch (Exception e) {
Logger.warn(this, "Unable to format modDate", e);
}
} else if (item.getNodeName().equals("offSitePreferenceId")) {
offSitePreferenceId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("placementTypeId")) {
placementTypeId = Integer.parseInt(item.getTextContent());
} else if (item.getNodeName().equals("LocalizedPostingDetails")) {
NodeList details = item.getChildNodes();
for (int j = 0; j < details.getLength(); j++) {
Node detail = details.item(j);
localizedPostingDetails.add(parseNodeAsDetails(detail));
}
} else if (item.getNodeName().equals("startDate")) {
startDate = item.getTextContent();
} else if (item.getNodeName().equals("websiteIndustryTypeId")) {
websiteIndustryTypeId = Integer.parseInt(item.getTextContent());
}
}
return new PostedJob(agentId, city, considerRelocation, isFeatured, isPosted, jobId, locationId,
marketId, minorSegmentId, modDate, offSitePreferenceId, placementTypeId, localizedPostingDetails,
startDate, websiteIndustryTypeId);
}
/**
* Parses an XML node as a LocalizedPostingDetails object.
*
* @param node the XML node to parse
* @return the LocalizedPostingDetails object
*/
private LocalizedPostingDetails parseNodeAsDetails(Node node) {
NodeList children = node.getChildNodes();
String clientDesc = null;
String countryCode = null;
String jobDesc = null;
String jobTitle = null;
String langCode = null;
String location = null;
String modBy = null;
Date localizedModDate = null;
String otherReq = null;
int postingId = 0;
String salary = null;
String localizedStartDate = null;
for (int k = 0; k < children.getLength(); k++) {
Node child = children.item(k);
if (child.getNodeName().equals("clientDesc")) {
clientDesc = child.getTextContent();
} else if (child.getNodeName().equals("countryCode")) {
countryCode = child.getTextContent();
} else if (child.getNodeName().equals("jobDesc")) {
jobDesc = child.getTextContent();
} else if (child.getNodeName().equals("jobTitle")) {
jobTitle = child.getTextContent();
} else if (child.getNodeName().equals("langCode")) {
langCode = child.getTextContent();
} else if (child.getNodeName().equals("location")) {
location = child.getTextContent();
} else if (child.getNodeName().equals("modBy")) {
modBy = child.getTextContent();
} else if (child.getNodeName().equals("localized_modDate")) {
try {
localizedModDate = soapdf.parse(child.getTextContent());
} catch (Exception e) {
Logger.warn(this, "Unable to parse localized_modDate", e);
}
} else if (child.getNodeName().equals("otherReq")) {
otherReq = child.getTextContent();
} else if (child.getNodeName().equals("postingId")) {
postingId = Integer.parseInt(child.getTextContent());
} else if (child.getNodeName().equals("salary")) {
salary = child.getTextContent();
} else if (child.getNodeName().equals("localized_startDate")) {
localizedStartDate = child.getTextContent();
}
}
return new LocalizedPostingDetails(clientDesc, countryCode, jobDesc,
jobTitle, langCode, location, modBy, localizedModDate, otherReq, postingId, salary,
localizedStartDate);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment