org.zlogic.vogon.web.controller.DataController.java Source code

Java tutorial

Introduction

Here is the source code for org.zlogic.vogon.web.controller.DataController.java

Source

/*
 * Vogon personal finance/expense analyzer.
 * Licensed under Apache license: http://www.apache.org/licenses/LICENSE-2.0
 * Author: Dmitry Zolotukhin <zlogic@gmail.com>
 */
package org.zlogic.vogon.web.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
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.multipart.MultipartFile;
import org.zlogic.vogon.data.FinanceAccount;
import org.zlogic.vogon.data.VogonUser;
import org.zlogic.vogon.data.interop.ClassExporter;
import org.zlogic.vogon.data.interop.ExportedData;
import org.zlogic.vogon.data.interop.VogonExportException;
import org.zlogic.vogon.data.interop.VogonImportException;
import org.zlogic.vogon.data.interop.VogonImportLogicalException;
import org.zlogic.vogon.data.interop.XmlExporter;
import org.zlogic.vogon.data.interop.XmlImporter;
import org.zlogic.vogon.data.tools.DatabaseMaintenance;
import org.zlogic.vogon.web.controller.serialization.JSONMapper;
import org.zlogic.vogon.web.data.AccountRepository;
import org.zlogic.vogon.web.data.InitializationHelper;
import org.zlogic.vogon.web.data.TransactionRepository;
import org.zlogic.vogon.web.data.UserRepository;
import org.zlogic.vogon.web.data.model.FinanceTransactionJson;
import org.zlogic.vogon.web.security.VogonSecurityUser;

/**
 * Spring MVC controller for importing/exporting data
 *
 * @author Dmitry Zolotukhin [zlogic@gmail.com]
 */
@Controller
@Transactional
@RequestMapping(value = "/service")
public class DataController {

    /**
     * The EntityManager instance
     */
    @PersistenceContext
    private EntityManager em;
    /**
     * The users repository
     */
    @Autowired
    private UserRepository userRepository;
    /**
     * The transactions repository
     */
    @Autowired
    private TransactionRepository transactionRepository;
    /**
     * The accounts repository
     */
    @Autowired
    private AccountRepository accountRepository;
    /**
     * InitializationHelper instance
     */
    @Autowired
    private InitializationHelper initializationHelper;
    /**
     * JSONMapper instance
     */
    @Autowired
    private JSONMapper jsonMapper;

    /**
     * Imports uploaded XML data
     *
     * @param data the file to import
     * @param userPrincipal the authenticated user
     * @return true of import succeeded
     */
    @RequestMapping(value = "/import", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
    public @ResponseBody Boolean importData(@RequestParam("file") MultipartFile data,
            @AuthenticationPrincipal VogonSecurityUser userPrincipal) throws RuntimeException {
        VogonUser user = userRepository.findByUsernameIgnoreCase(userPrincipal.getUsername());
        try {
            XmlImporter importer = new XmlImporter(data.getInputStream());
            importer.importData(user, em);
        } catch (IOException | VogonImportException | VogonImportLogicalException ex) {
            throw new RuntimeException(ex);
        }
        return true;
    }

    /**
     * Returns all data
     *
     * @param userPrincipal the authenticated user
     * @return the HTTPEntity for the file download
     */
    @RequestMapping(value = "/export/xml", method = { RequestMethod.GET, RequestMethod.POST })
    public HttpEntity<byte[]> exportDataXML(@AuthenticationPrincipal VogonSecurityUser userPrincipal)
            throws RuntimeException {
        VogonUser user = userRepository.findByUsernameIgnoreCase(userPrincipal.getUsername());
        try {
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            XmlExporter exporter = new XmlExporter(outStream);
            Sort accountSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));//NOI18N
            Sort transactionSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));//NOI18N
            exporter.exportData(user, accountRepository.findByOwner(user, accountSort),
                    transactionRepository.findByOwner(user, transactionSort), null);

            String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); //NOI18N

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_XML);
            headers.setContentLength(outStream.size());
            headers.setContentDispositionFormData("attachment", "vogon-" + date + ".xml"); //NOI18N //NOI18N

            return new HttpEntity<>(outStream.toByteArray(), headers);
        } catch (VogonExportException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * Returns all data
     *
     * @param userPrincipal the authenticated user
     * @return the HTTPEntity for the file download
     */
    @RequestMapping(value = "/export/json", method = { RequestMethod.GET, RequestMethod.POST })
    public HttpEntity<byte[]> exportDataJSON(@AuthenticationPrincipal VogonSecurityUser userPrincipal)
            throws RuntimeException {
        VogonUser user = userRepository.findByUsernameIgnoreCase(userPrincipal.getUsername());
        try {
            ClassExporter exporter = new ClassExporter();
            Sort accountSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));//NOI18N
            Sort transactionSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));//NOI18N

            exporter.exportData(user, accountRepository.findByOwner(user, accountSort),
                    transactionRepository.findByOwner(user, transactionSort), null);
            ExportedData exportedData = exporter.getExportedData();

            //Process transactions for JSON
            List<FinanceTransactionJson> processedTransactions = initializationHelper
                    .initializeTransactions(exportedData.getTransactions());
            exportedData.getTransactions().clear();
            for (FinanceTransactionJson transaction : processedTransactions)
                exportedData.getTransactions().add(transaction);

            //Convert to JSON
            byte[] output = jsonMapper.writer().withDefaultPrettyPrinter().writeValueAsString(exportedData)
                    .getBytes("utf-8"); //NOI18N

            String date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); //NOI18N

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            headers.setContentLength(output.length);
            headers.setContentDispositionFormData("attachment", "vogon-" + date + ".json"); //NOI18N //NOI18N

            return new HttpEntity<>(output, headers);
        } catch (VogonExportException | IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * Recalculates balance for all user's accounts
     *
     * @param userPrincipal the authenticated user
     * @return true on success
     */
    @RequestMapping(value = "/recalculateBalance", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody Boolean recalculateBalance(@AuthenticationPrincipal VogonSecurityUser userPrincipal) {
        VogonUser user = userRepository.findByUsernameIgnoreCase(userPrincipal.getUsername());
        DatabaseMaintenance databaseMaintenance = new DatabaseMaintenance();
        for (FinanceAccount account : accountRepository.findByOwner(user))
            databaseMaintenance.refreshAccountBalance(account, em);
        return true;
    }

    /**
     * Performs a DB cleanup operation
     *
     * @return true on success
     */
    @RequestMapping(value = "/cleanup", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody Boolean cleanup() {
        DatabaseMaintenance databaseMaintenance = new DatabaseMaintenance();
        databaseMaintenance.cleanup(em);//TODO: allows this action only for administrative users?
        return true;
    }
}