org.eclipse.recommenders.coordinates.maven.MavenCentralFingerprintSearchAdvisor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.recommenders.coordinates.maven.MavenCentralFingerprintSearchAdvisor.java

Source

/**
 * Copyright (c) 2010, 2013 Darmstadt University of Technology.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Andreas Sewe - initial API and implementation
 */
package org.eclipse.recommenders.coordinates.maven;

import static com.google.common.base.Optional.absent;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.recommenders.coordinates.Coordinates.tryNewProjectCoordinate;
import static org.eclipse.recommenders.coordinates.DependencyType.JAR;
import static org.eclipse.recommenders.utils.Versions.canonicalizeVersion;

import java.net.URL;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.eclipse.recommenders.coordinates.AbstractProjectCoordinateAdvisor;
import org.eclipse.recommenders.coordinates.DependencyInfo;
import org.eclipse.recommenders.coordinates.DependencyType;
import org.eclipse.recommenders.coordinates.ProjectCoordinate;
import org.eclipse.recommenders.utils.Fingerprints;
import org.eclipse.recommenders.utils.Urls;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Optional;

public class MavenCentralFingerprintSearchAdvisor extends AbstractProjectCoordinateAdvisor {

    public static final URL SEARCH_MAVEN_ORG = Urls.toUrl("http://search.maven.org/solrsearch");

    private static final Logger LOG = LoggerFactory.getLogger(MavenCentralFingerprintSearchAdvisor.class);

    private static final int NETWORK_TIMEOUT = (int) SECONDS.toMillis(3);

    private static final List<String> SUPPORTED_PACKAGINGS = Arrays.asList("jar", "war", "bundle");

    private static final String FIELD_GROUP_ID = "g";
    private static final String FIELD_ARTIFACT_ID = "a";
    private static final String FIELD_VERSION = "v";
    private static final String FIELD_PACKAGING = "p";

    private SolrServer server;

    public MavenCentralFingerprintSearchAdvisor() {
        this(null, -1);
    }

    public MavenCentralFingerprintSearchAdvisor(String proxyHost, int proxyPort) {
        this(proxyHost, proxyPort, null);
    }

    public MavenCentralFingerprintSearchAdvisor(String proxyHost, int proxyPort, String proxyUser) {
        this(proxyHost, proxyPort, proxyUser, null);
    }

    public MavenCentralFingerprintSearchAdvisor(String proxyHost, int proxyPort, String proxyUser,
            String proxyPassword) {
        server = createSolrServer(proxyHost, proxyPort, proxyUser, proxyPassword);
    }

    @Override
    protected boolean isApplicable(DependencyType dependencyType) {
        return dependencyType == JAR;
    }

    @Override
    protected Optional<ProjectCoordinate> doSuggest(DependencyInfo dependencyInfo) {
        if (!dependencyInfo.getFile().isFile()) {
            return absent();
        }

        try {
            SolrQuery query = new SolrQuery();
            query.setQuery("1:\"" + Fingerprints.sha1(dependencyInfo.getFile()) + "\"");
            query.setRows(1);
            QueryResponse response = server.query(query);
            SolrDocumentList results = response.getResults();

            for (SolrDocument document : results) {
                if (!SUPPORTED_PACKAGINGS.contains(document.get(FIELD_PACKAGING))) {
                    continue;
                }

                String groupId = (String) document.get(FIELD_GROUP_ID);
                String artifactId = (String) document.get(FIELD_ARTIFACT_ID);
                String version = (String) document.get(FIELD_VERSION);

                return tryNewProjectCoordinate(groupId, artifactId, canonicalizeVersion(version));
            }

            return absent();
        } catch (SolrServerException e) {
            LOG.error("Exception when querying Solr Server <{}>", SEARCH_MAVEN_ORG, e);
            return absent();
        }
    }

    public void setProxy(String host, int port, String user, String password) {
        server = createSolrServer(host, port, user, password);
    }

    private CommonsHttpSolrServer createSolrServer(String proxyHost, int proxyPort, String proxyUser,
            String proxyPassword) {
        HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

        // Need to set these on the connection manager ourselves rather than using
        // CommonsHttpSolrServer.setConnectionTimeout and CommonsHttpSolrServer.setSoTimeout, as the bundle
        // org.apache.solr.client.solrj is missing a necessary import of package org.apache.commons.httpclient.params.
        // See <https://bugs.eclipse.org/bugs/show_bug.cgi?id=413496>.
        connectionManager.getParams().setConnectionTimeout(NETWORK_TIMEOUT);
        connectionManager.getParams().setSoTimeout(NETWORK_TIMEOUT);

        final HttpClient httpClient = new HttpClient(connectionManager);

        if (proxyHost != null) {
            httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
        }
        if (proxyUser != null) {
            Credentials credentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
            httpClient.getState().setProxyCredentials(AuthScope.ANY, credentials);
        }

        final CommonsHttpSolrServer server = new CommonsHttpSolrServer(SEARCH_MAVEN_ORG, httpClient);

        server.setAllowCompression(true);
        server.setParser(new XMLResponseParser());

        return server;
    }
}