/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jmeter.protocol.jms.sampler.render;

import static java.lang.String.format;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.jmeter.protocol.jms.sampler.PublisherSampler;
import org.apache.jmeter.util.JMeterUtils;

import com.github.benmanes.caffeine.cache.Cache;
import com.thoughtworks.xstream.XStream;

class ObjectMessageRenderer implements MessageRenderer<Serializable> {

    TextMessageRenderer delegate;

    public ObjectMessageRenderer(TextMessageRenderer delegate) {
        this.delegate = delegate;
    }

    @Override
    public Serializable getValueFromFile(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache) {
        Serializable value;
        if (hasVariable) {
            value = getInterpretedContent(filename, encoding, hasVariable, cache);
        } else {
            value = (Serializable) cache.get(filename, _p -> getContent(filename));
        }

        return value;
    }

    /**
     * Try to load an object via XStream from XML text, so that it can be used as body
     * for a JMS message.
     * An {@link IllegalStateException} will be thrown if transforming the XML to an object fails.
     *
     * @param xmlMessage String containing XML text as input for the transformation
     * @return Serialized object instance
     */
    @Override
    public Serializable getValueFromText(final String xmlMessage) {
      Serializable readObject = null;
      try {
          XStream xstream = JMeterUtils.createXStream();
          readObject = (Serializable) xstream.fromXML(xmlMessage, readObject);
      } catch (Exception e) {
          throw new IllegalStateException("Unable to load object instance from text", e);
      }
      return readObject;
    }

    /**
     * <p>Gets content with variable replaced.</p>
     * <p>If encoding {@link PublisherSampler#DEFAULT_ENCODING isn't provided}, try to find it.</p>
     * <p>Only raw text is cached, neither interpreted text, neither parsed object.</p>
     */
    protected Serializable getInterpretedContent(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache) {
        Serializable value;
        if (PublisherSampler.DEFAULT_ENCODING.equals(encoding)) {
            encoding = findEncoding(filename);
        }
        String stringValue = delegate.getValueFromFile(filename, encoding, hasVariable, cache);
        value = (Serializable) JMeterUtils.createXStream().fromXML(stringValue);
        return value;
    }

    /** Try to determine encoding based on XML prolog, if none <code>null</code> is returned. **/
    protected String findEncoding(String filename) {
        XMLInputFactory factory = XMLInputFactory.newFactory();
        try (FileInputStream input = new FileInputStream(filename)) {
            XMLStreamReader reader = factory.createXMLStreamReader(input);
            return reader.getEncoding();
        } catch (IOException|XMLStreamException e) {
            throw new RuntimeException(format("Unable to read %s", filename), e);
        }
    }

    protected Serializable getContent(String filename) {
        return (Serializable) JMeterUtils.createXStream().fromXML(new File(filename));
    }
}

@@ -1890,17 +1890,16 @@
 lename, 
-_
 p -%3E get
@@ -2819,17 +2819,18 @@
 * %3Cp%3EIf 
-e
+pE
 ncoding 
@@ -3064,32 +3064,38 @@
 ng filename,
+ final
  String 
 encoding, bo
@@ -3074,33 +3074,34 @@
 e, final String 
-e
+pE
 ncoding, boolean
@@ -3153,33 +3153,42 @@
        S
-erializable value
+tring encoding = pEncoding
 ;%0A      
@@ -3400,39 +3400,38 @@
 cache);%0A        
-value =
+return
  (Serializable) 
@@ -3480,38 +3480,16 @@
 Value);%0A
-        return value;%0A
     %7D%0A%0A 
@@ -3691,23 +3691,24 @@
 tory.new
-Factory
+Instance
 ();%0A    
@@ -3968,15 +3968,23 @@
 new 
-Runtime
+IllegalArgument
 Exce

Fix sonar errors Use XMLInputFactory.newInstance instead of XMLInputFactory.newFactory as they have same meaning and code, but latest method does not exist in stax