de.mpg.imeji.presentation.servlet.autocompleter.java Source code

Java tutorial

Introduction

Here is the source code for de.mpg.imeji.presentation.servlet.autocompleter.java

Source

package de.mpg.imeji.presentation.servlet;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import de.mpg.imeji.logic.storage.util.StorageUtils;

/**
 * Servlet implementation class autocompleter
 */
@WebServlet(description = "act as bridge for front javascript query since javascript cannot query cross domain, e.g., from imeji to google", urlPatterns = {
        "/autocompleter" })
public class autocompleter extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private Pattern conePattern = Pattern.compile("http.*/cone/.*?format=json.*", Pattern.CASE_INSENSITIVE);
    private Pattern coneAuthorPattern = Pattern.compile("http.*/cone/persons/.*?format=json.*",
            Pattern.CASE_INSENSITIVE);
    private Pattern googleGeoAPIPattern = Pattern
            .compile("https://maps.googleapis.com/maps/api/geocode/json.*address=", Pattern.CASE_INSENSITIVE);
    private Pattern ccLicensePattern = Pattern.compile("http://api.creativecommons.org/rest/.*/simple/chooser.*");

    /**
     * @see HttpServlet#HttpServlet()
     */
    public autocompleter() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String suggest = request.getParameter("searchkeyword");
        String datasource = request.getParameter("datasource");
        String responseString = "";
        if (suggest.isEmpty()) {
            suggest = "a";
        } else if (datasource != null && !datasource.isEmpty()) {
            HttpClient client = new HttpClient();
            GetMethod getMethod = new GetMethod(datasource + URLEncoder.encode(suggest.toString(), "UTF-8"));
            try {
                client.executeMethod(getMethod);
                responseString = new String(StorageUtils.toBytes(getMethod.getResponseBodyAsStream()), "UTF-8");
                if (datasource != null && responseString != null)
                    responseString = passResult(responseString, datasource);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                getMethod.releaseConnection();
            }
        }
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();
        out.print(responseString);
        out.flush();
        out.close();
    }

    /**
     * parse JSON string returned from remote source by JSON-simple add properties [ { label: "Choice1", value: "value1"
     * }, ... ] to fit JQuery UI auto-complete pop format
     * 
     * @param input
     * @param source
     * @return
     * @throws IOException
     */
    private String passResult(String input, String source) throws IOException {
        if (conePattern.matcher(source).matches()) {
            if (coneAuthorPattern.matcher(source).matches()) {
                return parseConeAuthor(input);
            } else {
                return parseConeVocabulary(input);
            }
        } else if (googleGeoAPIPattern.matcher(source).matches()) {
            return parseGoogleGeoAPI(input);
        } else if (ccLicensePattern.matcher(source).matches()) {
            return parseCCLicense(input);
        }
        return input;
    }

    /**
     * Parse a CoNE Vocabulary (read the title value)
     * 
     * @param cone
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    private String parseConeVocabulary(String cone) throws IOException {
        Object obj = JSONValue.parse(cone);
        JSONArray array = (JSONArray) obj;
        JSONArray result = new JSONArray();
        for (int i = 0; i < array.size(); ++i) {
            JSONObject parseObject = (JSONObject) array.get(i);
            JSONObject sendObject = new JSONObject();
            sendObject.put("label", parseObject.get("http_purl_org_dc_elements_1_1_title"));
            sendObject.put("value", parseObject.get("http_purl_org_dc_elements_1_1_title"));
            result.add(sendObject);
        }
        StringWriter out = new StringWriter();
        result.writeJSONString(out);
        return out.toString();
    }

    /**
     * Parse a json input from Google Geo API
     * 
     * @param google
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    private String parseGoogleGeoAPI(String google) throws IOException {
        JSONObject obj = (JSONObject) JSONValue.parse(google);
        JSONArray array = (JSONArray) obj.get("results");
        JSONArray result = new JSONArray();
        for (int i = 0; i < array.size(); ++i) {
            JSONObject parseObject = (JSONObject) array.get(i);
            JSONObject sendObject = new JSONObject();
            sendObject.put("label", parseObject.get("formatted_address"));
            sendObject.put("value", parseObject.get("formatted_address"));
            JSONObject location = (JSONObject) ((JSONObject) parseObject.get("geometry")).get("location");
            sendObject.put("latitude", location.get("lat"));
            sendObject.put("longitude", location.get("lng"));
            result.add(sendObject);
        }
        StringWriter out = new StringWriter();
        result.writeJSONString(out);
        return out.toString();
    }

    /**
     * Parse a JSON file from CoNE with authors, and return a JSON which can be read by imeji autocomplete
     * 
     * @param cone
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    private String parseConeAuthor(String cone) throws IOException {
        Object obj = JSONValue.parse(cone);
        JSONArray array = (JSONArray) obj;
        JSONArray result = new JSONArray();
        for (int i = 0; i < array.size(); ++i) {
            JSONObject parseObject = (JSONObject) array.get(i);
            JSONObject sendObject = new JSONObject();
            sendObject.put("label", parseObject.get("http_purl_org_dc_elements_1_1_title"));
            sendObject.put("family", parseObject.get("http_xmlns_com_foaf_0_1_family_name"));
            sendObject.put("givenname", parseObject.get("http_xmlns_com_foaf_0_1_givenname"));
            sendObject.put("id", parseObject.get("id"));
            sendObject.put("orgs",
                    writeJsonArrayToOneString(parseObject.get("http_purl_org_escidoc_metadata_terms_0_1_position"),
                            "http_purl_org_eprint_terms_affiliatedInstitution"));
            sendObject.put("alternatives",
                    writeJsonArrayToOneString(parseObject.get("http_purl_org_dc_terms_alternative"), ""));
            result.add(sendObject);
        }
        StringWriter out = new StringWriter();
        JSONArray.writeJSONString(result, out);
        return out.toString();
    }

    private String parseCCLicense(String str) {
        str = "<licences>" + str + "</licences>";
        try {
            JSONArray json = new JSONArray();
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            org.w3c.dom.Document doc = dBuilder.parse(new ByteArrayInputStream(str.getBytes()));
            doc.getDocumentElement().normalize();
            NodeList nList = ((org.w3c.dom.Document) doc).getElementsByTagName("option");
            for (int i = 0; i < nList.getLength(); i++) {
                Node nNode = nList.item(i);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    JSONObject license = new JSONObject();
                    Element eElement = (Element) nNode;
                    license.put("label", eElement.getTextContent());
                    license.put("value", eElement.getTextContent());
                    license.put("licenseId", eElement.getAttribute("value"));
                    json.add(license);
                }
            }
            StringWriter out = new StringWriter();
            JSONArray.writeJSONString(json, out);
            return out.toString();
        } catch (Exception e) {
            log("Error Parsing CC License", e);
        }
        return str;
    }

    /**
     * Read a JSON Object as a String, whether it is an {@link JSONArray}, a {@link String} or a {@link JSONObject}
     * 
     * @param jsonObj
     * @param jsonName
     * @return
     */
    private String writeJsonArrayToOneString(Object jsonObj, String jsonName) {
        String str = "";
        if (jsonObj instanceof JSONArray) {
            for (Iterator<?> iterator = ((JSONArray) jsonObj).iterator(); iterator.hasNext();) {
                if (!"".equals(str)) {
                    str += ", ";
                }
                str += writeJsonArrayToOneString(iterator.next(), jsonName);
            }
        } else if (jsonObj instanceof JSONObject) {
            str = (String) ((JSONObject) jsonObj).get(jsonName);
        } else if (jsonObj instanceof String) {
            str = (String) jsonObj;
        }
        return str;
    }
}