14
14
import com .alchemyapi .api .parameters .TargetedSentimentParameters ;
15
15
import com .alchemyapi .api .parameters .TaxonomyParameters ;
16
16
import com .alchemyapi .api .parameters .TextParameters ;
17
+ import org .apache .commons .io .IOUtils ;
17
18
import org .apache .log4j .Logger ;
18
- import org .w3c .dom .Document ;
19
- import org .w3c .dom .NodeList ;
19
+ import org .jsoup .Jsoup ;
20
+ import org .jsoup .nodes .Document ;
21
+ import org .jsoup .nodes .Element ;
22
+ import org .jsoup .parser .Parser ;
20
23
import org .xml .sax .SAXException ;
21
24
22
- import javax .xml .parsers .DocumentBuilderFactory ;
23
25
import javax .xml .parsers .ParserConfigurationException ;
24
- import javax .xml .xpath .XPath ;
25
- import javax .xml .xpath .XPathConstants ;
26
- import javax .xml .xpath .XPathExpression ;
27
26
import javax .xml .xpath .XPathExpressionException ;
28
- import javax .xml .xpath .XPathFactory ;
29
- import java .io .DataInputStream ;
30
27
import java .io .DataOutputStream ;
31
28
import java .io .IOException ;
32
29
import java .net .HttpURLConnection ;
33
30
import java .net .URL ;
34
31
import java .nio .charset .Charset ;
35
32
36
- import static org .apache .commons .lang3 .StringUtils .isBlank ;
37
- import static org .apache .commons .lang3 .StringUtils .isNotBlank ;
38
33
import static org .apache .commons .lang3 .StringUtils .length ;
39
34
import static org .apache .commons .lang3 .StringUtils .trimToEmpty ;
40
35
@@ -510,32 +505,32 @@ public Document imageGetRankedImageKeywords(final ImageParameters params) {
510
505
outputStream .write (image );
511
506
outputStream .close ();
512
507
513
- return doRequest (handle , params . getOutputMode () );
508
+ return doRequest (handle , params );
514
509
515
510
} catch (IOException e ) {
516
511
throw new AlchemyApiException (e );
517
512
}
518
513
}
519
514
520
- private Document get (final String callName , final String callPrefix , final Parameters params ) {
515
+ private Document get (final String callName , final String callPrefix , final Parameters parameters ) {
521
516
try {
522
- final String urlQuery = "?apikey=" + configuration .getApiKey () + params .getUrlQuery ();
517
+ final String urlQuery = "?apikey=" + configuration .getApiKey () + parameters .getUrlQuery ();
523
518
final URL url = new URL (buildBaseApiUrl () + callPrefix + "/" + callName + urlQuery );
524
519
525
520
final HttpURLConnection httpURLConnection = (HttpURLConnection ) url .openConnection ();
526
521
httpURLConnection .setDoOutput (true );
527
522
528
- return doRequest (httpURLConnection , params . getOutputMode () );
523
+ return doRequest (httpURLConnection , parameters );
529
524
530
525
} catch (IOException e ) {
531
526
throw new AlchemyApiException (e );
532
527
}
533
528
}
534
529
535
- private Document post (final String callName , final String callPrefix , final Parameters params ) {
530
+ private Document post (final String callName , final String callPrefix , final Parameters parameters ) {
536
531
try {
537
532
final URL url = new URL (buildBaseApiUrl () + callPrefix + "/" + callName );
538
- final String data = "apikey=" + configuration .getApiKey () + params .getUrlQuery ();
533
+ final String data = "apikey=" + configuration .getApiKey () + parameters .getUrlQuery ();
539
534
540
535
final HttpURLConnection httpURLConnection = (HttpURLConnection ) url .openConnection ();
541
536
httpURLConnection .setDoOutput (true );
@@ -545,7 +540,7 @@ private Document post(final String callName, final String callPrefix, final Para
545
540
outputStream .write (data .getBytes (Charset .forName ("UTF-8" )));
546
541
outputStream .close ();
547
542
548
- return doRequest (httpURLConnection , params . getOutputMode () );
543
+ return doRequest (httpURLConnection , parameters );
549
544
550
545
} catch (IOException e ) {
551
546
throw new AlchemyApiException (e );
@@ -554,74 +549,62 @@ private Document post(final String callName, final String callPrefix, final Para
554
549
555
550
// TODO add json handling
556
551
// TODO return pojo with parsed field, but allow a "raw" xml/json getter to protect against api updates
557
- private Document doRequest (final HttpURLConnection httpURLConnection , final String outputMode ) {
552
+ private Document doRequest (final HttpURLConnection httpURLConnection , final Parameters parameters ) {
558
553
try {
559
- final DataInputStream inputStream = new DataInputStream (httpURLConnection .getInputStream ());
560
- final Document document = DocumentBuilderFactory .newInstance ().newDocumentBuilder ().parse (inputStream );
561
-
562
- inputStream .close ();
554
+ final String response = IOUtils .toString (httpURLConnection .getInputStream ());
563
555
httpURLConnection .disconnect ();
564
556
565
- switch (outputMode ) {
557
+ switch (parameters . getOutputMode () ) {
566
558
case Parameters .OUTPUT_XML :
567
- return parseXml (document );
559
+ return parseXml (response , parameters );
568
560
569
561
case Parameters .OUTPUT_RDF :
570
- return praseRdf (document );
562
+ return praseRdf (response , parameters );
571
563
572
564
case Parameters .OUTPUT_JSON :
573
565
throw new AlchemyApiException ("Json Response not supported yet" );
574
- }
575
- return document ;
576
566
577
- } catch (SAXException | ParserConfigurationException | IOException e ) {
567
+ default :
568
+ throw new AlchemyApiException ("Unknown output mode, must be one of [xml,rdf,json]" );
569
+ }
570
+ } catch (IOException e ) {
578
571
throw new AlchemyApiException (e );
579
572
}
580
573
}
581
574
582
- private Document parseXml (final Document document ) {
583
- final XPathFactory factory = XPathFactory .newInstance ();
584
- final String status = getNodeValue (factory , document , "/results/status/text()" );
585
- if (isBlank (status ) || !status .equals ("OK" )) {
586
- final String statusInfo = getNodeValue (factory , document , "/results/statusInfo/text()" );
587
- if (isNotBlank (statusInfo )) {
588
- throw new AlchemyApiException ("Error making API call: " + statusInfo );
589
- }
590
- throw new AlchemyApiException ("Error making API call: " + status );
591
- }
592
- return document ;
593
- }
575
+ private Document parseXml (final String response , final Parameters parameters ) {
576
+ final Document document = Jsoup .parse (response , parameters .getEncoding (), Parser .xmlParser ());
594
577
595
- private Document praseRdf (final Document document ) {
596
- final XPathFactory factory = XPathFactory .newInstance ();
597
- final String status = getNodeValue (factory , document , "//RDF/Description/ResultStatus/text()" );
598
- if (isBlank (status ) || !status .equals ("OK" )) {
599
- final String statusInfo = getNodeValue (factory , document , "//RDF/Description/ResultStatus/text()" );
600
- if (isNotBlank (statusInfo )) {
578
+ final Element status = document .select ("results > status" ).first ();
579
+ if (status == null || !status .text ().equals ("OK" )) {
580
+ final Element statusInfo = document .select ("results > statusInfo" ).first ();
581
+ if (statusInfo != null ) {
601
582
throw new AlchemyApiException ("Error making API call: " + statusInfo );
602
583
}
603
584
throw new AlchemyApiException ("Error making API call: " + status );
604
585
}
605
586
return document ;
606
587
}
607
588
608
- private String getNodeValue (XPathFactory factory , Document doc , String xpathStr ) {
609
- try {
610
- final XPath xpath = factory .newXPath ();
611
- final XPathExpression expr = xpath .compile (xpathStr );
612
- final Object result = expr .evaluate (doc , XPathConstants .NODESET );
613
- final NodeList results = (NodeList ) result ;
614
-
615
- if (results .getLength () == 0 || results .item (0 ) == null ) { return null ; }
616
- return results .item (0 ).getNodeValue ();
589
+ // TODO investigate rdf format
590
+ private Document praseRdf (final String response , final Parameters parameters ) {
591
+ final Document document = Jsoup .parse (response , parameters .getEncoding (), Parser .xmlParser ());
617
592
618
- } catch (XPathExpressionException e ) {
619
- throw new AlchemyApiException (e );
593
+ final Element status = document .select ("RDF > Description > ResultStatus" ).first ();
594
+ if (status == null || !status .text ().equals ("OK" )) {
595
+ throw new AlchemyApiException ("Error making API call: " + status );
620
596
}
597
+ return document ;
621
598
}
622
599
623
600
private String buildBaseApiUrl () {
624
601
return API_URL .replace ("{SUB_DOMAIN}" , configuration .getApiSubDomain ());
625
602
}
626
603
604
+ private String parseBaseUrl (final HttpURLConnection httpURLConnection ) {
605
+ final URL url = httpURLConnection .getURL ();
606
+ String path = url .getFile ().substring (0 , url .getFile ().lastIndexOf ('/' ));
607
+ return url .getProtocol () + "://" + url .getHost () + path ;
608
+ }
609
+
627
610
}
0 commit comments