/* * 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; } }