org.codice.ddf.catalog.twitter.source.TwitterSource.java Source code

Java tutorial

Introduction

Here is the source code for org.codice.ddf.catalog.twitter.source.TwitterSource.java

Source

/**
 * Copyright (c) Codice Foundation
 * <p/>
 * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or any later version.
 * <p/>
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details. A copy of the GNU Lesser General Public License
 * is distributed along with this program and can be found at
 * <http://www.gnu.org/licenses/lgpl.html>.
 **/
package org.codice.ddf.catalog.twitter.source;

import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ddf.catalog.data.ContentType;
import ddf.catalog.data.Metacard;
import ddf.catalog.data.Result;
import ddf.catalog.data.impl.MetacardImpl;
import ddf.catalog.data.impl.ResultImpl;
import ddf.catalog.operation.QueryRequest;
import ddf.catalog.operation.ResourceResponse;
import ddf.catalog.operation.SourceResponse;
import ddf.catalog.operation.impl.SourceResponseImpl;
import ddf.catalog.resource.ResourceNotFoundException;
import ddf.catalog.resource.ResourceNotSupportedException;
import ddf.catalog.resource.ResourceReader;
import ddf.catalog.source.FederatedSource;
import ddf.catalog.source.SourceMonitor;
import ddf.catalog.source.UnsupportedQueryException;
import twitter4j.GeoLocation;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;

public class TwitterSource implements FederatedSource {

    private static final Logger LOGGER = LoggerFactory.getLogger(TwitterSource.class);

    TwitterFactory twitterFactory;

    String id;

    ResourceReader resourceReader;

    String consumerKey;

    String consumerSecret;

    public TwitterSource() {

    }

    public void init() {
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
        Configuration configuration = configurationBuilder.setOAuthConsumerKey(consumerKey)
                .setOAuthConsumerSecret(consumerSecret).setApplicationOnlyAuthEnabled(true).build();

        twitterFactory = new TwitterFactory(configuration);
    }

    public void destroy() {
        twitterFactory = null;
    }

    @Override
    public ResourceResponse retrieveResource(URI uri, Map<String, Serializable> arguments)
            throws IOException, ResourceNotFoundException, ResourceNotSupportedException {
        return resourceReader.retrieveResource(uri, arguments);
    }

    @Override
    public Set<String> getSupportedSchemes() {
        return Collections.emptySet();
    }

    @Override
    public Set<String> getOptions(Metacard metacard) {
        return Collections.emptySet();
    }

    @Override
    public boolean isAvailable() {
        Twitter instance = twitterFactory.getInstance();
        try {
            instance.getOAuth2Token();
            return true;
        } catch (TwitterException e) {
            LOGGER.error("Unable to get OAuth2 token.", e);
            return false;
        }
    }

    @Override
    public boolean isAvailable(SourceMonitor callback) {
        if (isAvailable()) {
            callback.setAvailable();
            return true;
        } else {
            callback.setUnavailable();
            return false;
        }
    }

    @Override
    public SourceResponse query(QueryRequest request) throws UnsupportedQueryException {
        Twitter instance = twitterFactory.getInstance();
        try {
            instance.getOAuth2Token();
        } catch (TwitterException e) {
            throw new UnsupportedQueryException("Unable to get OAuth2 token.", e);
        }
        TwitterFilterVisitor visitor = new TwitterFilterVisitor();
        request.getQuery().accept(visitor, null);
        Query query = new Query();
        query.setCount(request.getQuery().getPageSize());
        if (visitor.hasSpatial()) {
            GeoLocation geoLocation = new GeoLocation(visitor.getLatitude(), visitor.getLongitude());
            query.setGeoCode(geoLocation, visitor.getRadius(), Query.Unit.km);
        }
        if (visitor.getContextualSearch() != null) {
            query.setQuery(visitor.getContextualSearch().getSearchPhrase());
        }
        if (visitor.getTemporalSearch() != null) {
            Calendar.Builder builder = new Calendar.Builder();
            builder.setInstant(visitor.getTemporalSearch().getStartDate());
            Calendar calendar = builder.build();
            query.setSince(calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH) + "-"
                    + calendar.get(Calendar.DAY_OF_MONTH));

            builder = new Calendar.Builder();
            builder.setInstant(visitor.getTemporalSearch().getEndDate());
            calendar = builder.build();
            query.setUntil(calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH) + "-"
                    + calendar.get(Calendar.DAY_OF_MONTH));
        }

        QueryResult queryResult;
        try {
            queryResult = instance.search().search(query);
        } catch (TwitterException e) {
            throw new UnsupportedQueryException(e);
        }
        List<Result> resultList = new ArrayList<>(queryResult.getCount());
        resultList.addAll(queryResult.getTweets().stream().map(status -> new ResultImpl(getMetacard(status)))
                .collect(Collectors.toList()));
        return new SourceResponseImpl(request, resultList);
    }

    private Metacard getMetacard(Status status) {
        MetacardImpl metacard = new MetacardImpl();
        metacard.setSourceId(id);
        metacard.setId(String.valueOf(status.getId()));
        metacard.setTitle(status.getText());
        metacard.setMetadata("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "<Resource>"
                + "<name>" + status.getText() + "</name>" + "</Resource>");
        metacard.setCreatedDate(status.getCreatedAt());
        metacard.setModifiedDate(status.getCreatedAt());
        metacard.setEffectiveDate(status.getCreatedAt());
        metacard.setPointOfContact(status.getUser().getName());
        if (status.getURLEntities() != null && status.getURLEntities().length > 0) {
            try {
                metacard.setResourceURI(new URI(status.getURLEntities()[0].getExpandedURL()));
            } catch (URISyntaxException e) {
                LOGGER.error("Unable to set resource URI.", e);
            }
        } else if (status.getMediaEntities() != null && status.getMediaEntities().length > 0) {
            try {
                metacard.setResourceURI(new URI(status.getMediaEntities()[0].getExpandedURL()));
            } catch (URISyntaxException e) {
                LOGGER.error("Unable to set resource URI.", e);
            }
        } else if (status.getExtendedMediaEntities() != null && status.getExtendedMediaEntities().length > 0) {
            try {
                metacard.setResourceURI(new URI(status.getExtendedMediaEntities()[0].getExpandedURL()));
            } catch (URISyntaxException e) {
                LOGGER.error("Unable to set resource URI.", e);
            }
        }
        GeoLocation geoLocation = status.getGeoLocation();
        if (geoLocation != null) {
            metacard.setLocation("POINT (" + geoLocation.getLongitude() + " " + geoLocation.getLatitude() + ")");
        }

        return metacard;
    }

    @Override
    public Set<ContentType> getContentTypes() {
        return Collections.emptySet();
    }

    @Override
    public String getVersion() {
        return "1";
    }

    @Override
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String getTitle() {
        return "Twitter Federated Source";
    }

    @Override
    public String getDescription() {
        return "Query using the Twitter API.";
    }

    @Override
    public String getOrganization() {
        return "Codice";
    }

    public String getConsumerKey() {
        return consumerKey;
    }

    public void setConsumerKey(String consumerKey) {
        this.consumerKey = consumerKey;
    }

    public String getConsumerSecret() {
        return consumerSecret;
    }

    public void setConsumerSecret(String consumerSecret) {
        this.consumerSecret = consumerSecret;
    }

    public void setResourceReader(ResourceReader resourceReader) {
        this.resourceReader = resourceReader;
    }
}