net.triptech.metahive.web.RecordController.java Source code

Java tutorial

Introduction

Here is the source code for net.triptech.metahive.web.RecordController.java

Source

/*******************************************************************************
 * Copyright (c) 2012 David Harrison, Triptech Ltd.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 *
 * Contributors:
 *     David Harrison, Triptech Ltd - initial API and implementation
 ******************************************************************************/
package net.triptech.metahive.web;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import net.triptech.metahive.FlashScope;
import net.triptech.metahive.messaging.JmsRecalculateRequest;
import net.triptech.metahive.model.DataGrid;
import net.triptech.metahive.model.Definition;
import net.triptech.metahive.model.KeyValue;
import net.triptech.metahive.model.KeyValueBoolean;
import net.triptech.metahive.model.KeyValueCollection;
import net.triptech.metahive.model.MetahivePreferences;
import net.triptech.metahive.model.Person;
import net.triptech.metahive.model.Record;
import net.triptech.metahive.model.SubmittedField;
import net.triptech.metahive.model.UserRole;
import net.triptech.metahive.web.model.CommentForm;
import net.triptech.metahive.web.model.FilterAction;
import net.triptech.metahive.web.model.FilterVector;
import net.triptech.metahive.web.model.KeyValueForm;
import net.triptech.metahive.web.model.KeyValueJson;
import net.triptech.metahive.web.model.RecordFilter;
import net.triptech.metahive.web.model.RecordForm;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import flexjson.JSONSerializer;

@RequestMapping("/records")
@Controller
public class RecordController extends BaseController {

    @Autowired
    private transient JmsTemplate keyValueGenerationTemplate;

    /** The default page size. */
    private final static int DEFAULT_PAGE_SIZE = 50;

    @RequestMapping(method = RequestMethod.POST)
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public String create(@Valid RecordForm record, BindingResult bindingResult, Model uiModel,
            HttpServletRequest request) {

        Person user = loadUser(request);

        if (user == null) {
            // A valid user is required
            FlashScope.appendMessage(getMessage("metahive_valid_user_required"), request);
            return "redirect:/records";
        }

        if (StringUtils.isNotBlank(record.getRecordId())) {
            Record newRecord = record.newRecord(loadPreferences());
            newRecord.persist();
            newRecord.flush();
        }

        if (StringUtils.isNotBlank(record.getRecordIds())) {

            Collection<Record> records = record.parseRecords(loadPreferences());

            for (Record newRecord : records) {
                newRecord.persist();
                newRecord.flush();
            }
        }

        uiModel.asMap().clear();

        FlashScope.appendMessage(getMessage("metahive_create_complete", Record.class), request);

        return "redirect:/records";
    }

    @RequestMapping(params = "form", method = RequestMethod.GET)
    public String createForm(Model uiModel) {
        uiModel.addAttribute("record", new RecordForm());
        return "records/create";
    }

    @RequestMapping(params = "bulk", method = RequestMethod.GET)
    public String bulkForm(Model uiModel) {
        uiModel.addAttribute("record", new RecordForm());
        return "records/bulk";
    }

    @RequestMapping(value = "/advanced", method = RequestMethod.GET)
    public String advancedSearch(@RequestParam(value = "id", required = false) String id, Model uiModel,
            HttpServletRequest request) {

        if (StringUtils.isNotBlank(id)) {
            // Modify search action
            Map<String, RecordFilter> searches = getSearches(request);
            if (searches.containsKey(id)) {
                uiModel.addAttribute("filter", searches.get(id));
            }

            Collection<FilterAction> filterActions = new ArrayList<FilterAction>();
            for (FilterAction filterAction : FilterAction.values()) {
                filterActions.add(filterAction);
            }
            uiModel.addAttribute("filteractions", filterActions);
        }

        uiModel.addAttribute("booleanOptions", populateBooleanValues());

        return "records/advanced";
    }

