au.org.ala.biocache.web.AssertionController.java Source code

Java tutorial

Introduction

Here is the source code for au.org.ala.biocache.web.AssertionController.java

Source

/**************************************************************************
 *  Copyright (C) 2013 Atlas of Living Australia
 *  All Rights Reserved.
 * 
 *  The contents of this file are subject to the Mozilla Public
 *  License Version 1.1 (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.mozilla.org/MPL/
 * 
 *  Software distributed under the License is distributed on an "AS
 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 *  implied. See the License for the specific language governing
 *  rights and limitations under the License.
 ***************************************************************************/
package au.org.ala.biocache.web;

import au.org.ala.biocache.Store;
import au.org.ala.biocache.model.FullRecord;
import au.org.ala.biocache.model.QualityAssertion;
import au.org.ala.biocache.model.Versions;
import au.org.ala.biocache.vocab.ErrorCode;
import au.org.ala.biocache.service.AuthService;
import au.org.ala.biocache.util.AssertionUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.HttpURLConnection;
import java.util.List;

/**
 * This controller provides web services for assertion creation/deletion.
 *
 * TODO Add support for API keys so that only registered applications can
 * use these functions.
 */
@Controller
public class AssertionController extends AbstractSecureController {

    private final static Logger logger = Logger.getLogger(AssertionController.class);
    @Inject
    protected AssertionUtils assertionUtils;
    @Value("${registry.url:http://collections.ala.org.au}")
    protected String registryUrl = "http://collections.ala.org.au";
    @Inject
    protected AuthService authService;

