package eu.eudat.logic.proxy.config.configloaders; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.Unmarshaller; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.*; import java.util.*; import java.util.stream.Collectors; @Service("configLoader") //@Profile("devel") public class DefaultConfigLoader implements ConfigLoader { private static final Logger logger = LoggerFactory.getLogger(DefaultConfigLoader.class); private ExternalUrls externalUrls; private List rdaProperties; private XWPFDocument document; private ConfigurableProviders configurableProviders; private Map keyToSourceMap; @Autowired private Environment environment; private void setExternalUrls() { String fileUrl = this.environment.getProperty("configuration.externalUrls"); logger.info("Loaded also config file: " + fileUrl); InputStream is = null; try { JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); is = getStreamFromPath(fileUrl); externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is); } catch (Exception ex) { logger.error("Cannot find resource", ex); } finally { try { if (is != null) is.close(); } catch (IOException | NullPointerException e) { logger.warn("Warning: Could not close a stream after reading from file: " + fileUrl, e); } } } private void setRdaProperties() { String filePath = environment.getProperty("configuration.rda"); logger.info("Loaded also config file: " + filePath); BufferedReader reader; List rdaList = new LinkedList<>(); try { reader = new BufferedReader(new InputStreamReader(getStreamFromPath(filePath))); String line = reader.readLine(); while (line != null) { rdaList.add(line); line = reader.readLine(); } reader.close(); } catch (IOException | NullPointerException e) { logger.error(e.getMessage(), e); } rdaProperties = rdaList; } private void setDocument() { String filePath = environment.getProperty("configuration.h2020template"); logger.info("Loaded also config file: " + filePath); InputStream is = null; try { is = getStreamFromPath(filePath); this.document = new XWPFDocument(is); } catch (IOException | NullPointerException e) { logger.error(e.getMessage(), e); } finally { try { if (is != null) is.close(); } catch (IOException e) { logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); } } } private void setConfigurableProviders() { String filePath = environment.getProperty("configuration.configurable_login_providers"); logger.info("Loaded also config file: " + filePath); InputStream is = null; try { is = getStreamFromPath(filePath); ObjectMapper mapper = new ObjectMapper(); this.configurableProviders = mapper.readValue(is, ConfigurableProviders.class); } catch (IOException | NullPointerException e) { logger.error(e.getMessage(), e); } finally { try { if (is != null) is.close(); } catch (IOException e) { logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); } } } private void setKeyToSourceMap() { String filePath = this.environment.getProperty("configuration.externalUrls"); logger.info("Loaded also config file: " + filePath); Document doc = getXmlDocumentFromFilePath(filePath); if (doc == null) { this.keyToSourceMap = null; return; } String xpathExpression = "//key"; Map keysToSourceMap = new HashMap<>(); List keys = getXmlValuesFromXPath(doc, xpathExpression); keys = keys.stream().distinct().collect(Collectors.toList()); for (String key : keys) { String sourceExpression = String.format("//urlConfig[key='%s']/label", key); List sources = getXmlValuesFromXPath(doc, sourceExpression); if (sources.size() != 0) { keysToSourceMap.put(key, sources.get(0)); } } this.keyToSourceMap = keysToSourceMap; } public ExternalUrls getExternalUrls() { if (externalUrls == null) { externalUrls = new ExternalUrls(); this.setExternalUrls(); } else { while (externalUrls.getMaxresults() == null) { try { Thread.sleep(100L); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } return externalUrls; } public List getRdaProperties() { if (rdaProperties == null) { rdaProperties = new ArrayList<>(); this.setRdaProperties(); } else { while (rdaProperties.size() == 0) { try { Thread.sleep(100L); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } return rdaProperties; } public XWPFDocument getDocument() { this.setDocument(); return document; } public ConfigurableProviders getConfigurableProviders() { if (configurableProviders == null) { configurableProviders = new ConfigurableProviders(); this.setConfigurableProviders(); } else { while (configurableProviders.getProviders().size() == 0) { try { Thread.sleep(100L); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } return configurableProviders; } public Map getKeyToSourceMap() { if (keyToSourceMap == null) { keyToSourceMap = new HashMap<>(); this.setKeyToSourceMap(); } else { while (keyToSourceMap.size() == 0) { try { Thread.sleep(100L); } catch (InterruptedException e) { logger.error(e.getMessage(), e); } } } return keyToSourceMap; } private Document getXmlDocumentFromFilePath(String filePath) { InputStream is = null; Document doc; try { is = getStreamFromPath(filePath); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); doc = documentBuilder.parse(is); return doc; } catch (IOException | ParserConfigurationException | SAXException | NullPointerException e) { logger.error(e.getMessage(), e); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); } } return null; } private List getXmlValuesFromXPath(Document doc, String expression) { XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nodeList = null; List values = new LinkedList<>(); try { nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET); } catch (XPathExpressionException e) { logger.error(e.getMessage(), e); } if (nodeList != null) { for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.hasChildNodes()) { values.add(nodeList.item(i).getChildNodes().item(0).getNodeValue()); } } } return values; } private InputStream getStreamFromPath(String filePath) { try { return new FileInputStream(filePath); } catch (FileNotFoundException e) { logger.info("loading from classpath"); return getClass().getClassLoader().getResourceAsStream(filePath); } } }