diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/yaml/ModelConstructor.java b/plugin/src/main/java/io/jenkins/plugins/casc/yaml/ModelConstructor.java index c61aea0d37..3fe03cce3b 100644 --- a/plugin/src/main/java/io/jenkins/plugins/casc/yaml/ModelConstructor.java +++ b/plugin/src/main/java/io/jenkins/plugins/casc/yaml/ModelConstructor.java @@ -9,9 +9,10 @@ import java.util.Map; import org.apache.commons.collections.map.AbstractMapDecorator; import org.apache.commons.lang.ObjectUtils; +import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.constructor.AbstractConstruct; import org.yaml.snakeyaml.constructor.Construct; -import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; +import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.error.Mark; import org.yaml.snakeyaml.nodes.MappingNode; import org.yaml.snakeyaml.nodes.Node; @@ -22,10 +23,19 @@ /** * @author Nicolas De Loof */ -class ModelConstructor extends CustomClassLoaderConstructor { +class ModelConstructor extends Constructor { - public ModelConstructor() { - super(Mapping.class, ModelConstructor.class.getClassLoader()); + /* + * TODO remove loader field and getClassForName method and extend CustomClassLoaderConstructor instead after this + * plugin requires SnakeYAML 2.0 + */ + + private final ClassLoader loader; + + public ModelConstructor(LoaderOptions loadingConfig) { + super(Mapping.class, loadingConfig); + + this.loader = ModelConstructor.class.getClassLoader(); this.yamlConstructors.put(Tag.BOOL, ConstructScalar); this.yamlConstructors.put(Tag.INT, ConstructScalar); @@ -85,4 +95,16 @@ protected void constructSequenceStep2(SequenceNode node, Collection collection) ((Sequence) collection).setSource(getSource(node)); super.constructSequenceStep2(node, collection); } + + /** + * Load the class + * + * @param name - the name + * @return Class to create + * @throws ClassNotFoundException - when cannot load the class + */ + @Override + protected Class getClassForName(String name) throws ClassNotFoundException { + return Class.forName(name, true, loader); + } } diff --git a/plugin/src/main/java/io/jenkins/plugins/casc/yaml/YamlUtils.java b/plugin/src/main/java/io/jenkins/plugins/casc/yaml/YamlUtils.java index 93e9caaced..a8b9d3f41b 100644 --- a/plugin/src/main/java/io/jenkins/plugins/casc/yaml/YamlUtils.java +++ b/plugin/src/main/java/io/jenkins/plugins/casc/yaml/YamlUtils.java @@ -22,6 +22,7 @@ import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.parser.ParserImpl; +import org.yaml.snakeyaml.reader.StreamReader; import org.yaml.snakeyaml.resolver.Resolver; /** @@ -56,8 +57,10 @@ public static Node merge(List sources, ConfigurationContext context) public static Node read(YamlSource source, Reader reader, ConfigurationContext context) throws IOException { LoaderOptions loaderOptions = new LoaderOptions(); loaderOptions.setMaxAliasesForCollections(context.getYamlMaxAliasesForCollections()); - Composer composer = - new Composer(new ParserImpl(new StreamReaderWithSource(source, reader)), new Resolver(), loaderOptions); + Composer composer = new Composer( + new ParserImpl(new StreamReaderWithSource(source, reader), loaderOptions), + new Resolver(), + loaderOptions); try { return composer.getSingleNode(); } catch (YAMLException e) { @@ -100,21 +103,27 @@ public static Mapping loadFrom(List sources, ConfigurationContext co LOGGER.warning("configuration-as-code yaml source returned an empty document."); return Mapping.EMPTY; } - return loadFrom(merged); + return loadFrom(merged, context); } /** * Load configuration-as-code model from a snakeyaml Node */ - private static Mapping loadFrom(Node node) { - final ModelConstructor constructor = new ModelConstructor(); - constructor.setComposer(new Composer(null, null) { + private static Mapping loadFrom(Node node, ConfigurationContext context) { + final LoaderOptions loaderOptions = new LoaderOptions(); + loaderOptions.setMaxAliasesForCollections(context.getYamlMaxAliasesForCollections()); + final ModelConstructor constructor = new ModelConstructor(loaderOptions); + constructor.setComposer( + new Composer( + new ParserImpl(new StreamReader(Reader.nullReader()), loaderOptions), + new Resolver(), + loaderOptions) { - @Override - public Node getSingleNode() { - return node; - } - }); + @Override + public Node getSingleNode() { + return node; + } + }); return (Mapping) constructor.getSingleData(Mapping.class); } }