/** * */ package au.edu.anu.datacommons.external; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; 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.UriBuilder; import javax.ws.rs.core.UriInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import au.edu.anu.datacommons.services.DisplayResource; import au.edu.anu.datacommons.webservice.bindings.FedoraItem; import com.sun.jersey.api.view.Viewable; /** * REST API endpoint that accepts requests: * <ul> * <li>to display a page that accepts parameter values for selected metadata provider. * <li>to call the selected metadata provider passing on given parameters to it. When the provider returns the fedora * item it passes those metadata values to the create new item page so the form can be prepopulated. * </ul> * * @author Rahul Khanna * */ @Component @Scope("request") @Path("/extmetadata") public class ExternalMetadataResource { private static final Logger LOGGER = LoggerFactory.getLogger(ExternalMetadataResource.class); private static final String EXT_METADATA_JSP = "/extdata.jsp"; /** * List of external metadata providers */ @Autowired List<ExternalMetadataProvider> extMetadataProviders; @Context private HttpServletRequest request; /** * * @param uriInfo * @return */ @GET @Produces(MediaType.TEXT_HTML) @PreAuthorize("hasRole('ROLE_ANU_USER')") public Response getExternalMetadataSources(@Context UriInfo uriInfo) { Response resp = null; MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); String metadataProvider = queryParams.getFirst("provider"); if (metadataProvider == null || metadataProvider.length() == 0) { resp = generateInputFormPage(); } else { LOGGER.info("User {} ({}) requested metadata from {} with params {}", getCurUsername(), getRemoteIp(), metadataProvider, queryParams); resp = createRetrieveMetadataResponse(resp, queryParams, metadataProvider); if (resp == null) { resp = generateInputFormPage(); } } return resp; } private Response createRetrieveMetadataResponse(Response resp, MultivaluedMap<String, String> queryParams, String extMetadataSource) { for (ExternalMetadataProvider provider : extMetadataProviders) { if (provider.getClass().getName().equals(extMetadataSource)) { try { resp = retrieveMetadata(provider, queryParams); } catch (ExternalMetadataException e) { resp = Response.serverError().entity(e.getMessage()).build(); } break; } } return resp; } private Response retrieveMetadata(ExternalMetadataProvider provider, MultivaluedMap<String, String> formParams) throws ExternalMetadataException { Response resp = null; FedoraItem retrievedItem = provider.retrieveMetadata(formParams); UriBuilder newItemRedirUrl = UriBuilder.fromResource(DisplayResource.class).path(DisplayResource.class, "newItemPage"); for (Entry<String, List<String>> entry : retrievedItem.generateDataMap().entrySet()) { if (entry.getValue() != null && !entry.getValue().isEmpty()) { for (String iValue : entry.getValue()) { if (iValue != null && iValue.length() > 0) { newItemRedirUrl = newItemRedirUrl.queryParam(entry.getKey(), iValue); } } } } resp = Response.seeOther(newItemRedirUrl.build()).build(); return resp; } private Response generateInputFormPage() { Map<String, Object> model = new HashMap<>(); model.put("providers", extMetadataProviders); Response resp = Response.ok(new Viewable(EXT_METADATA_JSP, model)).build(); return resp; } /** * Gets the username of the currently logged-in user. * * @return Username as String */ private String getCurUsername() { return SecurityContextHolder.getContext().getAuthentication().getName(); } /** * Gets the IP address of the logged-in user. * @return */ private String getRemoteIp() { return request.getRemoteAddr(); } }