<repo_name>maheswaranvenkat/rabocustomerstatementprocessing<file_sep>/src/main/java/com/rabo/utils/CommonUtils.java
package com.rabo.utils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

public abstract class CommonUtils {

    public static final String CSV_SEPARATOR = ",";

    public static  <T> Pair<Set<T>,List<T>> resultSet(List<T> all) {
        Set<T> set = new HashSet<>();
        List<T> duplicateElements=new ArrayList<>();
        // Set#add returns false if the set does not change, which
        // indicates that a duplicate element has been added.
        for (T each: all) if (!set.add(each)) duplicateElements.add(each);
        return new ImmutablePair<>(set,duplicateElements);
    }

}
<file_sep>/src/main/java/com/rabo/controller/CustomerStatementUploadController.java
package com.rabo.controller;

import com.rabo.business.CSVCustomerStatementProcess;
import com.rabo.business.XMLCustomerStatementProcess;
import com.rabo.exception.CSVProcessingException;
import com.rabo.exception.CustomerStatementProcessException;
import com.rabo.exception.XMLProcessingException;
import com.rabo.model.FileExtensionFilter;
import com.rabo.model.Record;
import com.rabo.service.CustomerStatementErrorReportService;
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Upload Controller is responsible for routing the request to respective Process class and get the output.
 *
 * @author <NAME>
 * @date 18 June 2018
 */

@RestController
public class CustomerStatementUploadController {

    @Autowired
    CSVCustomerStatementProcess csvCustomerStatementProcess;

    @Autowired
    XMLCustomerStatementProcess xmlCustomerStatementProcess;

    @Autowired
    CustomerStatementErrorReportService customerStatementErrorReportService;

    @Value("${csvFileName.path}")
    private String csvfileNamePath;

    @Value("${xmlFileName.path}")
    private String xmlfileNamePath;

    @Value("${errorFileName.path}")
    private String errorDataProcessingFilePath;

    @RequestMapping("/")
    public String invoke() throws CustomerStatementProcessException, CSVProcessingException, XMLProcessingException {
        FileExtensionFilter extensionType = FileExtensionFilter.fromString(FilenameUtils.getExtension(csvfileNamePath));
        switch (extensionType) {
            case CSV: {
                //Thought to have CustomerStatementProvider from where we can get the proper fileName.
                Pair<Set<Record>, List<Record>> csvProcessed = csvCustomerStatementProcess.execute(csvfileNamePath);
                customerStatementErrorReportService.writeToCSV(csvProcessed.getRight(), errorDataProcessingFilePath);
                return "CSV Processed Successfully!!! Please check the Report.csv file is there any errors."
                        + " You Can find the file in following location Upload location";
            }
            case XML: {
                Pair<Set<Record>, List<Record>> xmlProcessed = xmlCustomerStatementProcess.execute(xmlfileNamePath);
                customerStatementErrorReportService.writeToCSV(xmlProcessed.getRight(), errorDataProcessingFilePath);
                return "XML Processed Successfully!!! Please check the Report.csv file is there any errors. "
                        + "You Can find the file in following location Upload location";
            }
            default: {
                throw new CustomerStatementProcessException("Customer Doesn't select any related file");
            }
        }
    }
}
<file_sep>/src/main/java/com/rabo/exception/XMLProcessingException.java
package com.rabo.exception;

/**
 * Exception class.
 *
 * @author <NAME>
 * @date 18 June 2018
 */
public class XMLProcessingException extends Exception {
    private static final long serialVersionUID = 1L;
    public XMLProcessingException(String message) {
        super(message);
    }
}
<file_sep>/src/main/java/com/rabo/model/FileExtensionFilter.java
package com.rabo.model;

import java.util.EnumSet;
import org.apache.commons.lang.StringUtils;

public enum FileExtensionFilter {
    CSV("csv"),
    XML("xml");

    private String code;

    FileExtensionFilter(String code) {
        this.code = new String(code);
    }

    public String getCode() {
        return code;
    }

    @Override
    public String toString() {
        return code;
    }

    public static FileExtensionFilter fromString(String status) {
        return EnumSet.allOf(FileExtensionFilter.class)
                .stream()
                .filter(value -> StringUtils.equals(value.getCode(), status))
                .findFirst()
                .orElse(null);
    }
}
<file_sep>/src/test/java/com/rabo/AppTest.java
package com.rabo;

import com.rabo.business.CSVCustomerStatementProcess;
import com.rabo.exception.CSVProcessingException;
import com.rabo.exception.CustomerStatementProcessException;
import com.rabo.exception.XMLProcessingException;
import com.rabo.model.FileExtensionFilter;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

import com.rabo.controller.CustomerStatementUploadController;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.springframework.test.context.TestPropertySource;

import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import static org.powermock.api.support.membermodification.MemberMatcher.method;


@RunWith(MockitoJUnitRunner.class)
@TestPropertySource(properties = {
        "xmlFileName.path=./upload/records.xml",
})
@PrepareForTest({FileExtensionFilter.class})
public class AppTest {

    private CustomerStatementUploadController customerStatementUploadController;

    @Mock
    private CSVCustomerStatementProcess csvCustomerStatementProcess;

    /*@Before
    public void setUp() {
        fileExtensionFilter = mock(FileExtensionFilter.class);
    }*/

    @Test
    public void testApp() throws CustomerStatementProcessException, CSVProcessingException, XMLProcessingException, Exception {

        //Mockito.when(FileExtensionFilter.fromString("./upload/records.xml")).thenReturn(FileExtensionFilter.XML);
        //whenNew(FileExtensionFilter.class).withNoArguments().thenReturn(fileExtensionFilter);
        //stub(method(FileExtensionFilter.class, "fromString()").toReturn(FileExtensionFilter.XML);
        //stub(method(FileExtensionFilter.class, "fromString")).toReturn(FileExtensionFilter.XML);


        customerStatementUploadController = Mockito.mock(CustomerStatementUploadController.class, Mockito.CALLS_REAL_METHODS);

        String result = customerStatementUploadController.invoke();
        assertEquals(result, "CSV Processed Successfully!!! Please check the Report.csv file is there any errors. "
                + "You Can find the file in following location Upload location");
    }
}
<file_sep>/src/main/java/com/rabo/business/XMLCustomerStatementProcess.java
package com.rabo.business;

import com.rabo.exception.XMLProcessingException;
import com.rabo.model.Record;
import com.rabo.model.Records;
import com.rabo.utils.CommonUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Component;

/**
 * XMLCustomer Statement Process is responsible for processing the data from XML file.
 *
 * @author <NAME>
 * @date 18 June 2018
 */

@Component
public class XMLCustomerStatementProcess {

    public Pair<Set<Record>, List<Record>> execute(String xmlFile) throws XMLProcessingException {
        Records customerStatementRecords = new Records();
        try(final InputStream is = new FileInputStream(new File(xmlFile))) {
            JAXBContext jaxbContext = JAXBContext.newInstance(Records.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            customerStatementRecords = (Records) jaxbUnmarshaller.unmarshal(is);
        } catch (JAXBException | IOException e) {
            throw new XMLProcessingException("CSV Processing Exception" + e.getMessage());
        }
        return CommonUtils.resultSet(customerStatementRecords.getRecords());
    }
}
