/************************************************************************* * Copyright 2014 Infield Design * * Licensed 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. * * @author Gaetan Marmasse <gaetan@infielddesign.com> * *************************************************************************/ package com.infield.googlesearch; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.customsearch.Customsearch; import com.google.api.services.customsearch.CustomsearchRequestInitializer; import com.google.api.services.customsearch.model.Result; import com.google.api.services.customsearch.model.Search; import com.google.api.services.customsearch.model.Search.SearchInformation; import com.infield.googlesearch.model.ResultItem; import com.infield.googlesearch.model.ResultList; public class GoogleSearchService { private final Logger log = LoggerFactory.getLogger(getClass()); private String apikey = ""; private String applicationname = ""; private String cx = ""; private long num = 7; private long pagesToShow = 10; private Long pagesRight; private Long pagesLeft; private Customsearch customsearch; private LinkedList<ResultItem> resultItems; static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); @SuppressWarnings("unused") private static final long serialVersionUID = 1; public GoogleSearchService(String apikey, String applicationname, String cx) { this.apikey = apikey; this.applicationname = applicationname; this.cx = cx; } public ResultList getResults(String q, String currentTab, long num, long pagesToShow) { this.num = num; this.pagesToShow = pagesToShow; ResultList resultList = new ResultList().setResultItems(new LinkedList<ResultItem>()); this.pagesLeft = (this.pagesToShow - (pagesToShow % 2)) / 2; this.pagesRight = this.pagesToShow - this.pagesLeft; // currentPage starts from 1 Long currentPage = Long.valueOf(currentTab); Customsearch.Cse.List list; Search results = null; try { customsearch = new Customsearch.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, null) .setApplicationName(applicationname) .setGoogleClientRequestInitializer(new CustomsearchRequestInitializer(apikey)) .build(); list = customsearch.cse().list(q) .setNum(this.num) .setStart((this.num * (currentPage - 1)) + 1) .setCx(cx); results = list.execute(); } catch (IOException e) { log.error(e.getMessage(), e); } catch (GeneralSecurityException e) { log.error(e.getMessage(), e); } finally { SearchInformation searchInformation = (results != null) ? results.getSearchInformation() : null; this.resultItems = new LinkedList<ResultItem>(); if (searchInformation != null){ Long totalResults = searchInformation.getTotalResults(); Long totalPages = (totalResults - (totalResults % this.num))/this.num + 1; this.pagesToShow = (totalPages > this.pagesToShow) ? this.pagesToShow : totalPages; resultList.setTotalPages(totalPages) .setPagesToShow(this.pagesToShow) .setTotalResults(searchInformation.getTotalResults()) .setFormattedSearchTime(searchInformation.getFormattedSearchTime()) .setFormattedTotalResults(searchInformation.getFormattedTotalResults()) .setSearchTime(searchInformation.getSearchTime()) .setStartPage(getStartPage(currentPage)) .setEndPage(getEndPage(currentPage)) .setCurrentTab(currentPage); //TODO: Labels and Images List<Result> searchResults = results.getItems() != null ? results.getItems() : new LinkedList<Result>(); for (Result searchResult : searchResults){ ResultItem resultItem = new ResultItem(); resultItem.setCacheId(searchResult.getCacheId()); resultItem.setDisplayLink(searchResult.getDisplayLink()); resultItem.setFileFormat(searchResult.getFileFormat()); resultItem.setFormattedUrl(searchResult.getFormattedUrl()); resultItem.setHtmlFormattedUrl(searchResult.getHtmlFormattedUrl()); resultItem.setHtmlSnippet(searchResult.getHtmlSnippet()); resultItem.setHtmlTitle(searchResult.getHtmlTitle()); resultItem.setKind(searchResult.getKind()); //resultItem.setLabels(searchResult.getLabels()); resultItem.setLink(searchResult.getLink()); resultItem.setMime(searchResult.getMime()); resultItem.setSnippet(searchResult.getSnippet()); resultItem.setTitle(searchResult.getTitle()); resultItems.add(resultItem); } resultList.setResultItems(resultItems); } } return resultList; } private long getEndPage(long currentPage) { this.pagesLeft = (pagesToShow - (pagesToShow % 2)) / 2; this.pagesRight = pagesToShow - this.pagesLeft; long cp = currentPage - 1; long startPage = cp - this.pagesLeft; long endPage = cp + this.pagesRight; startPage = (startPage < 0) ? 0 : startPage; endPage = (endPage > pagesToShow - 1) ? pagesToShow - 1: endPage; while ((endPage - startPage) < pagesToShow && (startPage == 0) && endPage < pagesToShow - 1) { endPage++; } return endPage + 1; } private long getStartPage(long currentPage) { this.pagesLeft = (pagesToShow - (pagesToShow % 2)) / 2; this.pagesRight = pagesToShow - this.pagesLeft; long cp = currentPage - 1; long startPage = cp - this.pagesLeft; long endPage = cp + this.pagesRight; startPage = (startPage < 0) ? 0 : startPage; endPage = (endPage > pagesToShow - 1) ? pagesToShow - 1: endPage; while ((endPage - startPage) < pagesToShow && (endPage == pagesToShow - 1) && startPage > 0) { startPage--; } return startPage + 1; } }