You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by mc...@apache.org on 2017/02/16 23:50:01 UTC

svn commit: r1783319 [1/2] - in /jmeter/trunk: src/jorphan/org/apache/jorphan/gui/ src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/ src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/ src/protocol/jms/org/apache/jmeter/protocol/jms/sam...

Author: mchassagneux
Date: Thu Feb 16 23:50:00 2017
New Revision: 1783319

URL: http://svn.apache.org/viewvc?rev=1783319&view=rev
Log:
Support variable for all JMS messages (bytes, object, ...) and sources (file, folder)

Added:
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/cache/
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java   (with props)
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/cp1252.txt   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt   (with props)
    jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/utf8.txt   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/cache/
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/test/
    jmeter/trunk/test/src/org/apache/jmeter/test/ResourceLocator.java   (with props)
    jmeter/trunk/test/src/org/apache/jmeter/threads/JMeterContextServiceHelper.java   (with props)
Modified:
    jmeter/trunk/src/jorphan/org/apache/jorphan/gui/JLabeledChoice.java
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/JMSPublisherGui.java
    jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/PublisherSampler.java
    jmeter/trunk/xdocs/changes.xml

Modified: jmeter/trunk/src/jorphan/org/apache/jorphan/gui/JLabeledChoice.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/jorphan/org/apache/jorphan/gui/JLabeledChoice.java?rev=1783319&r1=1783318&r2=1783319&view=diff
==============================================================================
--- jmeter/trunk/src/jorphan/org/apache/jorphan/gui/JLabeledChoice.java (original)
+++ jmeter/trunk/src/jorphan/org/apache/jorphan/gui/JLabeledChoice.java Thu Feb 16 23:50:00 2017
@@ -173,6 +173,10 @@ public class JLabeledChoice extends JPan
 
     }
 
+    public void setChoiceListEnabled(boolean enabled) {
+        choiceList.setEnabled(enabled);
+    }
+
     /**
      * Set the text displayed in the label.
      *

Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/JMSPublisherGui.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/JMSPublisherGui.java?rev=1783319&r1=1783318&r2=1783319&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/JMSPublisherGui.java (original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/control/gui/JMSPublisherGui.java Thu Feb 16 23:50:00 2017
@@ -39,6 +39,7 @@ import org.apache.jmeter.protocol.jms.sa
 import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
 import org.apache.jmeter.testelement.TestElement;
 import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.JLabeledChoice;
 import org.apache.jorphan.gui.JLabeledPasswordField;
 import org.apache.jorphan.gui.JLabeledTextField;
 
@@ -56,7 +57,7 @@ public class JMSPublisherGui extends Abs
     /** Take source from a random file */
     public static final String USE_RANDOM_RSC = "jms_use_random_file"; //$NON-NLS-1$
     /** Take source from the text area */
-    private static final String USE_TEXT_RSC   = "jms_use_text"; //$NON-NLS-1$
+    public static final String USE_TEXT_RSC   = "jms_use_text"; //$NON-NLS-1$
 
     /** Create a TextMessage */
     public static final String TEXT_MSG_RSC = "jms_text_message"; //$NON-NLS-1$
@@ -111,6 +112,8 @@ public class JMSPublisherGui extends Abs
 
     private final JLabeledRadioI18N msgChoice = new JLabeledRadioI18N("jms_message_type", MSGTYPES_ITEMS, TEXT_MSG_RSC); //$NON-NLS-1$
     
+    private JLabeledChoice fileEncoding;
+
     private final JCheckBox useNonPersistentDelivery = new JCheckBox(JMeterUtils.getResString("jms_use_non_persistent_delivery"),false); //$NON-NLS-1$
 
     // These are the names of properties used to define the labels
@@ -180,6 +183,7 @@ public class JMSPublisherGui extends Abs
       sampler.setInputFile(messageFile.getFilename());
       sampler.setRandomPath(randomFile.getFilename());
       sampler.setConfigChoice(configChoice.getText());
+      sampler.setFileEncoding(fileEncoding.getText());
       sampler.setMessageChoice(msgChoice.getText());
       sampler.setIterations(iterations.getText());
       sampler.setUseAuth(useAuth.isSelected());
@@ -218,6 +222,13 @@ public class JMSPublisherGui extends Abs
         mainPanel.add(configChoice);
         msgChoice.setLayout(new BoxLayout(msgChoice, BoxLayout.X_AXIS));
         mainPanel.add(msgChoice);
+
+        fileEncoding = new JLabeledChoice(JMeterUtils.getResString("content_encoding") + "\u00A0\u00A0", // $NON-NLS-1$
+                PublisherSampler.getSupportedEncodings(), true, false);
+        fileEncoding.setLayout(new BoxLayout(fileEncoding, BoxLayout.X_AXIS));
+        fileEncoding.add(Box.createHorizontalGlue());
+        mainPanel.add(fileEncoding);
+
         mainPanel.add(messageFile);
         mainPanel.add(randomFile);
 
@@ -249,6 +260,7 @@ public class JMSPublisherGui extends Abs
         messageFile.setFilename(""); // $NON-NLS-1$
         randomFile.setFilename(""); // $NON-NLS-1$
         msgChoice.setText(""); // $NON-NLS-1$
+        fileEncoding.setSelectedIndex(0);
         configChoice.setText(USE_TEXT_RSC);
         updateConfig(USE_TEXT_RSC);
         msgChoice.setText(TEXT_MSG_RSC);
@@ -281,6 +293,7 @@ public class JMSPublisherGui extends Abs
         randomFile.setFilename(sampler.getRandomPath());
         configChoice.setText(sampler.getConfigChoice());
         msgChoice.setText(sampler.getMessageChoice());
+        fileEncoding.setText(sampler.getFileEncoding());
         iterations.setText(sampler.getIterations());
         expiration.setText(sampler.getExpiration());
         jmsErrorReconnectOnCodes.setText(sampler.getReconnectionErrorCodes());
