org.apache.manifoldcf.agents.output.opensearchserver.OpenSearchServerConnection.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.manifoldcf.agents.output.opensearchserver.OpenSearchServerConnection.java

Source

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.manifoldcf.agents.output.opensearchserver;

import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.io.StringWriter;
import java.io.Reader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.ContentType;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.client.RedirectException;
import org.apache.http.client.CircularRedirectException;
import org.apache.http.NoHttpResponseException;
import org.apache.http.HttpException;
import org.apache.http.ParseException;

import org.apache.manifoldcf.agents.interfaces.IOutputHistoryActivity;
import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
import org.apache.manifoldcf.core.util.URLEncoder;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class OpenSearchServerConnection {

    private String serverLocation;

    private String indexName;

    private String userName;

    private String apiKey;

    private String resultDescription;

    private String callUrlSnippet;

    private String response;

    private Document xmlResponse;

    private HttpClient httpClient;

    protected String xPathStatus = "/response/entry[@key='Status']/text()";
    protected String xPathException = "/response/entry[@key='Exception']/text()";

    public enum Result {
        OK, ERROR, UNKNOWN;
    }

    private Result result;

    private String resultCode;

    protected OpenSearchServerConnection(HttpClient client, OpenSearchServerConfig config) {
        this.httpClient = client;
        result = Result.UNKNOWN;
        response = null;
        xmlResponse = null;
        resultDescription = "";
        callUrlSnippet = null;
        serverLocation = config.getServerLocation();
        indexName = config.getIndexName();
        userName = config.getUserName();
        apiKey = config.getApiKey();
    }

    protected StringBuffer getApiUrl(String command) throws ManifoldCFException {
        StringBuffer url = new StringBuffer(serverLocation);
        if (!serverLocation.endsWith("/"))
            url.append('/');
        url.append(command);
        url.append("?use=");
        url.append(URLEncoder.encode(indexName));
        callUrlSnippet = url.toString();
        if (userName != null && apiKey != null && userName.length() > 0 && apiKey.length() > 0) {
            url.append("&login=");
            url.append(URLEncoder.encode(userName));
            url.append("&key=");
            url.append(apiKey);
        }
        return url;
    }

    protected StringBuffer getApiUrlV2(String path) throws ManifoldCFException {
        StringBuffer url = new StringBuffer(serverLocation);
        if (!serverLocation.endsWith("/"))
            url.append('/');
        url.append(path);
        callUrlSnippet = url.toString();
        if (userName != null && apiKey != null && userName.length() > 0 && apiKey.length() > 0) {
            url.append("&login=");
            url.append(URLEncoder.encode(userName));
            url.append("&key=");
            url.append(apiKey);
        }
        return url;
    }

    protected static class CallThread extends Thread {
        protected final HttpClient client;
        protected final HttpRequestBase method;
        protected int resultCode = -1;
        protected String response = null;
        protected Throwable exception = null;

        public CallThread(HttpClient client, HttpRequestBase method) {
            this.client = client;
            this.method = method;
            setDaemon(true);
        }

        @Override
        public void run() {
            try {
                try {
                    HttpResponse resp = client.execute(method);
                    resultCode = resp.getStatusLine().getStatusCode();
                    HttpEntity entity = resp.getEntity();
                    response = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                } finally {
                    method.abort();
                }
            } catch (java.net.SocketTimeoutException e) {
                exception = e;
            } catch (InterruptedIOException e) {
                // Just exit
            } catch (Throwable e) {
                exception = e;
            }
        }

        public int getResultCode() {
            return resultCode;
        }

        public String getResponse() {
            return response;
        }

        public void finishUp() throws InterruptedException, HttpException, IOException {
            join();
            Throwable t = exception;
            if (t != null) {
                if (t instanceof HttpException)
                    throw (HttpException) t;
                else if (t instanceof IOException)
                    throw (IOException) t;
                else if (t instanceof RuntimeException)
                    throw (RuntimeException) t;
                else if (t instanceof Error)
                    throw (Error) t;
                else
                    throw new RuntimeException("Unexpected exception thrown: " + t.getMessage(), t);
            }
        }
    }

    protected void call(HttpRequestBase method) throws ManifoldCFException {
        CallThread ct = new CallThread(httpClient, method);
        try {
            ct.start();
            try {
                ct.finishUp();

                if (!checkResultCode(ct.getResultCode()))
                    throw new ManifoldCFException(getResultDescription());
                response = ct.getResponse();
            } catch (InterruptedException e) {
                ct.interrupt();
                throw new ManifoldCFException("Interrupted: " + e.getMessage(), e, ManifoldCFException.INTERRUPTED);
            }
        } catch (java.net.SocketTimeoutException e) {
            setResult(e.getClass().getSimpleName().toUpperCase(Locale.ROOT), Result.ERROR, e.getMessage());
            throw new ManifoldCFException(
                    "SocketTimeoutException while calling " + method.getURI() + ": " + e.getMessage(), e);
        } catch (InterruptedIOException e) {
            setResult(e.getClass().getSimpleName().toUpperCase(Locale.ROOT), Result.ERROR, e.getMessage());
            throw new ManifoldCFException("Interrupted: " + e.getMessage(), e, ManifoldCFException.INTERRUPTED);
        } catch (HttpException e) {
            setResult(e.getClass().getSimpleName().toUpperCase(Locale.ROOT), Result.ERROR, e.getMessage());
            throw new ManifoldCFException("HttpException while calling " + method.getURI() + ": " + e.getMessage(),
                    e);
        } catch (IOException e) {
            setResult(e.getClass().getSimpleName().toUpperCase(Locale.ROOT), Result.ERROR, e.getMessage());
            throw new ManifoldCFException("IOException while calling " + method.getURI() + ": " + e.getMessage(),
                    e);
        }
    }

    private void readXmlResponse() throws ManifoldCFException {
        if (xmlResponse != null)
            return;
        StringReader sw = null;
        try {
            sw = new StringReader(response);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true); // never forget this!
            DocumentBuilder builder;
            builder = dbf.newDocumentBuilder();
            xmlResponse = builder.parse(new InputSource(sw));
        } catch (ParserConfigurationException e) {
            throw new ManifoldCFException(e);
        } catch (SAXException e) {
            throw new ManifoldCFException(e);
        } catch (IOException e) {
            throw new ManifoldCFException(e);
        } finally {
            if (sw != null) {
                sw.close();
            }
        }
    }

    protected String checkXPath(String xPathQuery) throws ManifoldCFException {
        try {
            readXmlResponse();
            XPathFactory factory = XPathFactory.newInstance();
            XPath xpath = factory.newXPath();
            XPathExpression xPathExpr = xpath.compile(xPathQuery);
            return xPathExpr.evaluate(xmlResponse);
        } catch (XPathExpressionException e) {
            throw new ManifoldCFException(e);
        }
    }

    protected void setResult(String resultCode, Result res, String desc) {
        if (res != null)
            result = res;
        if (desc != null)
            if (desc.length() > 0)
                resultDescription = desc;
        setResultCode(resultCode);
    }

    public String getResultDescription() {
        return resultDescription;
    }

    protected String getResponse() {
        return response;
    }

    private boolean checkResultCode(int code) {
        switch (code) {
        case 0:
            setResult(IOutputHistoryActivity.HTTP_ERROR, Result.UNKNOWN, null);
            return false;
        case 200:
            setResult("OK", Result.OK, null);
            return true;
        case 404:
            setResult(IOutputHistoryActivity.HTTP_ERROR, Result.ERROR, "Server/page not found");
            return false;
        default:
            setResult(IOutputHistoryActivity.HTTP_ERROR, Result.ERROR, null);
            return false;
        }
    }

    public Result getResult() {
        return result;
    }

    public String getCallUrlSnippet() {
        return callUrlSnippet;
    }

    public void setResultCode(String resultCode) {
        this.resultCode = resultCode;
    }

    public String getResultCode() {
        return resultCode;
    }
}