package eu.eudat.logic.proxy.fetching; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.fetching.entities.Config; import eu.eudat.logic.proxy.fetching.entities.ConfigSingle; import eu.eudat.logic.services.ApiContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.Unmarshaller; import java.io.InputStream; import java.lang.reflect.Method; import java.util.*; @Component public class LocalFetcher { private final ApiContext apiContext; @Autowired public LocalFetcher(ApiContext apiContext) { this.apiContext = apiContext; } @Cacheable("currencies") public List> retrieveCurrency() throws Exception { InputStream is = getClass().getClassLoader().getResource("internal/fetchConfig.xml").openStream(); JAXBContext context = JAXBContext.newInstance(Config.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Config config = (Config) unmarshaller.unmarshal(is); is.close(); ConfigSingle currencyConfig = config.getConfigs().stream().filter(configSingle -> configSingle.getType().equals("currency")).findFirst().get(); return retrieveData(currencyConfig); } public List> retrieveData(ConfigSingle configSingle) throws Exception { List> result = new ArrayList<>(); InputStream is = getClass().getClassLoader().getResource(configSingle.getFilePath()).openStream(); FileType type = FileType.fromName(configSingle.getFileType()); switch(type) { case XML: { Class aClass = Class.forName(configSingle.getParseClass()); JAXBContext context = JAXBContext.newInstance(aClass); Unmarshaller unmarshaller = context.createUnmarshaller(); Object object = unmarshaller.unmarshal(is); is.close(); Method reader = null; if (configSingle.getParseField() != null && !configSingle.getParseField().isEmpty()) { String camelCaseGetter =configSingle.getParseField() != null && !configSingle.getParseField().isEmpty() ? "get" + configSingle.getParseField().substring(0, 1).toUpperCase() + configSingle.getParseField().substring(1) : ""; reader = aClass.getMethod(camelCaseGetter); } List> values = new ArrayList<>(); int max = 1; if (reader != null) { Object invokedField = reader.invoke(object); if (invokedField instanceof Collection) { max = ((Collection) invokedField).size(); } } for (int i = 0; i< max; i++) { Object value; if (reader != null) { Object invokedField = reader.invoke(object); if (invokedField instanceof Collection) { value = ((Collection) invokedField).toArray()[i]; } else { value = invokedField; } } else { value = object; } Map map = apiContext.getObjectMapper().convertValue(value, Map.class); result.add(new HashMap<>()); result.get(result.size() - 1).put("name", map.get(configSingle.getName())); result.get(result.size() - 1).put("value", map.get(configSingle.getValue())); } } } return result; } public enum FileType { XML("xml"), JSON("json"); private String name; FileType(String name) { this.name = name; } public String getName() { return name; } public static FileType fromName(String name) { for (FileType type: FileType.values()) { if (name.equals(type.getName())) { return type; } } throw new NoSuchElementException("File Type [" + name + "] is not supported"); } } }