Develop a Java Spring Boot application that provides an endpoint for uploading and processing large text files. The application should count the occurrences of each word in the file and store the results in a MongoDB database.
PLAINFORMAT
package com.example.demo.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "word_occurrences")
public class WordOccurrence {

    @Id
    private String id;
    private String word;
    private int count;

    public WordOccurrence(String word, int count) {
        this.word = word;
        this.count = count;
    }

    // Getters and setters
}

package com.example.demo.repository;

import com.example.demo.model.WordOccurrence;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface WordOccurrenceRepository extends MongoRepository<WordOccurrence, String> {
}

package com.example.demo.service;

import com.example.demo.model.WordOccurrence;
import com.example.demo.repository.WordOccurrenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@Service
public class TextProcessingService {

    @Autowired
    private WordOccurrenceRepository wordOccurrenceRepository;

    public void processTextFile(MultipartFile file) throws IOException {
        Map<String, Integer> wordCountMap = new HashMap<>();

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] words = line.split("\\s+");
                for (String word : words) {
                    word = word.toLowerCase().replaceAll("[^a-z0-9]", "");
                    if (!word.isEmpty()) {
                        wordCountMap.put(word, wordCountMap.getOrDefault(word, 0) + 1);
                    }
                }
            }
        }

        for (Map.Entry<String, Integer> entry : wordCountMap.entrySet()) {
            WordOccurrence wordOccurrence = new WordOccurrence(entry.getKey(), entry.getValue());
            wordOccurrenceRepository.save(wordOccurrence);
        }
    }
}

package com.example.demo.controller;

import com.example.demo.service.TextProcessingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileUploadController {

    @Autowired
    private TextProcessingService textProcessingService;

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return new ResponseEntity<>("Please select a file to upload", HttpStatus.BAD_REQUEST);
        }

        try {
            textProcessingService.processTextFile(file);
            return new ResponseEntity<>("File uploaded and processed successfully", HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>("Error processing the file: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}