diff --git a/src/main/java/org/quickfixj/codegenerator/MessageCodeGenerator.java b/src/main/java/org/quickfixj/codegenerator/MessageCodeGenerator.java index 4603ef3..86a197b 100644 --- a/src/main/java/org/quickfixj/codegenerator/MessageCodeGenerator.java +++ b/src/main/java/org/quickfixj/codegenerator/MessageCodeGenerator.java @@ -27,6 +27,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; @@ -50,6 +51,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.xml.XMLConstants; @@ -220,18 +222,42 @@ private void generateComponentClasses(Task task) throws ParserConfigurationExcep } } + private final TransformerFactory transformerFactory = new net.sf.saxon.TransformerFactoryImpl(); + + private final Map templatesCache = new ConcurrentHashMap<>(); + private Transformer createTransformer(Task task, String xsltFile) throws TransformerFactoryConfigurationError, TransformerConfigurationException { - StreamSource styleSource; - File xslt = new File(task.getTransformDirectory() + "/" + xsltFile); + final String cacheKey; + final File xslt = new File(task.getTransformDirectory() + "/" + xsltFile); if (xslt.exists()) { - styleSource = new StreamSource(xslt); + cacheKey = xslt.getAbsolutePath(); } else { - logInfo("Loading predefined xslt file:" + xsltFile); - styleSource = new StreamSource(this.getClass().getResourceAsStream(xsltFile)); + cacheKey = "classpath:" + xsltFile; + } + + try { + Templates templates = templatesCache.computeIfAbsent(cacheKey, k -> { + try { + StreamSource styleSource; + if (xslt.exists()) { + styleSource = new StreamSource(xslt); + } else { + logInfo("Loading predefined xslt file:" + xsltFile); + styleSource = new StreamSource(this.getClass().getResourceAsStream(xsltFile)); + } + return transformerFactory.newTemplates(styleSource); + } catch (TransformerConfigurationException e) { + throw new CodeGenerationException(e); + } + }); + return templates.newTransformer(); + } catch (CodeGenerationException e) { + if (e.getCause() instanceof TransformerConfigurationException) { + throw (TransformerConfigurationException) e.getCause(); + } + throw e; } - TransformerFactory transformerFactory = new net.sf.saxon.TransformerFactoryImpl(); - return transformerFactory.newTransformer(styleSource); } private final Map specificationCache = new HashMap<>();