ACI API 24.1

# Process an ACI Response

The API uses a processor based system to consume the responses from an ACI Server. It is based around two interfaces: `Processor<T>` and `StAXProcessor<T>`. `StAXProcessor<T>` has an abstract implementation that sets up the StAX parser. You can either write your own processor implementations, or use those that are included with the API.

The default processor that is included with the API is the `DocumentProcessor`. This processor returns a DOM Document object, which you can then parse using either DOM or XPath. However, not all ACI responses are XML. For example, the cluster and spectrograph functionality can also return images. The SDK contains a `BinaryResponseProcessor` for these cases. Internally it uses the `ByteArrayProcessor` to process the binary data, or the `ErrorProcessor` if it detects that the response is actually XML.

The following example shows the use of the `DocumentProcessor` and `XPath` to output query results to the console:

    // Send the action and process the response into a DOM Document...
    final Document response = aciService.executeAction(
          parameters, new DocumentProcessor());

    // Get the individual documents in the response...
    final XPath xpath = XPathFactory.newInstance().newXPath();
    final NodeList nodeList = (NodeList) xpath.evaluate(
          "/autnresponse/responsedata/hit",
          response,
          XPathConstants.NODESET
    );
    final int documents = nodeList.getLength();

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

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

        // Output a few key fields...
        System.out.println('\n' + xpath.evaluate("reference", node));
        System.out.println("Title     : " + 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", " "));
    }

The following example shows the use of the `BinaryResponseProcessor` in a Spring based service implementation:

    @Service
    public class ClusteringServiceImpl implements ClusteringService {

        @Autowired
        @Qualifier("clusterService")
        private AciService clusteringService;

        ...

        @Override
        public byte[] clusterServe2DMap(final String job) {
            return clusteringService.executeAction(
                  new ActionParameters(
                        new AciParameter(
                              AciConstants.PARAM_ACTION, "ClusterServe2DMap"),
                        new AciParameter("sourceJobName", job)
                  ),
                  new BinaryResponseProcessor()
            );
        }

        ...
    }

You might want to write your own response processors for increased performance, or to return the response as a collection of `JavaBeans`. In this case, you simply implement one of the two processor interfaces. When you need access to the underlying response stream, implement the `Processor<T>` interface. When you want to parse XML, then extend the `AbstractStAXProcessor<T>` class, which implements the `StAXProcessor<T>` interface.

The following example shows how to return the first instance of a field in a response. This process is useful for pulling out information such as `SecurityInfo` strings, where you do not need the rest of the response.

    public class ElementValueProcessor extends AbstractStAXProcessor<String> {

        private final String elementName;

        public ElementValueProcessor(final String elementName) {
            this.elementName = elementName;
            setErrorProcessor(new ErrorProcessor());
        }

        @Override
        public String process(final XMLStreamReader xmlStreamReader) {
            try {
                if(isErrorResponse(xmlStreamReader)) {
                    processErrorResponse(xmlStreamReader);
                }

                String result = null;

                while(xmlStreamReader.hasNext()) {
                    final int elementType = xmlStreamReader.next();

                    if((elementType == XMLEvent.START_ELEMENT) &&
                            (elementName.equals(xmlStreamReader.getLocalName()))) {
                        result = xmlStreamReader.getElementText();
                        break;
                    }
                }

                return result;
            }
            catch(XMLStreamException e) {
                throw new ProcessorException(
                      "Unable to parse the ACI response.", e);
            }
        }

    }

The following example processes the response from the `UserReadUserList` action into a `UserList` `JavaBean`.

    public class UserReadUserListProcessor extends AbstractStAXProcessor<UserList> {

        public UserReadUserListProcessor() {
            setErrorProcessor(new ErrorProcessor());
        }

        @Override
        public UserList process(final XMLStreamReader xmlStreamReader) {
            try {
                if(isErrorResponse(xmlStreamReader)) {
                    processErrorResponse(xmlStreamReader);
                }

                final UserList userList = new UserList();

                while(xmlStreamReader.hasNext()) {
                    final int eventType = xmlStreamReader.next();

                    // We want the start elements...
                    if(XMLEvent.START_ELEMENT == eventType) {
                        if("autn:user".equalsIgnoreCase(
                                xmlStreamReader.getLocalName())) {
                            userList.addUserName(xmlStreamReader.getElementText());
                        }
                        else if("autn:totalusers".equalsIgnoreCase(
                              xmlStreamReader.getLocalName())) {
                            userList.setTotalUsers(NumberUtils.toInt(
                                  xmlStreamReader.getElementText()));
                        }
                        else if("autn:numusers".equalsIgnoreCase(
                              xmlStreamReader.getLocalName())) {
                            userList.setNumUsers(NumberUtils.toInt(
                                  xmlStreamReader.getElementText()));
                        }
                    }
                }

                return userList;
            }
            catch(XMLStreamException xmlse) {
                throw new ProcessorException(
                        "Unable to create a list of users.", xmlse);
            }
        }

    }

Copyright 2023 Open Text
Version 24.1 | Last updated December 2023

Send documentation feedback

Close

Send documentation feedback

To send feedback using your default email client, open an email window.

Otherwise, send your feedback and the information below to MFI-swpdl.idoldocsfeedback@opentext.com.

We appreciate your feedback!

Product: IDOL ACI API 24.1

Topic Title: Process an ACI Response