@@ -315,6 +328,12 @@ public class JMSPublisherGui extends Abs
             jmsPwd.setEnabled(useAuth.isSelected()  && useAuth.isEnabled());
         }
     }
+
+    private void updateFileEncoding() {
+        boolean isTextMode = USE_TEXT_RSC.equals(configChoice.getText());
+        boolean isObjectType = OBJECT_MSG_RSC.equals(msgChoice.getText());
+        fileEncoding.setChoiceListEnabled(!isTextMode && !isObjectType);
+    }
     /**
      * Update choice contains the actual logic for hiding or showing Textarea if Bytes message
      * is selected
@@ -333,6 +352,7 @@ public class JMSPublisherGui extends Abs
             configChoice.resetButtons(CONFIG_ITEMS, oldChoice);
             textMessage.setEnabled(true);
         }
+        updateFileEncoding();
         validate();
     }
     /**
@@ -355,6 +375,7 @@ public class JMSPublisherGui extends Abs
             messageFile.enableFile(true);
             randomFile.enableFile(false);
         }
+        updateFileEncoding();
     }
     
     /**

Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/PublisherSampler.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/PublisherSampler.java?rev=1783319&r1=1783318&r2=1783319&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/PublisherSampler.java (original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/PublisherSampler.java Thu Feb 16 23:50:00 2017
@@ -17,19 +17,20 @@
 
 package org.apache.jmeter.protocol.jms.sampler;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.Serializable;
 import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
+import java.lang.reflect.Modifier;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 import javax.jms.DeliveryMode;
 import javax.jms.JMSException;
@@ -43,23 +44,53 @@ import org.apache.jmeter.protocol.jms.cl
 import org.apache.jmeter.protocol.jms.client.InitialContextFactory;
 import org.apache.jmeter.protocol.jms.client.Publisher;
 import org.apache.jmeter.protocol.jms.control.gui.JMSPublisherGui;
+import org.apache.jmeter.protocol.jms.sampler.render.MessageRenderer;
+import org.apache.jmeter.protocol.jms.sampler.render.Renderers;
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jmeter.services.FileServer;
 import org.apache.jmeter.testelement.TestStateListener;
 import org.apache.jmeter.testelement.property.TestElementProperty;
 import org.apache.jmeter.util.JMeterUtils;
-import org.apache.jorphan.io.TextFile;
-import org.apache.jorphan.util.JOrphanUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.thoughtworks.xstream.XStream;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
 
 /**
  * This class implements the JMS Publisher sampler.
  */
 public class PublisherSampler extends BaseJMSSampler implements TestStateListener {
 
+    /** Encoding value to sent data as is (no variabilisation) **/
+    public static final String RAW_DATA         = "<RAW>";
+    /** Encoding value to sent parsed data but read with default system encoding **/
+    public static final String DEFAULT_ENCODING = "<DEFAULT>";
+
+    /** Constant for system default encodings **/
+    public static final Set<String> NO_ENCODING = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(RAW_DATA, DEFAULT_ENCODING)));
+
+    /** Init available encoding using constants, then JVM standard ones **/
+    public static String[] getSupportedEncodings() {
+        // Only get JVM standard charsets
+        return Stream.concat(
+            NO_ENCODING.stream(),
+            Arrays
+                .stream(StandardCharsets.class.getDeclaredFields())
+                .filter(f -> Modifier.isStatic(f.getModifiers()) && Modifier.isPublic(f.getModifiers()) && f.getType() == Charset.class)
+                .map(f -> {
+                    try {
+                        return (Charset) f.get(null);
+                    } catch (IllegalArgumentException | IllegalAccessException e) {
+                        throw new RuntimeException(e);
+                    }
+                })
+                .map(Charset::displayName)
+                .sorted()
+         )
+         .toArray(size -> new String[size]);
+    }
+
     private static final long serialVersionUID = 233L;
 
     private static final Logger log = LoggerFactory.getLogger(PublisherSampler.class);
@@ -74,15 +105,22 @@ public class PublisherSampler extends Ba
     private static final String CONFIG_CHOICE = "jms.config_choice"; //$NON-NLS-1$
 
     private static final String MESSAGE_CHOICE = "jms.config_msg_type"; //$NON-NLS-1$
-    
+
     private static final String NON_PERSISTENT_DELIVERY = "jms.non_persistent"; //$NON-NLS-1$
-    
+
     private static final String JMS_PROPERTIES = "jms.jmsProperties"; // $NON-NLS-1$
 
     private static final String JMS_PRIORITY = "jms.priority"; // $NON-NLS-1$
 
     private static final String JMS_EXPIRATION = "jms.expiration"; // $NON-NLS-1$
 
+    private static final String JMS_FILE_ENCODING = "jms.file_encoding"; // $NON-NLS-1$
+
+    /** File extensions for text files **/
+    private static final String[] EXT_FILE_TEXT = { ".txt", ".obj" };
+    /** File extensions for binary files **/
+    private static final String[] EXT_FILE_BIN  = { ".dat"         };
+
     //--
 
     // Does not need to be synch. because it is only accessed from the sampler thread
@@ -91,19 +129,8 @@ public class PublisherSampler extends Ba
 
     private static final FileServer FSERVER = FileServer.getFileServer();
 
