Skip to content
Permalink
Browse files

Tweak XmlInputFactory settings

  • Loading branch information...
benas committed Jan 11, 2019
1 parent 7ca11f2 commit edfbdbb82a61294c2ea7eaabeb1add29ca6cb068
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2014 the original author or authors.
* Copyright 2010-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
import java.io.StringWriter;
import java.math.BigDecimal;

import javax.xml.XMLConstants;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -48,7 +49,10 @@ protected Marshaller getMarshaller() throws Exception {

public static String getTextFromSource(Source source) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult stream = new StreamResult(new StringWriter());
transformer.transform(source, stream);
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@
* The implementation is <b>not</b> thread-safe.
*
* @author Robert Kasanicky
* @author Mahmoud Ben Hassine
*/
public class StaxEventItemReader<T> extends AbstractItemCountingItemStreamItemReader<T> implements
ResourceAwareItemReaderItemStream<T>, InitializingBean {
@@ -76,6 +77,8 @@

private boolean strict = true;

private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();

public StaxEventItemReader() {
setName(ClassUtils.getShortName(StaxEventItemReader.class));
}
@@ -118,6 +121,15 @@ public void setFragmentRootElementNames(String[] fragmentRootElementNames) {
}
}

/**
* Set the {@link XMLInputFactory}.
* @param xmlInputFactory to use
*/
public void setXmlInputFactory(XMLInputFactory xmlInputFactory) {
Assert.notNull(xmlInputFactory, "XMLInputFactory must not be null");
this.xmlInputFactory = xmlInputFactory;
}

/**
* Ensure that all required dependencies for the ItemReader to run are provided after all properties have been set.
*
@@ -208,7 +220,7 @@ protected void doOpen() throws Exception {
}

inputStream = resource.getInputStream();
eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
eventReader = xmlInputFactory.createXMLEventReader(inputStream);
fragmentReader = new DefaultFragmentEventReader(eventReader);
noInput = false;

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2007 the original author or authors.
* Copyright 2006-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -31,6 +32,7 @@
* This class is thread-safe.
*
* @author Josh Long
* @author Mahmoud Ben Hassine
*
*/
public abstract class StaxUtils {
@@ -42,4 +44,11 @@ public static Source getSource(XMLEventReader r) throws XMLStreamException {
public static Result getResult(XMLEventWriter w) {
return new StAXResult(w);
}

public static XMLInputFactory createXmlInputFactory() {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
return xmlInputFactory;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,10 @@
import java.util.Arrays;
import java.util.List;

import javax.xml.stream.XMLInputFactory;

import org.springframework.batch.item.xml.StaxEventItemReader;
import org.springframework.batch.item.xml.StaxUtils;
import org.springframework.core.io.Resource;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
@@ -50,6 +53,8 @@

private int currentItemCount;

private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();

/**
* Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport}
* should be persisted within the {@link org.springframework.batch.item.ExecutionContext}
@@ -175,6 +180,19 @@
return this;
}

/**
* Set the {@link XMLInputFactory}.
*
* @param xmlInputFactory to use
* @return The current instance of the builder
* @see StaxEventItemReader#setXmlInputFactory(XMLInputFactory)
*/
public StaxEventItemReaderBuilder<T> xmlInputFactory(XMLInputFactory xmlInputFactory) {
this.xmlInputFactory = xmlInputFactory;

return this;
}

/**
* Validates the configuration and builds a new {@link StaxEventItemReader}
*
@@ -203,6 +221,7 @@
reader.setUnmarshaller(this.unmarshaller);
reader.setCurrentItemCount(this.currentItemCount);
reader.setMaxItemCount(this.maxItemCount);
reader.setXmlInputFactory(this.xmlInputFactory);

return reader;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.batch.item.xml;

import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.item.ExecutionContext;
@@ -33,12 +35,12 @@
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Source;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -56,6 +58,8 @@
* Tests for {@link StaxEventItemReader}.
*
* @author Robert Kasanicky
* @author Michael Minella
* @author Mahmoud Ben Hassine
*/
public class StaxEventItemReaderTests {

@@ -329,7 +333,7 @@ public void testMultiFragmentNestedRestart() throws Exception {
@Test
public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(xml.getBytes());
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());

final int EXPECTED_NUMBER_OF_FRAGMENTS = 2;
for (int i = 0; i < EXPECTED_NUMBER_OF_FRAGMENTS; i++) {
@@ -346,7 +350,7 @@ public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryCon
@Test
public void testMoveCursorToNextFragmentOnEmpty() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(emptyXml.getBytes());
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());

assertFalse(source.moveCursorToNextFragment(reader));
}
@@ -357,7 +361,7 @@ public void testMoveCursorToNextFragmentOnEmpty() throws XMLStreamException, Fac
@Test
public void testMoveCursorToNextFragmentOnMissing() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(missingXml.getBytes());
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
assertFalse(source.moveCursorToNextFragment(reader));
}

@@ -577,6 +581,39 @@ public void exceptionDuringUnmarshalling() throws Exception {
assertNull(source.read());
}

@Test
public void testDtdXml() {
String xmlWithDtd = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE rohit [\n<!ENTITY entityex SYSTEM \"file://" +
new File("src/test/resources/org/springframework/batch/support/existing.txt").getAbsolutePath() +
"\">\n]>\n<abc>&entityex;</abc>";
StaxEventItemReader<String> reader = new StaxEventItemReader<>();
reader.setName("foo");
reader.setResource(new ByteArrayResource(xmlWithDtd.getBytes()));
reader.setUnmarshaller(new MockFragmentUnmarshaller() {
@Override
public Object unmarshal(Source source) throws XmlMappingException {
try {
XMLEventReader xmlEventReader = StaxTestUtils.getXmlEventReader(source);
xmlEventReader.nextEvent();
xmlEventReader.nextEvent();
return xmlEventReader.getElementText();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
reader.setFragmentRootElementName("abc");

reader.open(new ExecutionContext());

try {
reader.read();
fail("Should fail when XML contains DTD");
} catch (Exception e) {
Assert.assertThat(e.getMessage(), Matchers.containsString("Undeclared general entity \"entityex\""));
}
}

/**
* Stub emulating problems during unmarshalling.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.batch.item.xml.builder;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.stream.XMLInputFactory;

import org.junit.Before;
import org.junit.Test;
@@ -35,6 +36,7 @@

/**
* @author Michael Minella
* @author Mahmoud Ben Hassine
*/
public class StaxEventItemReaderBuilderTests {

@@ -95,6 +97,7 @@ public void testConfiguration() throws Exception {
.currentItemCount(1)
.maxItemCount(2)
.unmarshaller(unmarshaller)
.xmlInputFactory(XMLInputFactory.newInstance())
.build();

reader.afterPropertiesSet();
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2012 the original author or authors.
* Copyright 2008-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,20 +18,21 @@
import java.util.NoSuchElementException;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

import junit.framework.TestCase;

import org.springframework.batch.item.xml.EventHelper;
import org.springframework.batch.item.xml.StaxUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;

/**
* Tests for {@link DefaultFragmentEventReader}.
*
* @author Robert Kasanicky
* @author Mahmoud Ben Hassine
*/
public class DefaultFragmentEventReaderTests extends TestCase {

@@ -50,7 +51,7 @@
@Override
protected void setUp() throws Exception {
Resource input = new ByteArrayResource(xml.getBytes());
eventReader = XMLInputFactory.newInstance().createXMLEventReader(
eventReader = StaxUtils.createXmlInputFactory().createXMLEventReader(
input.getInputStream());
fragmentReader = new DefaultFragmentEventReader(eventReader);
}

0 comments on commit edfbdbb

Please sign in to comment.
You can’t perform that action at this time.