/*
* Copyright 2012 Nodeable Inc
*
* 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.
*/
package com.streamreduce.rest.resource.api;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.streamreduce.core.model.Account;
import com.streamreduce.core.model.messages.SobaMessage;
import com.streamreduce.core.service.SearchService;
import com.streamreduce.core.service.SecurityService;
import com.streamreduce.core.service.UserService;
import com.streamreduce.rest.dto.response.SobaMessageResponseDTO;
import com.streamreduce.rest.resource.AbstractResource;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Path("api/search/messages")
public class SearchMessageResource extends AbstractResource {
@Autowired
UserService userService;
@Autowired
SecurityService securityService;
@Autowired
SearchService searchService;
/**
*
* @response.representation.200.doc Search results
* @response.representation.200.mediaType application/json
* @response.representation.500.doc If a general exception occurs.
* @response.representation.404.mediaType text/plain
*
* @param query
* @param resourceName
* @param uriInfo
* @return the response body
*/
@POST
@Path("{resourceName}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response searchMessagesPassthrough(JSONObject query,
@PathParam("resourceName") String resourceName,
@Context UriInfo uriInfo) {
try {
Account currentAccount = securityService.getCurrentUser().getAccount();
ImmutableMap<String, String> queryParameters = ImmutableMap.copyOf(flattenValues(uriInfo.getQueryParameters()));
List<SobaMessage> sobaMessages = searchService.searchMessages(currentAccount, resourceName, queryParameters, query);
boolean fullText = queryParameters.get("fullText") != null ? Boolean.valueOf(queryParameters.get("fullText")) : false;
return Response
.ok(SobaMessageResponseDTO.fromSobaMessages(sobaMessages,fullText))
.build();
} catch (Exception e) {
String errorMessage = "Unable to perform search: " + e.getMessage();
logger.info(errorMessage,e);
return error(errorMessage, Response.serverError());
}
}
/**
* Compresses the values in a Map<String,Collection<String>> to Strings by selecting the first valid
* value in the Collection. This method is presumed to only be called with the value of UriInfo.getQueryParameters.
*
* @param map
* @return
*/
private Map<String, String> flattenValues(MultivaluedMap<String, String> map) {
HashMap<String, String> newMap = new HashMap<>();
for (String key : map.keySet()) {
Collection<String> value = map.get(key);
Optional<String> possibleFind = Iterables.tryFind(value, new Predicate<String>() {
@Override
public boolean apply(@Nullable String input) {
return (input != null && StringUtils.isNotBlank(input));
}
});
if (possibleFind.isPresent()) {
newMap.put(key, possibleFind.get());
}
}
return newMap;
}
}