-    // Cache for file. Only used by sample() in a single thread
-    private String file_contents = null;
-    // Cache for object-message, only used when parsing from a file because in text-area
-    // property replacement might have been used
-    private Serializable object_msg_file_contents = null;
-    // Cache for bytes-message, only used when parsing from a file 
-    private byte[] bytes_msg_file_contents = null;
-
-    // Cached file name
-    private String cachedFileName;
-
-    public PublisherSampler() {
-    }
+    /** File cache handler **/
+    private Cache<Object,Object> fileCache = null;
 
     /**
      * the implementation calls testStarted() without any parameters.
@@ -137,11 +164,12 @@ public class PublisherSampler extends Ba
 
     /**
      * initialize the Publisher client.
-     * @throws JMSException 
-     * @throws NamingException 
+     * @throws JMSException
+     * @throws NamingException
      *
      */
     private void initClient() throws JMSException, NamingException {
+
         configureIsReconnectErrorCode();
         publisher = new Publisher(getUseJNDIPropertiesAsBoolean(), getJNDIInitialContextFactory(), 
                 getProviderUrl(), getConnectionFactory(), getDestination(), isUseAuth(), getUsername(),
@@ -158,6 +186,12 @@ public class PublisherSampler extends Ba
      */
     @Override
     public SampleResult sample() {
+        String configChoice = getConfigChoice();
+        if (fileCache == null) {
+            Cache<Object, Object> newCache = buildCache(configChoice);
+            fileCache = newCache;
+        }
+
         SampleResult result = new SampleResult();
         result.setSampleLabel(getName());
         result.setSuccessful(false); // Assume it will fail
@@ -175,34 +209,34 @@ public class PublisherSampler extends Ba
         int loop = getIterationCount();
         result.sampleStart();
         String type = getMessageChoice();
-        
+
         try {
             Map<String, Object> msgProperties = getJMSProperties().getJmsPropertysAsMap();
-            int deliveryMode = getUseNonPersistentDelivery() ? DeliveryMode.NON_PERSISTENT : DeliveryMode.PERSISTENT; 
+            int deliveryMode = getUseNonPersistentDelivery() ? DeliveryMode.NON_PERSISTENT : DeliveryMode.PERSISTENT;
             int priority = Integer.parseInt(getPriority());
             long expiration = Long.parseLong(getExpiration());
-            
+
             for (int idx = 0; idx < loop; idx++) {
+                Message msg;
                 if (JMSPublisherGui.TEXT_MSG_RSC.equals(type)){
-                    String tmsg = getMessageContent();
-                    Message msg = publisher.publish(tmsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
+                    String tmsg = getRenderedContent(String.class, EXT_FILE_TEXT);
+                    msg = publisher.publish(tmsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
                     buffer.append(tmsg);
-                    Utils.messageProperties(propBuffer, msg);
                 } else if (JMSPublisherGui.MAP_MSG_RSC.equals(type)){
-                    Map<String, Object> m = getMapContent();
-                    Message msg = publisher.publish(m, getDestination(), msgProperties, deliveryMode, priority, expiration);
-                    Utils.messageProperties(propBuffer, msg);
+                    @SuppressWarnings("unchecked")
+                    Map<String,Object> map = getRenderedContent(Map.class, EXT_FILE_TEXT);
+                    Map<String, Object> m = map;
+                    msg = publisher.publish(m, getDestination(), msgProperties, deliveryMode, priority, expiration);
                 } else if (JMSPublisherGui.OBJECT_MSG_RSC.equals(type)){
-                    Serializable omsg = getObjectContent();
-                    Message msg = publisher.publish(omsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
-                    Utils.messageProperties(propBuffer, msg);
+                    Serializable omsg = getRenderedContent(Serializable.class, EXT_FILE_TEXT);
+                    msg = publisher.publish(omsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
                 } else if (JMSPublisherGui.BYTES_MSG_RSC.equals(type)){
-                    byte[] bmsg = getBytesContent();
-                    Message msg = publisher.publish(bmsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
-                    Utils.messageProperties(propBuffer, msg);
+                    byte[] bmsg = getRenderedContent(byte[].class, EXT_FILE_BIN);
+                    msg = publisher.publish(bmsg, getDestination(), msgProperties, deliveryMode, priority, expiration);
                 } else {
-                    throw new JMSException(type+ " is not recognised");                    
+                    throw new JMSException(type+ " is not recognised");
                 }
+                Utils.messageProperties(propBuffer, msg);
             }
             result.setResponseCodeOK();
             result.setResponseMessage(loop + " messages published");
@@ -215,7 +249,7 @@ public class PublisherSampler extends Ba
         } catch (Exception e) {
             handleError(result, e, false);
         } finally {
-            result.sampleEnd();            
+            result.sampleEnd();
         }
         return result;
     }
@@ -250,198 +284,54 @@ public class PublisherSampler extends Ba
         result.setResponseData(writer.toString(), "UTF-8");
     }
 
-    private Map<String, Object> getMapContent() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-        Map<String,Object> m = new HashMap<>();
-        String text = getMessageContent();
-        String[] lines = text.split("\n");
-        for (String line : lines){
-            String[] parts = line.split(",",3);
-            if (parts.length != 3) {
-                throw new IllegalArgumentException("line must have 3 parts: "+line);
-            }
-            String name = parts[0];
-            String type = parts[1];
-            if (!type.contains(".")){// Allow shorthand names
-                type = "java.lang."+type;
-            }
-            String value = parts[2];
-            Object obj;
-            if (type.equals("java.lang.String")){
-                obj = value;
-            } else {
-                Class <?> clazz = Class.forName(type);
-                Method method = clazz.getMethod("valueOf", String.class);
-                obj = method.invoke(clazz, value);                
-            }
-            m.put(name, obj);
+    protected static Cache<Object, Object> buildCache(String configChoice) {
+        Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder();
+        switch (configChoice) {
+            case JMSPublisherGui.USE_FILE_RSC:
+                cacheBuilder.maximumSize(1);
+                break;
+            default:
+                cacheBuilder.expireAfterWrite(0, TimeUnit.MILLISECONDS).maximumSize(0);
+        }
+        Cache<Object, Object> newCache = cacheBuilder.build();
+        return newCache;
+    }
+                	
+    /** Gets file path to use **/
+    private String getFilePath(String... ext) {
+        switch (getConfigChoice()) {
+            case JMSPublisherGui.USE_FILE_RSC:
+                return getInputFile();
+            case JMSPublisherGui.USE_RANDOM_RSC:
+                String fname = FSERVER.getRandomFile(getRandomPath(), ext).getAbsolutePath();
+                return fname;
+            default:
+                throw new IllegalArgumentException("Type of input not handled:" + getConfigChoice());
         }
-        return m;
     }
 
-    /**
-     * Method will check the setting and get the contents for the message.
-     *
-     * @return the contents for the message
-     */
-    private String getMessageContent() {
-        if (getConfigChoice().equals(JMSPublisherGui.USE_FILE_RSC)) {
-            // in the case the test uses a file, we set it locally and
-            // prevent loading the file repeatedly
-            // if the file name changes we reload it
-            if (file_contents == null || !Objects.equals(cachedFileName, getInputFile())) {
-                cachedFileName = getInputFile();
-                file_contents = getFileContent(getInputFile());
-            }
-            return file_contents;
-        } else if (getConfigChoice().equals(JMSPublisherGui.USE_RANDOM_RSC)) {
-            // Maybe we should consider creating a global cache for the
-            // random files to make JMeter more efficient.
-            String fname = FSERVER.getRandomFile(getRandomPath(), new String[] { ".txt", ".obj" })
-                    .getAbsolutePath();
-            return getFileContent(fname);
+    /** Look-up renderer and get appropriate value
+     *
+     * @param type Message type to render
+     * @param fileExts File extensions for directory mode.
+     **/
+    private <T> T getRenderedContent(Class<T> type, String[] fileExts) {
+        MessageRenderer<T> renderer = Renderers.getInstance(type);
+        if (getConfigChoice().equals(JMSPublisherGui.USE_TEXT_RSC)) {
+            return renderer.getValueFromText(getTextMessage());
         } else {
-            return getTextMessage();
+            return renderer.getValueFromFile(getFilePath(fileExts), getFileEncoding(), !isRaw(), fileCache);
         }
     }
 
     /**
-     * The implementation uses TextFile to load the contents of the file and
-     * returns a string.
-     *
-     * @param path path to the file to read in
-     * @return the contents of the file
+     * Specified if value must be parsed or not.
+     * @return <code>true</code> if value must be sent as-is.
      */
-    public String getFileContent(String path) {
-        TextFile tf = new TextFile(path);
-        return tf.getText();
-    }
-
-    /**
-     * This method will load the contents for the JMS Object Message.
-     * The contents are either loaded from file (might be cached), random file
-     * or from the GUI text-area.
-     * 
-     * @return Serialized object as loaded from the specified input file
-     */
-    private Serializable getObjectContent() {
-        if (getConfigChoice().equals(JMSPublisherGui.USE_FILE_RSC)) {
-            // in the case the test uses a file, we set it locally and
-            // prevent loading the file repeatedly
-            // if the file name changes we reload it
-            if (object_msg_file_contents == null || !Objects.equals(cachedFileName, getInputFile())) {
-                cachedFileName = getInputFile();
-                object_msg_file_contents = getFileObjectContent(getInputFile());
-            }
-
-            return object_msg_file_contents;
-        } else if (getConfigChoice().equals(JMSPublisherGui.USE_RANDOM_RSC)) {
-            // Maybe we should consider creating a global cache for the
-            // random files to make JMeter more efficient.
-            final String fname = FSERVER.getRandomFile(getRandomPath(), new String[] {".txt", ".obj"})
-                .getAbsolutePath();
-
-            return getFileObjectContent(fname);
-        } else {
-            final String xmlMessage = getTextMessage();
-            return transformXmlToObjectMessage(xmlMessage);
-        }
+    private boolean isRaw() {
+        return RAW_DATA.equals(getFileEncoding());
     }
-    
-    /**
-     * This method will load the contents for the JMS BytesMessage.
-     * The contents are either loaded from file (might be cached), random file
-     * 
-     * @return byte[] as loaded from the specified input file
-     * @since 2.9
-     */
-    private  byte[] getBytesContent() {
-        if (getConfigChoice().equals(JMSPublisherGui.USE_FILE_RSC)) {
-            // in the case the test uses a file, we set it locally and
-            // prevent loading the file repeatedly
-            // if the file name changes we reload it
-            if (bytes_msg_file_contents == null || !Objects.equals(cachedFileName, getInputFile())) {
-                cachedFileName = getInputFile();
-                bytes_msg_file_contents = getFileBytesContent(getInputFile());
-            }
-
-            return bytes_msg_file_contents;
-        } else if (getConfigChoice().equals(JMSPublisherGui.USE_RANDOM_RSC)) {
-            final String fname = FSERVER.getRandomFile(getRandomPath(), new String[] {".dat"})
-                .getAbsolutePath();
 
-            return getFileBytesContent(fname);
-        } else {
-            throw new IllegalArgumentException("Type of input not handled:" + getConfigChoice());
-        }
-    }
-    
-    /**
-     * Try to load an object from a provided file, so that it can be used as body
-     * for a JMS message.
-     * An {@link IllegalStateException} will be thrown if loading the object fails.
-     * 
-     * @param path Path to the file that will be serialized
-     * @return byte[]  instance
-     * @since 2.9
-     */
-    private static byte[] getFileBytesContent(final String path) {
-        InputStream inputStream = null;
-        try {
-            File file = new File(path);
-            inputStream = new BufferedInputStream(new FileInputStream(file));
-            return IOUtils.toByteArray(inputStream, (int)file.length());
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage(), e);
-            throw new IllegalStateException("Unable to load file:'"+path+"'", e);
-        } finally {
-            JOrphanUtils.closeQuietly(inputStream);
-        }
-    }
-    
-    /**
-     * Try to load an object from a provided file, so that it can be used as body
-     * for a JMS message.
-     * An {@link IllegalStateException} will be thrown if loading the object fails.
-     * 
-     * @param path Path to the file that will be serialized
-     * @return Serialized object instance
-     */
-    private static Serializable getFileObjectContent(final String path) {
-      Serializable readObject = null;
-      InputStream inputStream = null;
-      try {
-          inputStream = new BufferedInputStream(new FileInputStream(path));
-          XStream xstream = new XStream();
-        readObject = (Serializable) xstream.fromXML(inputStream, readObject);
-      } catch (Exception e) {
-          log.error(e.getLocalizedMessage(), e);
-          throw new IllegalStateException("Unable to load object instance from file:'"+path+"'", e);
-      } finally {
-          JOrphanUtils.closeQuietly(inputStream);
-      }
-      return readObject;
-    }
-    
-    /**
-     * 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
-     */
-    private static Serializable transformXmlToObjectMessage(final String xmlMessage) {
-      Serializable readObject = null;
-      try {
-          XStream xstream = new XStream();
-          readObject = (Serializable) xstream.fromXML(xmlMessage, readObject);
-      } catch (Exception e) {
-          log.error(e.getLocalizedMessage(), e);
-          throw new IllegalStateException("Unable to load object instance from text", e);
-      }
-      return readObject;
-    }
-    
     // ------------- get/set properties ----------------------//
     /**
      * set the source of the message
@@ -469,7 +359,7 @@ public class PublisherSampler extends Ba
     public String getConfigChoice() {
         // Allow for the old JMX file which used the local language string
         String config = getPropertyAsString(CONFIG_CHOICE);
-        if (config.equals(USE_FILE_LOCALNAME) 
+        if (config.equals(USE_FILE_LOCALNAME)
          || config.equals(JMSPublisherGui.USE_FILE_RSC)){
             return JMSPublisherGui.USE_FILE_RSC;
         }
@@ -565,7 +455,7 @@ public class PublisherSampler extends Ba
             return priority;
         }
     }
-    
+
     public void setPriority(String s) {
         // Bug 59173
         if (Utils.DEFAULT_PRIORITY_4.equals(s)) {
@@ -573,7 +463,7 @@ public class PublisherSampler extends Ba
         }
         setProperty(JMS_PRIORITY, s); // always need to save the field
     }
-    
+
     public void setExpiration(String s) {
         // Bug 59173
         if (Utils.DEFAULT_NO_EXPIRY.equals(s)) {
@@ -581,14 +471,14 @@ public class PublisherSampler extends Ba
         }
         setProperty(JMS_EXPIRATION, s); // always need to save the field
     }
-    
+
     /**
      * @param value boolean use NON_PERSISTENT
      */
     public void setUseNonPersistentDelivery(boolean value) {
         setProperty(NON_PERSISTENT_DELIVERY, value, false);
     }
-    
+
     /**
      * @return true if NON_PERSISTENT delivery must be used
      */
@@ -596,7 +486,7 @@ public class PublisherSampler extends Ba
         return getPropertyAsBoolean(NON_PERSISTENT_DELIVERY, false);
     }
 
-    /** 
+    /**
      * @return {@link JMSProperties} JMS Properties
      */
     public JMSProperties getJMSProperties() {
@@ -614,11 +504,33 @@ public class PublisherSampler extends Ba
         }
         return jmsProperties;
     }
-    
+
     /**
      * @param jmsProperties JMS Properties
      */
     public void setJMSProperties(JMSProperties jmsProperties) {
         setProperty(new TestElementProperty(JMS_PROPERTIES, jmsProperties));
     }
+
+    /**
+     * Gets file encoding to use. If {@value #RAW_DATA}, content isn't parsed.
+     * @return File encoding.
+     * @see #RAW_DATA
+     * @see #DEFAULT_ENCODING
+     * @see #getSupportedEncodings()
+     */
+    public String getFileEncoding() {
+        return getPropertyAsString(JMS_FILE_ENCODING, RAW_DATA);
+    }
+
+    /**
+     * Sets file encoding to use. If {@value #RAW_DATA}, content isn't parsed.
+     * @param fileEncoding File encoding.
+     * @see #RAW_DATA
+     * @see #DEFAULT_ENCODING
+     * @see #getSupportedEncodings()
+     */
+    public void setFileEncoding(String fileEncoding) {
+        setProperty(JMS_FILE_ENCODING, fileEncoding, RAW_DATA);
+    }
 }

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,69 @@
+/*
+ * 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.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.apache.jmeter.protocol.jms.control.gui.JMSPublisherGui;
+
+import com.github.benmanes.caffeine.cache.Cache;
+
+class BinaryMessageRenderer implements MessageRenderer<byte[]> {
+
+    private TextMessageRenderer delegate;
+
+    public BinaryMessageRenderer(TextMessageRenderer delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public byte[] getValueFromText(String text) {
+        throw new UnsupportedOperationException(format("Type of input not handled: %s", JMSPublisherGui.USE_TEXT_RSC));
+    }
+
+    @Override
+    public byte[] getValueFromFile(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache) {
+        byte[] bytes;
+
+        if (hasVariable) {
+            String stringValue = delegate.getValueFromFile(filename, encoding, hasVariable, cache);
+            try {
+                bytes = stringValue.getBytes(encoding);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            bytes = (byte[]) cache.get(filename, _p -> getContent(filename));
+        }
+
+        return bytes;
+    }
+
+    byte[] getContent(String filename) {
+        try {
+            return Files.readAllBytes(Paths.get(filename));
+        } catch (IOException e) {
+            throw new RuntimeException(format("Can't read content of %s", filename), e);
+        }
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRenderer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,60 @@
+/*
+ * 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 java.util.Objects;
+
+/** File specification for {@link TextMessageRenderer} **/
+class FileKey {
+
+    private final String filename;
+    private final String encoding;
+
+    public FileKey(String filename, String encoding) {
+        this.filename = filename;
+        this.encoding = encoding;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(filename);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof FileKey)) {
+            return false;
+        }
+
+        FileKey that = (FileKey) obj;
+
+        return Objects.equals(this.filename, that.filename);
+
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/FileKey.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,73 @@
+/*
+ * 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 java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.github.benmanes.caffeine.cache.Cache;
+
+public class MapMessageRenderer implements MessageRenderer<Map<String,Object>> {
+
+    private TextMessageRenderer delegate;
+
+    public MapMessageRenderer(TextMessageRenderer delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Map<String, Object> getValueFromText(String text) {
+        Map<String,Object> m = new HashMap<>();
+        String[] lines = text.split("\n");
+        for (String line : lines){
+            String[] parts = line.split(",",3);
+            if (parts.length != 3) {
+                throw new IllegalArgumentException("line must have 3 parts: "+line);
+            }
+            String name = parts[0];
+            String type = parts[1];
+            if (!type.contains(".")){// Allow shorthand names
+                type = "java.lang."+type;
+            }
+            String value = parts[2];
+            Object obj;
+            if (type.equals("java.lang.String")){
+                obj = value;
+            } else {
+                try {
+                    Class <?> clazz = Class.forName(type);
+                    Method method = clazz.getMethod("valueOf", new Class<?>[]{String.class});
+                    obj = method.invoke(clazz, value);
+                } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException
+                        | IllegalArgumentException | InvocationTargetException e) {
+                    throw new RuntimeException(String.format("Can't convert %s to object", line), e);
+                }
+            }
+            m.put(name, obj);
+        }
+        return m;
+    }
+
+    @Override
+    public Map<String, Object> getValueFromFile(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache) {
+        String text = delegate.getValueFromFile(filename, encoding, hasVariable, cache);
+        return getValueFromText(text);
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MapMessageRenderer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,27 @@
+/*
+ * 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 com.github.benmanes.caffeine.cache.Cache;
+
+public interface MessageRenderer<T> {
+    /** Convert text to expected type **/
+    T getValueFromText(String text);
+    /** Read text from file, eventually replace variables, then convert it. Cached content depends if variabilisation is active or not. **/
+    T getValueFromFile(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache);
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/MessageRenderer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,106 @@
+/*
+ * 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 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 = new XStream();
+          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) new XStream().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) {
+        Serializable object = (Serializable) new XStream().fromXML(new File(filename));
+        return object;
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRenderer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,72 @@
+/*
+ * 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 java.io.Serializable;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Renderer singleton.
+ */
+enum RendererFactory {
+
+    INSTANCE;
+
+    public static RendererFactory getInstance() {
+        return INSTANCE;
+    }
+
+    private TextMessageRenderer   text   = new TextMessageRenderer();
+    private BinaryMessageRenderer binary = new BinaryMessageRenderer(text);
+    private ObjectMessageRenderer object = new ObjectMessageRenderer(text);
+    private MapMessageRenderer    map    = new MapMessageRenderer(text);
+
+    /** Registred renderers **/
+    private Map<Class<?>, MessageRenderer<?>> renderers;
+    {
+        Map<Class<?>, MessageRenderer<?>> writable = new LinkedHashMap<>();
+        writable.put(String.class, text);
+        writable.put(byte[].class, binary);
+        writable.put(Serializable.class, object);
+        writable.put(Map.class, map);
+        renderers = Collections.unmodifiableMap(writable);
+    }
+
+    public TextMessageRenderer getText() {
+        return text;
+    }
+
+    public BinaryMessageRenderer getBinary() {
+        return binary;
+    }
+
+    public ObjectMessageRenderer getObject() {
+        return object;
+    }
+
+    public MapMessageRenderer getMap() {
+        return map;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> MessageRenderer<T> getInstance(Class<T> type) {
+        return (MessageRenderer<T>) renderers.get(type);
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/RendererFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,47 @@
+/*
+ * 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 java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Renderer API entry point.
+ */
+public interface Renderers {
+
+    public static MessageRenderer<String> getText() {
+        return RendererFactory.getInstance().getText();
+    }
+
+    public static MessageRenderer<byte[]> getBinary() {
+        return RendererFactory.getInstance().getBinary();
+    }
+
+    public static MessageRenderer<Serializable> getObject() {
+        return RendererFactory.getInstance().getObject();
+    }
+
+    public static MessageRenderer<Map<String,Object>> getMap() {
+        return RendererFactory.getInstance().getMap();
+    }
+
+    public static <T> MessageRenderer<T> getInstance(Class<T> type) {
+        return RendererFactory.getInstance().getInstance(type);
+    }
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/Renderers.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.jmeter.engine.util.CompoundVariable;
+import org.apache.jorphan.io.TextFile;
+
+import com.github.benmanes.caffeine.cache.Cache;
+
+class TextMessageRenderer implements MessageRenderer<String> {
+
+    @Override
+    public String getValueFromText(String text) {
+        return text;
+    }
+
+    @Override
+    public String getValueFromFile(String filename, String encoding, boolean hasVariable, Cache<Object,Object> cache) {
+        String text = (String) cache.get(new FileKey(filename, encoding), key -> getContent((FileKey)key));
+        if (hasVariable) {
+            text = new CompoundVariable(text).execute();
+        }
+
+        return text;
+    }
+
+    String getContent(FileKey key) {
+        return new TextFile(key.getFilename(), key.getEncoding()).getText();
+    }
+
+
+}

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRenderer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java (added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,23 @@
+/*
+ * 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 contains all renderer for JMS publisher.
+ * @see Renderers
+ * @see MessageRenderer
+ */
+package org.apache.jmeter.protocol.jms.sampler.render;
\ No newline at end of file

Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/render/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/cp1252.txt
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/cp1252.txt?rev=1783319&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/cp1252.txt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt Thu Feb 16 23:50:00 2017
@@ -0,0 +1 @@
+noVar
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/noVar.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml Thu Feb 16 23:50:00 2017
@@ -0,0 +1 @@
+<org.apache.jmeter.protocol.jms.sampler.render.Person><name>e��</name></org.apache.jmeter.protocol.jms.sampler.render.Person>
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_cp1252.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml Thu Feb 16 23:50:00 2017
@@ -0,0 +1 @@
+<org.apache.jmeter.protocol.jms.sampler.render.Person><name>Doe</name></org.apache.jmeter.protocol.jms.sampler.render.Person>
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_doe.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml Thu Feb 16 23:50:00 2017
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<org.apache.jmeter.protocol.jms.sampler.render.Person><name>e��</name></org.apache.jmeter.protocol.jms.sampler.render.Person>
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_prolog_cp1252.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml Thu Feb 16 23:50:00 2017
@@ -0,0 +1 @@
+<org.apache.jmeter.protocol.jms.sampler.render.Person><name>eéè€</name></org.apache.jmeter.protocol.jms.sampler.render.Person>
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/object_utf8.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt (added)
+++ jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt Thu Feb 16 23:50:00 2017
@@ -0,0 +1 @@
+${oneVar}
\ No newline at end of file

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/oneVar.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/utf8.txt
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/utf8.txt?rev=1783319&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jmeter/trunk/test/resources/org/apache/jmeter/protocol/jms/sampler/render/utf8.txt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import java.util.Locale;
+
+import org.apache.jmeter.protocol.jms.control.gui.JMSPublisherGui;
+import org.apache.jmeter.util.JMeterUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.github.benmanes.caffeine.cache.Cache;
+
+/**
+ *
+ */
+public class PublisherSamplerTest {
+
+    @Before
+    public void initJMeter() {
+        JMeterUtils.setLocale(new Locale("ignoreResources"));
+    }
+
+    @After
+    public void resetJMeter() {
+        JMeterUtils.setLocale(Locale.ENGLISH);
+    }
+
+    @Test
+    public void noopCache() {
+        Cache<Object,Object> noopCache = PublisherSampler.buildCache(JMSPublisherGui.USE_RANDOM_RSC);
+        assertEquals(0, noopCache.estimatedSize());
+
+        String key  = "key";
+        String val1 = "1st time";
+        assertSame(val1, noopCache.get(key, k -> val1));
+
+        String val2 = "2nd call";
+        assertSame(val2, noopCache.get(key, k -> val2));
+    }
+}

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/PublisherSamplerTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,123 @@
+/*
+ * 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 static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class BinaryMessageRendererTest extends MessageRendererTest<byte[]> {
+
+    @Rule
+    public ExpectedException error = ExpectedException.none();
+
+    BinaryMessageRenderer render = RendererFactory.getInstance().getBinary();
+    @Override
+    protected MessageRenderer<byte[]> getRenderer() {
+        return render;
+    }
+
+    @Test(expected=UnsupportedOperationException.class)
+    public void getValueFromText() {
+        render.getValueFromText("");
+    }
+
+    @Test
+    public void readUTF8File() {
+        assertContent("utf8.txt", "UTF-8");
+    }
+
+    @Test
+    public void readCP1252File() {
+        assertContent("cp1252.txt", "Cp1252");
+    }
+
+    private void assertContent(String resource, String encoding) {
+        String filename = getResourceFile(resource);
+        byte[] actual = render.getContent(filename);
+        try {
+            assertArrayEquals("éè€".getBytes(encoding), actual);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    public void readNonExistingContent() {
+        error.expect(RuntimeException.class);
+        error.expectCause(instanceOf(IOException.class));
+        error.expectMessage("Can't read content of __file_that_may_not_exists_else_it_will_fail");
+        render.getContent("__file_that_may_not_exists_else_it_will_fail");
+    }
+
+    @Test
+    public void getValueFromFile_withNoVar() {
+        String text = format("éè€%n");
+        assertValueFromFile(text, "utf8.txt", true);
+        assertCacheContentInString(text);
+
+    }
+
+    @Test
+    public void getValueFromFile_withOneVar() {
+        String value = "éè€";
+        jmeterCtxService.get().getVariables().put("oneVar", value);
+        assertValueFromFile(format("%s%n", value), "oneVar.txt", true);
+        assertCacheContentInString(format("${oneVar}%n"));
+    }
+
+
+
+    @Test
+    public void getValueFromFile_withInvalidEncoding() {
+        error.expect(RuntimeException.class);
+        error.expectCause(instanceOf(UnsupportedEncodingException.class));
+
+        render.getValueFromFile(getResourceFile("utf8.txt"), "banana", true, cache);
+    }
+
+    @Test
+    public void getValueFromFile_inRawMode() {
+        String text = "${oneVar}";
+        assertValueFromFile(text, "oneVar.txt", false);
+        assertCacheContentInBytes(text);
+    }
+
+    protected void assertValueFromFile(String expected, String resource, boolean hasVariable) {
+        assertValueFromFile(actual -> assertBytesEquals(expected, actual), resource, hasVariable);
+    }
+
+    protected void assertCacheContentInBytes(String expected) {
+        assertBytesEquals(expected, (byte[]) cacheContent.getValue());
+    }
+    protected void assertCacheContentInString(String expected) {
+        assertEquals(expected, cacheContent.getValue());
+    }
+    protected void assertBytesEquals(String expected, byte[] actual) {
+        assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8), actual);
+    }
+}

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/BinaryMessageRendererTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,74 @@
+/*
+ * 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.util.AbstractMap;
+import java.util.Map.Entry;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.apache.jmeter.protocol.jms.sampler.cache.Cache;
+import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterContextServiceHelper;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.junit.Rule;
+
+/**
+ *
+ */
+public abstract class MessageRendererTest<T> {
+
+    @SuppressWarnings("rawtypes")
+    protected Entry cacheContent;
+    protected Cache cache = new Cache() {
+        @Override
+        public void put(Object key, Object value) {
+            cacheContent = new AbstractMap.SimpleImmutableEntry<>(key, value);
+        }
+
+        @Override
+        public <K, V> V get(K key, Function<K, V> get) {
+            V value = get.apply(key);
+            cacheContent = new AbstractMap.SimpleImmutableEntry<>(key, value);
+            return value;
+        }
+    };
+
+    @Rule
+    public JMeterContextServiceHelper jmeterCtxService = new JMeterContextServiceHelper() {
+        @Override
+        protected void initContext(JMeterContext jMeterContext) {
+            jMeterContext.setVariables(new JMeterVariables());
+        }
+    };
+
+    protected abstract MessageRenderer<T> getRenderer();
+
+    protected String getResourceFile(String resource) {
+        return format("test/resources/%s/%s", getClass().getPackage().getName().replace('.', '/'), resource);
+    }
+
+    protected void assertValueFromFile(Consumer<T> assertion, String resource, boolean hasVariable) {
+        String filename = getResourceFile(resource);
+        T actual = getRenderer().getValueFromFile(filename, "UTF-8", hasVariable, cache);
+        assertion.accept(actual);
+    }
+
+}

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/MessageRendererTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,99 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.io.Serializable;
+
+import org.apache.jmeter.protocol.jms.sampler.PublisherSampler;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class ObjectMessageRendererTest extends MessageRendererTest<Serializable> {
+
+    private ObjectMessageRenderer render = RendererFactory.getInstance().getObject();
+    @Override
+    public ObjectMessageRenderer getRenderer() {
+        return render;
+    }
+
+    @Test
+    public void getValueFromText() {
+        Serializable object = render.getValueFromText(getDoeContent());
+        assertObject(object, "Doe");
+    }
+
+   private void assertObject(Serializable object, String name) {
+        assertNotNull("object", object);
+        assertEquals("object.class", Person.class, object.getClass());
+        Person p = (Person) object;
+        assertEquals("object.name", name, p.getName());
+    }
+
+    @Test
+    public void getValueFromFile_inRawMode() {
+        assertValueFromFile(object -> {
+            assertObject(object, "Doe");
+            Person p = (Person) object;
+            assertSame("cache", p, cacheContent.getValue());
+        }, "object_doe.xml", false);
+    }
+
+    @Test
+    public void getValueFromFile_withForcedEncoding() {
+        String filename = getResourceFile("object_cp1252.xml");
+        Serializable object = getRenderer().getValueFromFile(filename, "Cp1252", true, cache);
+        assertObject(object, "eéè€");
+        assertEquals("cache", format("%s%n", getUnicodeContent()), cacheContent.getValue());
+
+    }
+
+    @Test
+    public void getValueFromFile_withDefaultEncodingAndNoProlog() {
+        String filename = getResourceFile("object_utf8.xml");
+        Serializable object = getRenderer().getValueFromFile(filename, PublisherSampler.DEFAULT_ENCODING, true, cache);
+        assertObject(object, "eéè€");
+        assertEquals("cache", format("%s%n", getUnicodeContent()), cacheContent.getValue());
+
+    }
+
+    @Test
+    public void getValueFromFile_withDefaultEncodingAndProlog() {
+        String filename = getResourceFile("object_prolog_cp1252.xml");
+        Serializable object = getRenderer().getValueFromFile(filename, PublisherSampler.DEFAULT_ENCODING, true, cache);
+        assertObject(object, "eéè€");
+        Person p = (Person) object;
+        assertEquals("object.name", "eéè€", p.getName());
+        assertEquals("cache", format("<?xml version=\"1.0\" encoding=\"Windows-1252\"?>%n%s%n", getUnicodeContent()), cacheContent.getValue());
+
+    }
+
+    private String getUnicodeContent() {
+        return "<org.apache.jmeter.protocol.jms.sampler.render.Person><name>eéè€</name></org.apache.jmeter.protocol.jms.sampler.render.Person>";
+    }
+
+    private String getDoeContent() {
+        return "<org.apache.jmeter.protocol.jms.sampler.render.Person><name>Doe</name></org.apache.jmeter.protocol.jms.sampler.render.Person>";
+    }
+}

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/ObjectMessageRendererTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,32 @@
+/*
+ * 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 java.io.Serializable;
+
+class Person implements Serializable  {
+    private static final long serialVersionUID = 1L;
+
+    private String name;
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+}
\ No newline at end of file

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/Person.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java?rev=1783319&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java Thu Feb 16 23:50:00 2017
@@ -0,0 +1,94 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+/**
+ *
+ */
+public class TextMessageRendererTest extends MessageRendererTest<String> {
+
+    private TextMessageRenderer render = RendererFactory.getInstance().getText();
+    @Override
+    protected MessageRenderer<String> getRenderer() {
+        return render;
+    }
+
+    @Test
+    public void readUTF8File() {
+        assertContent("utf8.txt", "UTF-8");
+    }
+
+    @Test
+    public void readCP1252File() {
+        assertContent("cp1252.txt", "Cp1252");
+    }
+
+    private void assertContent(String resource, String encoding) {
+        String filename = getResourceFile(resource);
+        String actual = render.getContent(new FileKey(filename, encoding));
+        assertEquals(format("éè€%n"), actual);
+    }
+
+
+    @Test
+    public void getValueFromFileWithNoVar() {
+        assertValueFromFile(format("noVar%n"), "noVar.txt", true);
+    }
+
+    @Test
+    public void getValueFromFileWithOneVar() {
+        jmeterCtxService.get().getVariables().put("oneVar", "foobar");
+        assertValueFromFile(format("foobar%n"), "oneVar.txt", true);
+    }
+
+    @Test
+    public void checkCache() {
+        jmeterCtxService.get().getVariables().put("oneVar", "foo");
+        assertValueFromFile(format("foo%n"), "oneVar.txt", true);
+        assertEquals(format("${oneVar}%n"), cacheContent.getValue());
+
+        jmeterCtxService.get().getVariables().put("oneVar", "bar");
+        assertValueFromFile(format("bar%n"), "oneVar.txt", true);
+        assertEquals(format("${oneVar}%n"), cacheContent.getValue());
+    }
+
+    @Test
+    public void checkNoVariable() {
+        jmeterCtxService.get().getVariables().put("oneVar", "RAW");
+        assertValueFromFile(format("${oneVar}%n"), "oneVar.txt", false);
+    }
+
+    @Test
+    public void getValueFromText() {
+        for (String text : Arrays.asList("a", null, "b", "")) {
+            assertSame(text, render.getValueFromText(text));
+        }
+    }
+
+    protected void assertValueFromFile(String expected, String resource, boolean hasVariable) {
+        assertValueFromFile(actual -> assertEquals(expected, actual), resource, hasVariable);
+    }
+}

Propchange: jmeter/trunk/test/src/org/apache/jmeter/protocol/jms/sampler/render/TextMessageRendererTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain