vendredi 1 mars 2019

How to Implement Factory Design Pattern for CsvProcessing based on Key

I have written a controller which is a default for MototuploadService(for Motor Upload), but I need to make one Factory Design so that based on parentPkId, need to call HealUploadService, TempUploadService, PersonalUploadService etc which will have separate file processing stages.

controller is below.

@RequestMapping(value = "/csvUpload", method = RequestMethod.POST)
    public List<String> csvUpload(@RequestParam String parentPkId, @RequestParam List<MultipartFile> files)
            throws IOException, InterruptedException, ExecutionException, TimeoutException {
        log.info("Entered method csvUpload() of DaoController.class");
        List<String> response = new ArrayList<String>();
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService<String> compService = new ExecutorCompletionService<String>(executor);
        List< Future<String> > futureList = new ArrayList<Future<String>>();
        for (MultipartFile f : files) {
            compService.submit(new ProcessMutlipartFile(f ,parentPkId,uploadService));
            futureList.add(compService.take());
        }       
        for (Future<String> f : futureList) {
            long timeout = 0;
            System.out.println(f.get(timeout, TimeUnit.SECONDS));
            response.add(f.get());
        }
        executor.shutdown();
        return response;
    }

Here is ProcessMutlipartFile class which extends the callable interface, with CompletionService's compService.submit() invoke this class, which in turn executes call() method, which will process a file.

public class ProcessMutlipartFile implements Callable<String>
{
   private MultipartFile file; 
   private String temp;
   private MotorUploadService motUploadService;
   public ProcessMutlipartFile(MultipartFile file,String temp, MotorUploadService motUploadService )
   {
       this.file=file;
       this.temp=temp;
       this.motUploadService=motUploadService;
   }

   public String call() throws Exception 
   {

    return   motUploadService.csvUpload(temp, file);
    }

}

Below is MotorUploadService class, where I'm processing uploaded CSV file, line by line and then calling validateCsvData() method to validate Data, which returns ErrorObject having line number and Errors associated with it. if csvErrorRecords is null, then error-free and proceed with saving to Db. else save errorList to Db and return Upload Failure.

@Component
public class UploadService {

@Value("${external.resource.folder}")
     String resourceFolder;

    public String csvUpload(String parentPkId, MultipartFile file) {

    String OUT_PATH = resourceFolder;

    try {
            DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss"); 
            String filename = file.getOriginalFilename().split(".")[0] + df.format(new Date()) + file.getOriginalFilename().split(".")[1];
            Path  path = Paths.get(OUT_PATH,fileName)
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
        }
        catch(IOException e){
            e.printStackTrace();
            return "Failed to Upload File...try Again";
        }
        List<TxnMpMotSlaveRaw> txnMpMotSlvRawlist = new ArrayList<TxnMpMotSlaveRaw>();

        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream()));
            String line = "";
            int header = 0;
            int lineNum = 1;
            TxnMpSlaveErrorNew txnMpSlaveErrorNew = new TxnMpSlaveErrorNew();
            List<CSVErrorRecords> errList = new ArrayList<CSVErrorRecords>();
            while ((line = br.readLine()) != null) {
                // TO SKIP HEADER
                if (header == 0) {
                    header++;
                    continue;
                }
                lineNum++;
                header++;
                // Use Comma As Separator
                String[] csvDataSet = line.split(",");

                CSVErrorRecords csvErrorRecords = validateCsvData(lineNum, csvDataSet);
                System.out.println("Errors from csvErrorRecords is " + csvErrorRecords);

                if (csvErrorRecords.equals(null) || csvErrorRecords.getRecordNo() == 0) {
                    //Function to Save to Db

                } else {
                    // add to errList
                    continue;
                }
            }
            if (txnMpSlaveErrorNew.getErrRecord().size() == 0) {
                //save all
                return "Successfully Uploaded " + file.getOriginalFilename();   
            } 
            else {
                // save the error in db;
                return "Failure as it contains Faulty Information" + file.getOriginalFilename();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            return "Failure Uploaded " + file.getOriginalFilename();
        }

    }

    private TxnMpMotSlaveRaw saveCsvData(String[] csvDataSet, String parentPkId) {
        /*
            Mapping csvDataSet to PoJo
            returning Mapped Pojo;
        */
    }

    private CSVErrorRecords validateCsvData(int lineNum, String[] csvDataSet) {
        /*
        Logic for Validation goes here
        */
    }

}

How to make it as a factory design pattern from controller, so that if

 parentPkId='Motor' call MotorUploadService,
    parentPkId='Heal' call HealUploadService 

I'm not so aware of the Factory Design pattern, please help me out. Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire