package com.autonomy.examples.aci.ng;

import com.autonomy.aci.client.services.AciConstants;
import com.autonomy.aci.client.services.AciService;
import com.autonomy.aci.client.services.AciServiceException;
import com.autonomy.aci.client.services.ProcessorException;
import com.autonomy.aci.client.services.impl.AciServiceImpl;
import com.autonomy.aci.client.services.impl.DocumentProcessor;
import com.autonomy.aci.client.transport.AciParameter;
import com.autonomy.aci.client.transport.gss.GssAciHttpClientImpl;
import com.autonomy.aci.client.transport.gss.GssAciServerDetails;
import com.autonomy.aci.client.transport.impl.HttpClientFactory;
import com.autonomy.aci.client.util.AciParameters;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

 * This example uses the GSS-API extensions to communicate with ACI Servers
 * secured with Kerberos. It will first retrieve the users Securityinfo 
 * string from IDOL Server and then send this as part of a standard query.

public class GssApiExample {

 // We'll use XPAth in this example, although you could easily use the
 // processor and classes from the QueryExample...
 private XPath xpath = XPathFactory.newInstance().newXPath();

 private void query(final String serviceName, final String host, final int port, final String userName, final String queryText) {
    // Create the AciService to use when communicating with IDOL Server...
    final AciService aciService = new AciServiceImpl(
            new GssAciHttpClientImpl(new HttpClientFactory().createInstance()),
            new GssAciServerDetails(serviceName, host, port)

    // Get the security info string...
    final String securityInfo = getSecurityInfoString(aciService, userName);

    // Send a query to IDOL Server the contains the security info string...
    final Document results = aciService.executeAction(
          new AciParameters(
                 new AciParameter(AciConstants.PARAM_ACTION, "Query"),
                 new AciParameter("Text", queryText),
                 new AciParameter("combine", "simple"),
                 new AciParameter("maxResults", 10),
                 new AciParameter("totalResults", true),
                 new AciParameter("print", "none"),
                 new AciParameter("summary", "ParagraphConcept"),
                 new AciParameter("characters", 400),
                 new AciParameter("anyLanguage", true),
                 new AciParameter("outputEncoding", "utf8"),
                 new AciParameter("SecurityInfo", securityInfo)
          new DocumentProcessor()

    try {
       // Get the individual documents in the response...
       final NodeList nodeList = (NodeList) xpath.evaluate("/autnresponse/responsedata/hit", results, XPathConstants.NODESET);
       final int documents = nodeList.getLength();

       System.out.println("Displaying " + documents + " results from a total of " + xpath.evaluate("/autnresponse/responsedata/totalhits", results) + '\n');

       for(int ii = 0; ii < documents; ii++) {
          // Get an individual document in the response...
          final Node node = nodeList.item(ii);

          // Output it's details to the console...
          System.out.println(xpath.evaluate("reference", node));

          System.out.println("\nTitle     : " + xpath.evaluate("title", node));
          System.out.println("Relevance : " + xpath.evaluate("weight", node) + '%');
          System.out.println("Database  : " + xpath.evaluate("database", node));
          final String links = xpath.evaluate("links", node);
          if(StringUtils.isNotBlank(links)) {
              System.out.println("Matched on: " + links);
          System.out.println("Summary   : " + xpath.evaluate("summary", node).replaceAll("\n", " ")); // Remove line breaks for clarity...
    catch(XPathExpressionException e) {
       throw new ProcessorException("Unable to parse the query response.", e);

 private String getSecurityInfoString(final AciService aciService, final String userName) {
    // Get the users Security Info string...
    final Document document = aciService.executeAction(
            new AciParameters(
                  new AciParameter(AciConstants.PARAM_ACTION, "UserRead"),
                  new AciParameter("UserName", userName),
                  new AciParameter("SecurityInfo", true)
            new DocumentProcessor()

    try {
       // Use XPath to pull out the users SecurityInfo string, you could
       // alternatively do this with a simple processor...
       return (String) xpath.evaluate("/autnresponse/responsedata/securityinfo", document, XPathConstants.STRING);
    catch(XPathExpressionException e) {
       throw new ProcessorException("Unable to obtain the SecurityInfo string from the response.", e);

 public static void main(final String[] args) throws IOException {
    // Read three things from stdin, the host, port and the query text...
    final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    System.out.print("Please enter the Kr5b service name: ");
    final String serviceName = reader.readLine();

    System.out.print("Please enter the host [localhost]: ");
    final String host = StringUtils.defaultIfBlank(reader.readLine(), "localhost");

    System.out.print("Please enter the port [9000]: ");
    final int port = NumberUtils.toInt(reader.readLine(), 9000);

    System.out.print("Please enter your username: ");
    final String userName = reader.readLine();

    System.out.print("Please enter the query text [*]: ");
    final String queryText = StringUtils.defaultIfBlank(reader.readLine(), "*");

    try {
      // Display the query response...
      new GssApiExample().query(serviceName, host, port, userName, queryText);
    catch(AciServiceException ase) {
      System.err.println("An error occurred while trying to output the IDOL query response.");