    @RequestMapping(value = "/advanced", method = RequestMethod.POST)
    public String advancedSearchProcess(@RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "action", required = false) FilterAction action, Model uiModel,
            HttpServletRequest request) {

        RecordFilter filter = new RecordFilter();
        filter.setEncoding(request.getCharacterEncoding());
        filter.processSearchForm(request);

        Map<String, RecordFilter> searches = getSearches(request);

        if (StringUtils.isNotBlank(id) && searches.containsKey(id)) {
            // This is a modify search operation - get the processed filter vector
            FilterVector vector = null;

            if (filter.getFilterVectors() != null && filter.getFilterVectors().size() > 0) {
                vector = filter.getFilterVectors().get(0);

                if (action != null) {
                    vector.setAction(action);
                }
            }
            // Add the vector to the existing search if it is not null
            filter = searches.get(id);
            if (vector != null) {
                filter.getFilterVectors().add(vector);
            }
        }

        // Add the filter to the search array
        searches.put(filter.getId(), filter);

        request.getSession().setAttribute("searches", searches);

        return "redirect:/records?id=" + filter.getId();
    }

    /**
     * Show the record.
     *
     * @param id the id
     * @param uiModel the ui model
     * @return the string
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String show(@PathVariable("id") Long id, Model uiModel,
            @RequestParam(value = "show", required = false) Boolean show,
            @RequestParam(value = "expand", required = false) Boolean expand, HttpServletRequest request) {

        Person user = loadUser(request);
        UserRole role = UserRole.ANONYMOUS;

        boolean showAllDefinitions = false;
        boolean expandAllDefinitions = false;

        if (user != null) {
            role = user.getUserRole();
            showAllDefinitions = user.isShowAllDefinitions();
            expandAllDefinitions = user.isExpandAllDefinitions();
        }

        if (show != null) {
            showAllDefinitions = show;
        }
        if (expand != null) {
            expandAllDefinitions = expand;
        }

        if (user != null) {
            if (show != null) {
                user.setShowAllDefinitions(show);
            }
            if (expand != null) {
                user.setExpandAllDefinitions(expand);
            }
            if (show != null || expand != null) {
                user.merge();
            }
        }

        Record record = Record.findRecord(id);
        record.setShowAllDefinitions(showAllDefinitions);
        record.loadAllAggregatedKeyValues(role, this.getContext());

        CommentForm commentForm = new CommentForm();
        commentForm.setRecord(record);

        uiModel.addAttribute("record", record);
        uiModel.addAttribute("comment", commentForm);
        uiModel.addAttribute("show", showAllDefinitions);
        uiModel.addAttribute("expand", expandAllDefinitions);

        return "records/show";
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @PreAuthorize("hasAnyRole('ROLE_EDITOR','ROLE_ADMIN')")
    public String delete(@PathVariable("id") Long id, Model uiModel, HttpServletRequest request) {

        Person user = loadUser(request);

        if (user == null) {
            // A valid user is required
            FlashScope.appendMessage(getMessage("metahive_valid_user_required"), request);
            return "redirect:/records";
        }

        Record.findRecord(id).remove();
        uiModel.asMap().clear();

        FlashScope.appendMessage(getMessage("metahive_delete_complete", Record.class), request);

        return "redirect:/records";
    }

    /**
     * Show information on the key value.
     *
     * @param id the id
     * @param keyValueId the key value id
     * @param uiModel the ui model
     * @param request the request
     * @return the string
     */
    @RequestMapping(value = "/keyvalue/{id}", method = RequestMethod.GET)
    public String keyvalueDetail(@PathVariable("id") Long id, Model uiModel, HttpServletRequest request) {

        KeyValue kv = KeyValue.findKeyValue(id);
        kv.setSubmittedFields(SubmittedField.findSubmittedFields(kv.getDefinition(), kv.getPrimaryRecordId(),
                kv.getSecondaryRecordId(), kv.getTertiaryRecordId()));

        kv.setContext(this.getContext());

        uiModel.addAttribute("keyValue", kv);

        return "records/keyvaluedetail";
    }

    /**
     * The key value as a json string.
     *
     * @param id the id
     * @param request the request
     * @return the string
     */
    @RequestMapping(value = "/keyvalue/{id}", params = "json", method = RequestMethod.GET)
    public @ResponseBody String keyvalueJson(@PathVariable("id") Long id, HttpServletRequest request) {

        UserRole userRole = UserRole.ANONYMOUS;

        Person user = loadUser(request);
        if (user != null && user.getUserRole() != null) {
            userRole = user.getUserRole();
        }

        KeyValue kv = KeyValue.findKeyValue(id);
        KeyValueJson kvj = new KeyValueJson(kv, kv.getDefinition(), userRole);

        return new JSONSerializer().exclude("*.class").serialize(kvj);
    }

    @RequestMapping(value = "/keyvalue/{id}", method = RequestMethod.POST)
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public @ResponseBody String overrideKeyValue(@PathVariable("id") Long id, KeyValueForm kvForm, Model uiModel,
            HttpServletRequest request) {

        Person user = loadUser(request);

        if (user == null) {
            // A valid user is required
            return getMessage("metahive_valid_user_required");
        }

        List<KeyValue> updatedValues = KeyValue.updateRelevantKeyValues(id, kvForm, user);

        // Submit a recalculation JMS request for each updated key value
        for (KeyValue kv : updatedValues) {
            JmsRecalculateRequest req = new JmsRecalculateRequest(kv);
            keyValueGenerationTemplate.convertAndSend(req);
        }

        uiModel.asMap().clear();

        return getMessage("metahive_record_keyvaluedetail_success");
    }

    /**
     * List the records.
     *
     * @param id the id
     * @param vid the vid
     * @param orderId the order id
     * @param recordId the record id
     * @param page the page
     * @param size the size
     * @param uiModel the ui model
     * @param request the http servlet request
     * @return the string
     */
    @RequestMapping(method = RequestMethod.GET)
    public String list(@RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "vid", required = false) Integer vid,
            @RequestParam(value = "order", required = false) Long orderId,
            @RequestParam(value = "recordId", required = false) String recordId,
            @RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "size", required = false) Integer size, Model uiModel,
            HttpServletRequest request) {

        Person user = loadUser(request);

        List<Definition> definitions = new ArrayList<Definition>();
        if (user == null) {
            // Load the default definition list
            MetahivePreferences preferences = MetahivePreferences.load();
            definitions = preferences.getDefaultDefinitions();
        } else {
            if (user.getSearchDefinitions().size() == 0) {
                // Set the default definitions for the user
                MetahivePreferences preferences = MetahivePreferences.load();

                for (Definition def : preferences.getDefaultDefinitions()) {
                    definitions.add(def);
                }
                user.setSearchDefinitions(definitions);
                user.persist();
            } else {
                definitions = user.getSearchDefinitions();
            }
        }

        UserRole userRole = UserRole.ANONYMOUS;
        if (user != null && user.getUserRole() != null) {
            userRole = user.getUserRole();
        }

        RecordFilter filter = new RecordFilter();
        filter.setEncoding(request.getCharacterEncoding());

        Map<String, RecordFilter> searches = getSearches(request);

        if (StringUtils.isNotBlank(id) && searches.containsKey(id)) {
            filter = searches.get(id);
        }

        if (orderId != null) {
            filter.setOrderId(orderId);
        }

        if (filter.getFilterVectors() == null || filter.getFilterVectors().size() == 0) {
            List<FilterVector> defaultVector = new ArrayList<FilterVector>();
            defaultVector.add(new FilterVector());
            filter.setFilterVectors(defaultVector);
        }

        if (vid != null && vid > 1 && filter.getFilterVectors().size() >= vid) {
            List<FilterVector> vectors = filter.getFilterVectors();
            vectors.remove(vid - 1);
            filter.setFilterVectors(vectors);
        }

        String defaultRecordFilter = getMessage("metahive_records_filter_id");

        if (StringUtils.isNotBlank(recordId) && !StringUtils.equalsIgnoreCase(recordId, defaultRecordFilter)) {
            filter.setRecordId(recordId);
        } else {
            filter.setRecordId("");
        }

        searches.put(filter.getId(), filter);

        request.getSession().setAttribute("searches", searches);

        int sizeNo = size == null ? DEFAULT_PAGE_SIZE : size.intValue();
        int pageNo = page == null ? 0 : page.intValue() - 1;

        uiModel.addAttribute("definitions", definitions);

        uiModel.addAttribute("records", Record.findRecordEntries(filter, definitions, userRole, this.getContext(),
                pageNo * sizeNo, sizeNo));

        float nrOfPages = (float) Record.countRecords(filter) / sizeNo;

        uiModel.addAttribute("resultCounts", resultCounts());
        uiModel.addAttribute("page", pageNo + 1);
        uiModel.addAttribute("size", sizeNo);
        uiModel.addAttribute("filter", filter);
        uiModel.addAttribute("maxPages",
                (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));

        return "records/list";
    }

    @RequestMapping(value = "/search.xls", method = RequestMethod.POST)
    public ModelAndView recordsExport(@RequestParam(value = "searchId", required = false) String id,
            @RequestParam(value = "searchDefinitions", required = true) String[] defIds, HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        Person user = loadUser(request);

        UserRole userRole = UserRole.ANONYMOUS;
        if (user != null && user.getUserRole() != null) {
            userRole = user.getUserRole();
        }

        List<Definition> definitions = Definition.findDefinitionEntries(defIds);

        RecordFilter filter = new RecordFilter();

        if (StringUtils.isNotBlank(id)) {
            Map<String, RecordFilter> searches = getSearches(request);

            if (searches.containsKey(id)) {
                filter = searches.get(id);
            }
        }

        List<Record> records = Record.findRecordEntries(filter, definitions, userRole, this.getContext(), 1, 0);

        DataGrid dataGrid = buildDataGrid(records, definitions);

        return new ModelAndView("ExcelTemplateView", "dataGrid", dataGrid);
    }

    @RequestMapping(value = "/{id}/record.xls", method = RequestMethod.POST)
    public ModelAndView recordExport(
            @RequestParam(value = "searchDefinitions", required = true) String[] definitionIds,
            @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        Person user = loadUser(request);

        UserRole userRole = UserRole.ANONYMOUS;
        if (user != null && user.getUserRole() != null) {
            userRole = user.getUserRole();
        }

        List<Definition> definitions = Definition.findDefinitionEntries(definitionIds);

        Record record = Record.findRecord(id);
        record.loadKeyValues(definitions, userRole, this.getContext());

        List<Record> records = new ArrayList<Record>();
        records.add(record);

        DataGrid dataGrid = buildDataGrid(records, definitions);

        return new ModelAndView("ExcelTemplateView", "dataGrid", dataGrid);
    }

    @ModelAttribute("user")
    public Person populateUser(HttpServletRequest request) {

        Person user = loadUser(request);

        if (user == null) {
            user = new Person();

            MetahivePreferences preferences = MetahivePreferences.load();
            user.setSearchDefinitions(preferences.getDefaultDefinitions());
        }
        return user;
    }

    @ModelAttribute("exportDefinitions")
    public Map<String, List<Definition>> populateExportDefinitions() {
        return Definition.groupDefinitions(Definition.findTopLevelDefinitions());
    }

    private Collection<KeyValueBoolean> populateBooleanValues() {
        Collection<KeyValueBoolean> booleanValues = new ArrayList<KeyValueBoolean>();
        for (KeyValueBoolean kvBoolean : KeyValueBoolean.values()) {
            booleanValues.add(kvBoolean);
        }
        return booleanValues;
    }

    /**
     * Builds the data grid.
     *
     * @param records the records
     * @param definitions the definitions
     * @return the data grid
     */
    private DataGrid buildDataGrid(final List<Record> records, final List<Definition> definitions) {

        DataGrid dataGrid = new DataGrid();

        if (records.size() == 1) {
            dataGrid.setTitle("Record " + records.get(0).getRecordId());
        } else {
            dataGrid.setTitle("Record search results");
        }

        MetahivePreferences preferences = loadPreferences();

        dataGrid.addHeaderField(preferences.getPrimaryRecordName());

        if (StringUtils.isNotBlank(preferences.getSecondaryRecordName())) {
            dataGrid.addHeaderField(preferences.getSecondaryRecordName());
        }
        if (StringUtils.isNotBlank(preferences.getTertiaryRecordName())) {
            dataGrid.addHeaderField(preferences.getTertiaryRecordName());
        }

        for (Definition definition : definitions) {
            String field = definition.getName();
            if (StringUtils.isNotBlank(definition.getDescription().getUnitOfMeasure())) {
                field += " (" + definition.getDescription().getUnitOfMeasure() + ")";
            }
            dataGrid.addHeaderField(field);
        }

        for (Record record : records) {

            if (record.getKeyValueCollection() != null && record.getKeyValueCollection().size() > 0) {

                for (KeyValueCollection kvCollection : record.getKeyValueCollection()) {

                    List<String> rowData = new ArrayList<String>();

                    rowData.add(kvCollection.getRecordId());

                    if (StringUtils.isNotBlank(preferences.getSecondaryRecordName())) {
                        rowData.add(kvCollection.getSecondaryRecordId());
                    }
                    if (StringUtils.isNotBlank(preferences.getTertiaryRecordName())) {
                        rowData.add(kvCollection.getTertiaryRecordId());
                    }

                    for (String name : kvCollection.getKeyValueMap().keySet()) {
                        KeyValue kv = kvCollection.getKeyValueMap().get(name);

                        rowData.add(kv.getValueSansUnits());
                    }
                    dataGrid.addRow(rowData);
                }
            } else {
                // No data found, enter a blank (no data) row
                List<String> rowData = new ArrayList<String>();

                rowData.add(record.getRecordId());

                if (StringUtils.isNotBlank(preferences.getSecondaryRecordName())) {
                    rowData.add("");
                }
                if (StringUtils.isNotBlank(preferences.getTertiaryRecordName())) {
                    rowData.add("");
                }

                String noData = getMessage("label_net_triptech_metahive_model_keyvalue_no_data");

                for (int x = 0; x < definitions.size(); x++) {
                    rowData.add(noData);
                }
                dataGrid.addRow(rowData);
            }
        }
        return dataGrid;
    }

    /**
     * Gets the search array from the session (if one exists).
     *
     * @param request the request
     * @return the search array
     */
    private Map<String, RecordFilter> getSearches(final HttpServletRequest request) {

        Map<String, RecordFilter> searches = new HashMap<String, RecordFilter>();

        if (request.getSession().getAttribute("searches") != null) {
            Object objMap = request.getSession().getAttribute("searches");
            if (objMap instanceof Map) {
                Map<?, ?> map = (Map<?, ?>) objMap;
                for (Object objId : map.keySet()) {
                    Object objRecordFilter = map.get(objId);
                    if (objRecordFilter instanceof RecordFilter) {
                        RecordFilter recordFilter = (RecordFilter) objRecordFilter;

                        // Test if it has expired (older than one hour)
                        long oldTime = recordFilter.getCreated().getTime();
                        long newTime = Calendar.getInstance().getTimeInMillis();

                        if ((newTime - oldTime) <= (3600 * 1000)) {
                            searches.put(recordFilter.getId(), recordFilter);
                        }
                    }
                }
            }
        }
        return searches;
    }
}