Jsoup to post data and parse alternative URLs on CFscript - coldfusion

I need to get and parse a page from primary_URL using Jsoup in CFscript.
If page status is not OK or data is corrupt or empty, I should try an alternative page from secondary_URL.
primary_URL accepts POST requests only and I don't know how do it in cfscript
secondary_URL accepts GET by default
This is an idea:
<cfscript>
jsoup = createObject("java", "org.jsoup.Jsoup");
response = jsoup.connect(primary_URL).userAgent("#CGI.Http_User_Agent#").timeout(10000).method(Connection.Method.POST).execute(); // How to use Method.POST in this case???
if(response.statusCode() == 200)
{
doc = response.parse();
theData = doc.select("div##data");
...
`some other parsing and SQL UPDATE routine`
}
else
{
response = jsoup.connect(secondary_URL).userAgent("#CGI.Http_User_Agent#").timeout(10000).execute(); // default is GET
if(response.statusCode() == 200)
{
doc = response.parse();
theData = doc.select("div##same_data");
...
`some other parsing and SQL UPDATE routine`
}
}
</cfscript>
How to jump to the secondary_URL in case the response is OK but the data appears to be currupt or empty? A kind of goto operator?
Running ColdFusion 11.

How to jump to the secondary_URL in case the response is OK but the data appears to be currupt or empty? A kind of goto operator?
Instead of checking the statusCode only, call a function. Inside this function perform all necessary checks (corrupted data, empty data ...).
<cfscript>
function IsValid(response) {
// Perform all the tests here...
// Return TRUE on success or FALSE otherwise
return true;
}
jsoup = createObject("java", "org.jsoup.Jsoup");
response = jsoup //
.connect(primary_URL) //
.userAgent("#CGI.Http_User_Agent#") //
.timeout(10000) //
.post(); // Simply call the post() method for posting...
if( IsValid(response) ) {
} else {
response = jsoup //
.connect(secondary_URL) //
.userAgent("#CGI.Http_User_Agent#") //
.timeout(10000) //
.get(); // Make your intent clear
if ( IsValid(response) ) {
// ...
}
}
</cfscript>

Related

Doctrine: how to curb circular references

