'Reuse InputStream and be compliant with Sonar rules

I have below method, which validates some xml content. The xml content is valid when in stards with element with local name that I have in rootNameToUnmarshallerClassMap map. It also must be valid against XSD file. So both validations are made in this method. There can be content that is XSD compliat but localName of start element is not in my rootNameToUnmarshallerClassMap map, this means that it is not valid from business point of view.

Below implementation has two problems: first is that I load big message to memory twice (ByteArrayInputStream) and second is that Sonar tells me to change try to try-with-resources as he see autoclosable ByteArrayInputStream usage.

Now question to more experienced developers - how can I fix it ? Thanks in advance.

 public void validate(InputStream content) throws ValidationException {
        XMLStreamReader streamReader = null;
        try {
            byte[] content = createByteArray(content);
            XMLInputFactory xmlInputFactory = getXmlInputFactory();
            streamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(content));
            navigateToFirstStartElement(streamReader);
            String localPart = streamReader.getName().getLocalPart();
            Class<? extends MyClass> jaxbClass = Optional.ofNullable(rootNameToUnmarshallerClassMap.get(localPart))
                    .orElseThrow(() -> new ValidationException(String.format("Could not validate provided content, root element %s ", localPart)));
            JAXBContext context = JAXBContext.newInstance(jaxbClass);
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema schema = sf.newSchema(this.getClass().getResource("my.xsd"));
            Unmarshaller unmarshaller = context.createUnmarshaller();
            unmarshaller.setSchema(schema);
            ContentValidationEventHandler validationEventHandler = new ContentValidationEventHandler();
            unmarshaller.setEventHandler(validationEventHandler);
            unmarshaller.unmarshal(new ByteArrayInputStream(content));
            streamReader.close();
            if (validationEventHandler.getEvents().size() > 0) {
                throw new ValidationException(String.format("contnt was not xsd compliant"));
            }
        } catch (XMLStreamException | JAXBException | SAXException | IOException e) {
            log.error(e.getMessage(), e);
            throw new IllegalArgumentException(String.format("Could not validate provided content"));
        } finally {
            try {
                if (streamReader != null) {
                    streamReader.close();
                }
            } catch (XMLStreamException e) {
                log.error(e.getMessage(), e);
            }
        }
    }


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source