Last active
November 30, 2015 14:31
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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