I have devices being parts of brands and repairs being part of devices. Now I'm trying to get a simple AJAX call which will allow me to search for a device by either brand name or device name. Unfortunately, I get circular references. Even when I've written a handler for circular references to limit it to one, I still get too much information in my objects.
Consider the following return from serialize on my DQL query:
[{"0":{"id":1,"name":"iPhone
1","logo":"iPhone1","brand":{"id":2,"name":"Apple","logo":"apple","devices":["iPhone
1",{"id":2,"name":"iPhone","logo":"iphone","brand":"Apple","deletedAt":null,"repairs":[]}],"deletedAt":null},"deletedAt":null,"repairs":[]},"name":"Apple"},{"0":{"id":2,"name":"iPhone","logo":"iphone","brand":{"id":2,"name":"Apple","logo":"apple","devices":[{"id":1,"name":"iPhone
1","logo":"iPhone1","brand":"Apple","deletedAt":null,"repairs":[]},"iPhone"],"deletedAt":null},"deletedAt":null,"repairs":[]},"name":"Apple"}]
Here I don't even need repairs at all. However, since it is referenced in the PartEntity, I still get a bunch of unnecessary repair info. How can I limit the data I get out of an object?
my Controller code:
public function ajaxShowDevicesAction(Request $request) {
//if ($request->isXmlHttpRequest()) {
$data = $request->query->get('data');
$result = "";
if ($data) {
$result = $this->getDoctrine()->getManager()->getRepository('AppBundle:Device')->findAllByBrandOrName($data);
}
if ($result) {
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer());
$normalizers[0]->setCircularReferenceHandler(function ($object) {
return $object->getName();
});
$serializer = new Serializer($normalizers, $encoders);
$jsoncontent = $serializer->serialize($result, 'json');
$response = new Response($jsoncontent);
return $response;
}
// else { # unsure how to give a "no results" response
// $response = new Response(json_encode(array()));
// $response->headers->set('Content-Type', 'application/json');
// return $response;
// }
// } else {
// throw new HttpException(403, "Ajax access only");
// }
}
You can use
setCircularReferenceLimit()
method for normalizers.
Handling Circular References

Alfresco WS Client API - WSSecurityException when using fetchMore method

Can someone tell me what's wrong with my code here... I'm always getting this exception on the first call to contentService.read(...) after the first fetchMore has occurred.
org.apache.ws.security.WSSecurityException: The security token could not be authenticated or authorized
// Here we're setting the endpoint address manually, this way we don't need to use
// webserviceclient.properties
WebServiceFactory.setEndpointAddress(wsRepositoryEndpoint);
AuthenticationUtils.startSession(wsUsername, wsPassword);
// Set the batch size in the query header
int batchSize = 5000;
QueryConfiguration queryCfg = new QueryConfiguration();
queryCfg.setFetchSize(batchSize);
RepositoryServiceSoapBindingStub repositoryService = WebServiceFactory.getRepositoryService();
repositoryService.setHeader(new RepositoryServiceLocator().getServiceName().getNamespaceURI(), "QueryHeader", queryCfg);
ContentServiceSoapBindingStub contentService = WebServiceFactory.getContentService();
String luceneQuery = buildLuceneQuery(categories, properties);
// Call the repository service to do search based on category
Query query = new Query(Constants.QUERY_LANG_LUCENE, luceneQuery);
// Execute the query
QueryResult queryResult = repositoryService.query(STORE, query, true);
String querySession = queryResult.getQuerySession();
while (querySession != null) {
ResultSet resultSet = queryResult.getResultSet();
ResultSetRow[] rows = resultSet.getRows();
for (ResultSetRow row : rows) {
// Read the content from the repository
Content[] readResult = contentService.read(new Predicate(new Reference[] { new Reference(STORE, row.getNode().getId(), null) },
STORE, null), Constants.PROP_CONTENT);
Content content = readResult[0];
[...]
}
// Get the next batch of results
queryResult = repositoryService.fetchMore(querySession);
// process subsequent query results
querySession = queryResult.getQuerySession();
}

ColdFusion Code as failing on if condition

Working with cfscript code in ColdFusion, The following seems correct to me, if client_discount is either 0 or NULL, just do not generate the UniqueKey, use existing else use new one. But it does work somehow, I am not sure what I am missing here, trying different cflib UDF's also:
Here is my code:
f = structnew();
f.discountoffered = '#arguments.structform.client_discount#';
writedump(arguments);
result = structFindKeyWithValue(f,f.discountoffered,"0","ALL");
writedump(result);
if((arguments.structform.client_discount EQ 0)
OR (arguments.structform.client_discount NEQ "")) {
f.orderunique = generateRandomKey();
}
else {
f.orderunique = '#arguments.structform.orderunique#';
}
NULL is kind of wonky in ColdFusion.
I would handle this by paraming the value so it gets a value I decide if it does not exist.
Add this code under f = structNew() - or at the beginning of the function, does not really matter.
param name="arguments.structForm" default="#structNew()#;
param name="arguments.structForm.client_discount" default="0";
This way if client_discount is not present, it is set to 0 - the first line is to make sure that structform exists in arguments and if not, sets it to an empty struct.
Then your if statement need only check if it is 0.
if( arguments.structForm.client_discount == 0 ){
f.orderunique = generateRandomKey();
}
else{
f.orderunique = arguments.structform.orderunique;
}
Of course...you would need to verify that arguments.structForm.orderunique exists before using it.
I think that's what you are trying to do
<cfscript>
f = structnew();
if(not isnull(arguments.structform.client_discount)){
f.discountoffered = '#arguments.structform.client_discount#';
result = structFindKeyWithValue(f,f.discountoffered,"0","ALL");
if((arguments.structform.client_discount EQ 0))
f.orderunique = generateRandomKey();
else
f.orderunique = '#arguments.structform.orderunique#';
}
else {
f.orderunique = '#arguments.structform.orderunique#';
}
</cfscript>

How do I provide ObjectContent that is a string

I'm writing a unit test which tests the scenario where a body is sent in the request which is a plain string, i.e. not parseable as JSON.
In this test, I'm setting the HttpRequestMessage something like this:
var ojectContent = new ObjectContent(typeof(string)
, "aaaaa"
, new JsonMediaTypeFormatter());
httpRequestMessage.Content = objectContent;
The problem is, when I debug the code, the request body has been set to "aaaaa" (note the additional quotes) which is enough to cause the deserialisation code to treat the request body differently, meaning I can't test what I mean to test. I need the request body to be aaaaa.
Can anyone advise how I can set up the test so that the request body does not contain these quotes?
Edit: I have also tried new ObjectContent(typeof(object)... and it gives the same result.
Another way is to bypass the MediaTypeFormatter by using StringContent instead of ObjectContent:
var content = new StringContent("aaaaa");
httpRequestMessage.Content = content;
Okay, so I needed to create a media type formatter that didn't interfere with the input in any way. I used this:
private class DoNothingTypeFormatter : MediaTypeFormatter
{
public override bool CanReadType(Type type)
{
return false;
}
public override bool CanWriteType(Type type)
{
if (type == typeof(string))
{
return true;
}
return false;
}
public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext)
{
var myString = value as string;
if (myString == null)
{
throw new Exception("Everything is supposed to be a string here.");
}
var length = myString.Length;
var bytes = System.Text.Encoding.UTF8.GetBytes(myString);
return Task.Factory.StartNew(() => writeStream.Write(bytes, 0, length));
}
}
Then, when I want to generate the body of the `HttpRequestMessage', I do so like this:
objectContent = new ObjectContent(typeof(string)
, "not json"
, new DoNothingTypeFormatter());

Using protractorjs and mocha how do I read all links on a site?

I'm trying to read all HREF links on a site using protractor and mocha
I am not "married" to any of the technologies, but I'm under the impression that these are the current best in class technologies for driving selenium.
I'm working with the protractor Mocha example file that came with the project which I have tuned from the example code to read:
before(function() {
driver = new webdriver.Builder().
usingServer('http://localhost:4444/wd/hub').
withCapabilities(webdriver.Capabilities.chrome()).build();
driver.manage().timeouts().setScriptTimeout(10000);
ptor = protractor.wrapDriver(driver);
});
function Log(obj){
console.log(JSON.stringify(obj));
}
it.only('should read all HREFS', function(done){
ptor.get('http://www.angularjs.org');
var elements = ptor.findElements(protractor.By.tagName('a'));
Log(protractor.By.tagName('a'));
// {"using":"tag name","value":"a"}
Log(elements);
// Result: {}
// Expected: a full list of every 'a' tag element on the angularjs homepage
});
What appears to be happening is the "elements" list is returning immediately as opposed to after the page loads.
How do I deal with that in selenium+protractor?
OK - so turns out the Async was messing me up a little.
I've tuned the code to make this do what I've asked for above.
it.only('should read all HREFS', function(done){
ptor.get('http://www.angularjs.org');
var elements = ptor.findElements(protractor.By.tagName('a'));
Log(protractor.By.tagName('a'));
Log(elements);
var a = driver.findElements(webdriver.By.tagName('a'));
for (var element in a) {
Log(element);
}
// NOTE ***********************************
// this here is the "answer" the asynchonous nature of javascript means that I
// do not have have access to the contents of the request until I am inside the "then"
// response
//
// from there I have to use the same structure when executing the getAttribute method
a.then(function(elements){
for (var i = 0; i < elements.length; i++){
var link = elements[i];
link.getAttribute('href')
.then(function(value){
Log(value);
});
}
for (e in elements){
var link = elements[e];
Log(link.getTagName());
// I left this in my debugging code for the stackoverflow reader who might
// want to know what other functions they can execute on the LINK object
for (attribute in link) {
Log(attribute);
// "then"
// "cancel"
// "isPending"
// "errback"
// "driver_"
// "id_"
// "constructor"
// "getDriver"
// "toWireValue"
// "schedule_"
// "findElement"
// "isElementPresent"
// "findElements"
// "click"
// "sendKeys"
// "getTagName"
// "getCssValue"
// "getAttribute"
// "getText"
// "getSize"
// "getLocation"
// "isEnabled"
// "isSelected"
// "submit"
// "clear"
// "isDisplayed"
// "getOuterHtml"
// "getInnerHtml"
// "addCallback"
// "addErrback"
// "addBoth"
// "addCallbacks"
}
};
});
});