    /**
     * Retrieve an array of the assertion codes in use by the processing system
     *
     * @return an array of codes
     * @throws Exception
     */
    @RequestMapping(value = { "/assertions/codes", "/assertions/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showCodes() throws Exception {
        return Store.retrieveAssertionCodes();
    }

    @RequestMapping(value = { "/assertions/geospatial/codes",
            "/assertions/geospatial/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showGeospatialCodes() throws Exception {
        return Store.retrieveGeospatialCodes();
    }

    @RequestMapping(value = { "/assertions/taxonomic/codes",
            "/assertions/taxonomic/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showTaxonomicCodes() throws Exception {
        return Store.retrieveTaxonomicCodes();
    }

    @RequestMapping(value = { "/assertions/temporal/codes",
            "/assertions/temporal/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showTemporalCodes() throws Exception {
        return Store.retrieveTemporalCodes();
    }

    @RequestMapping(value = { "/assertions/miscellaneous/codes",
            "/assertions/miscellaneous/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showMiscellaneousCodes() throws Exception {
        return Store.retrieveMiscellaneousCodes();
    }

    @RequestMapping(value = { "/assertions/user/codes", "/assertions/user/codes/" }, method = RequestMethod.GET)
    public @ResponseBody ErrorCode[] showUserCodes() throws Exception {
        return Store.retrieveUserAssertionCodes();
    }

    /**
     * This version of the method can handle the situation where we use rowKeys as Uuids. Thus
     * URL style rowKeys can be correctly supported.
     * 
     * @param recordUuid
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = { "/occurrences/assertions/add" }, method = RequestMethod.POST)
    public void addAssertionWithParams(@RequestParam(value = "recordUuid", required = true) String recordUuid,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        addAssertion(recordUuid, request, response);
    }

    /**
     * Adds a bulk list of assertions.
     * 
     * This method expects certain request params to be provided
     * apiKey
     * userId
     * userDisplayName
     * assertions - a json list of assertion maps to be applied.
     * 
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/bulk/assertions/add", method = RequestMethod.POST)
    public void addBulkAssertions(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ObjectMapper om = new ObjectMapper();
        try {
            String json = request.getParameter("assertions");
            String userId = request.getParameter("userId");
            String userDisplayName = request.getParameter("userDisplayName");
            String apiKey = request.getParameter("apiKey");
            //check to see that the assertions have come from a valid source before adding
            if (shouldPerformOperation(apiKey, response)) {
                List<java.util.Map<String, String>> assertions = om.readValue(json,
                        new TypeReference<List<java.util.Map<String, String>>>() {
                        });
                logger.debug("The assertions in a list of maps: " + assertions);
                java.util.HashMap<String, QualityAssertion> qas = new java.util.HashMap<String, QualityAssertion>(
                        assertions.size());
                for (java.util.Map<String, String> assertion : assertions) {
                    String code = assertion.get("code");
                    String comment = assertion.get("comment");
                    String recordUuid = assertion.get("recordUuid");
                    QualityAssertion qa = au.org.ala.biocache.model.QualityAssertion.apply(Integer.parseInt(code));
                    qa.setComment(comment);
                    qa.setUserId(userId);
                    qa.setUserDisplayName(userDisplayName);
                    qas.put(recordUuid, qa);
                }
                if (qas.size() > 0) {
                    //add the qas in bulk
                    Store.addUserAssertions(qas);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response.sendError(HttpURLConnection.HTTP_BAD_REQUEST);
        }
    }

    /**
     * add an assertion
     */
    @RequestMapping(value = { "/occurrences/{recordUuid}/assertions/add" }, method = RequestMethod.POST)
    public void addAssertion(@PathVariable(value = "recordUuid") String recordUuid, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        String code = request.getParameter("code");
        String comment = request.getParameter("comment");
        String userId = request.getParameter("userId");
        String userDisplayName = request.getParameter("userDisplayName");
        String apiKey = request.getParameter("apiKey");

        if (shouldPerformOperation(apiKey, response)) {
            try {
                logger.debug("Adding assertion to:" + recordUuid + ", code:" + code + ", comment:" + comment
                        + ", userId:" + userId + ", userDisplayName:" + userDisplayName);

                QualityAssertion qa = au.org.ala.biocache.model.QualityAssertion.apply(Integer.parseInt(code));
                qa.setComment(comment);
                qa.setUserId(userId);
                qa.setUserDisplayName(userDisplayName);

                Store.addUserAssertion(recordUuid, qa);
                //NC 2013-07-25 No need to post a notification to the collectory the biocache service is queried for the annotations required by the notification service
                //                if(qa.getUuid() != null) {
                //                    //send this assertion addition event to the notification service
                //                    postNotificationEvent("create", recordUuid, qa.getUuid());
                //                }

                String server = request.getSession().getServletContext().getInitParameter("serverName");
                response.setHeader("Location",
                        server + "/occurrences/" + recordUuid + "/assertions/" + qa.getUuid());
                response.setStatus(HttpServletResponse.SC_CREATED);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            }
        }
    }

    /**
     * Removes an assertion
     * 
     * This version of the method can handle the situation where we use rowKeys as Uuids. Thus
     * URL style rowKeys can be correctly supported.
     * 
     * @param recordUuid
     * @param assertionUuid
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = { "/occurrences/assertions/delete" }, method = RequestMethod.POST)
    public void deleteAssertionWithParams(@RequestParam(value = "recordUuid", required = true) String recordUuid,
            @RequestParam(value = "assertionUuid", required = true) String assertionUuid,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        deleteAssertion(recordUuid, assertionUuid, request, response);
    }

    /**
     * Remove an assertion
     */
    @RequestMapping(value = { "/occurrences/{recordUuid}/assertions/delete" }, method = RequestMethod.POST)
    public void deleteAssertion(@PathVariable(value = "recordUuid") String recordUuid,
            @RequestParam(value = "assertionUuid", required = true) String assertionUuid,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        String apiKey = request.getParameter("apiKey");

        if (shouldPerformOperation(apiKey, response)) {
            try {
                Store.deleteUserAssertion(recordUuid, assertionUuid);
                //postNotificationEvent("delete", recordUuid, assertionUuid);
                response.setStatus(HttpServletResponse.SC_OK);
            } catch (Exception e) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
            }
        }
    }

    /**
     * Generic method to post a record assertion notification.
     * @param type
     * @param recordUuid
     * @param id
     * @deprecated assertion notifications are obtained through biocache ws NOT the collectory. This method should not be called.
     */
    @Deprecated
    private void postNotificationEvent(String type, String recordUuid, String id) {
        //get the processed record so that we can get the collection_uid
        FullRecord processed = Store.getByUuid(recordUuid, Versions.PROCESSED());
        if (processed == null) {
            processed = Store.getByRowKey(recordUuid, Versions.PROCESSED());
        }

        String uid = processed == null ? null : processed.getAttribution().getCollectionUid();

        if (uid != null) {
            final String uri = registryUrl + "/ws/notify";
            HttpClient h = new HttpClient();
            PostMethod m = new PostMethod(uri);

            try {
                m.setRequestEntity(new StringRequestEntity(
                        "{ event: 'user annotation', id: '" + id + "', uid: '" + uid + "', type:'" + type + "' }",
                        "text/json", "UTF-8"));

                logger.debug("Adding notification: " + type + ":" + uid + " - " + id);
                int status = h.executeMethod(m);
                logger.debug("STATUS: " + status);
                if (status == 200) {
                    logger.debug("Successfully posted an event to the notification service");
                } else {
                    logger.info("Failed to post an event to the notification service");
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);

            }
        }
    }

    @RequestMapping(value = { "/occurrences/assertions", "/occurrences/assertions/" }, method = RequestMethod.GET)
    public @ResponseBody Object getAssertionWithParams(
            @RequestParam(value = "recordUuid", required = true) String recordUuid,
            @RequestParam(value = "assertionUuid", required = false) String assertionUuid,
            HttpServletResponse response) throws Exception {
        if (assertionUuid != null) {
            return getAssertion(recordUuid, assertionUuid, response);
        } else {
            return getAssertions(recordUuid);
        }
    }

    /**
     * Get single assertion
     */
    @RequestMapping(value = { "/occurrences/{recordUuid}/assertions/{assertionUuid}",
            "/occurrences/{recordUuid}/assertions/{assertionUuid}/" }, method = RequestMethod.GET)
    public @ResponseBody QualityAssertion getAssertion(@PathVariable(value = "recordUuid") String recordUuid,
            @PathVariable(value = "assertionUuid") String assertionUuid, HttpServletResponse response)
            throws Exception {
        QualityAssertion qa = assertionUtils.getUserAssertion(recordUuid, assertionUuid);
        if (qa != null) {
            return qa;
        } else {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return null;
        }
    }

    /**
     * Get user assertions
     */
    @RequestMapping(value = { "/occurrences/{recordUuid}/assertions",
            "/occurrences/{recordUuid}/assertions/" }, method = RequestMethod.GET)
    public @ResponseBody List<QualityAssertion> getAssertions(@PathVariable(value = "recordUuid") String recordUuid)
            throws Exception {
        return assertionUtils.getUserAssertions(recordUuid);
    }

    public void setAssertionUtils(AssertionUtils assertionUtils) {
        this.assertionUtils = assertionUtils;
    }
}