I have a loader class that executes data loading functions at boot-time for my application to give me test data.
The idea is pretty simple, I'm reading in XML data, using JaxB to turn it into a POJO and then persisting the POJO using JPA repo.
Here is my code (pretty small):
Looking at the parseFile
method, I create a new JaxB instance but it requires the UserContainer class. The problem is, I want to reuse this method for potentially infinitely many containers. What is the best way to refactor this to make it more generic?
I was hoping to avoid the need to pass around a reference to the class type in each subsequent method.
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
LOGGER.log(Level.INFO, "Preparing to load data into database");
try {
loadAndStoreUserData();
} catch (IOException | JAXBException e) {
LOGGER.log(Level.INFO, "Unable to store user data");
e.printStackTrace();
}
}
/**
* Loads up any test data from resources and stores into embedded DB for test env
* @throws IOException
* @throws JAXBException
*/
private void loadAndStoreUserData() throws IOException, JAXBException {
LOGGER.log(Level.INFO, "User data table being added to database");
UserContainer userData = (UserContainer) ingestFromFile("testDatabase/users.xml", UserContainer);
userData.getUsers().stream().forEach(userRepo::save);
}
/**
* Read in file from static resources dir
* @param fileName
* @return
* @throws IOException
* @throws JAXBException
*/
private Object ingestFromFile(String fileName, Object classReference) throws IOException, JAXBException {
Resource resource = new ClassPathResource(fileName);
return parseFile(resource.getFile());
}
/**
* Takes input file from disk and parsed out contents by marshaling XML -> POJO
* @param inputFile
* @return
* @throws JAXBException
*/
private Object parseFile(File inputFile) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(UserContainer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return jaxbUnmarshaller.unmarshal(inputFile);
}
}
Best Answer
Why can't you just pass the a container class reference? Imagine: