Skip to content

INT-3494: Resolve dir for writing as a Resource #3109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.springframework.integration.expression;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand All @@ -25,6 +27,7 @@
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.io.Resource;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
Expand All @@ -39,6 +42,7 @@
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;

/**
* Utility class with static methods for helping with evaluation of SpEL expressions.
Expand All @@ -53,7 +57,7 @@ public final class ExpressionUtils {

private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();

private static final Log logger = LogFactory.getLog(ExpressionUtils.class);
private static final Log LOGGER = LogFactory.getLog(ExpressionUtils.class);

private ExpressionUtils() {
super();
Expand Down Expand Up @@ -84,7 +88,7 @@ public static SimpleEvaluationContext createSimpleEvaluationContext() {
*/
public static StandardEvaluationContext createStandardEvaluationContext(@Nullable BeanFactory beanFactory) {
if (beanFactory == null) {
logger.warn("Creating EvaluationContext with no beanFactory", new RuntimeException("No beanFactory"));
LOGGER.warn("Creating EvaluationContext with no beanFactory", new RuntimeException("No beanFactory"));
}
return (StandardEvaluationContext) doCreateContext(beanFactory, false);
}
Expand All @@ -98,7 +102,7 @@ public static StandardEvaluationContext createStandardEvaluationContext(@Nullabl
*/
public static SimpleEvaluationContext createSimpleEvaluationContext(@Nullable BeanFactory beanFactory) {
if (beanFactory == null) {
logger.warn("Creating EvaluationContext with no beanFactory", new RuntimeException("No beanFactory"));
LOGGER.warn("Creating EvaluationContext with no beanFactory", new RuntimeException("No beanFactory"));
}
return (SimpleEvaluationContext) doCreateContext(beanFactory, true);
}
Expand Down Expand Up @@ -161,36 +165,56 @@ private static EvaluationContext createEvaluationContext(@Nullable ConversionSer
* @param expression the expression.
* @param evaluationContext the evaluation context.
* @param message the message (if available).
* @param name the name of the result of the evaluation.
* @param propertyName the property name the expression is evaluated for.
* @return the File.
* @since 5.0
*/
public static File expressionToFile(Expression expression, EvaluationContext evaluationContext,
@Nullable Message<?> message, String name) {

File file;
Object value = message == null
? expression.getValue(evaluationContext)
: expression.getValue(evaluationContext, message);
if (value == null) {
throw new IllegalStateException(String.format("The provided %s expression (%s) must not evaluate to null.",
name, expression.getExpressionString()));
}
else if (value instanceof File) {
file = (File) value;
@Nullable Message<?> message, String propertyName) {

Object value =
message == null
? expression.getValue(evaluationContext)
: expression.getValue(evaluationContext, message);

Assert.state(value != null, () ->
String.format("The provided %s expression (%s) must not evaluate to null.",
propertyName, expression.getExpressionString()));

if (value instanceof File) {
return (File) value;
}
else if (value instanceof String) {
String path = (String) value;
Assert.hasText(path, String.format("Unable to resolve %s for the provided Expression '%s'.", name,
Assert.hasText(path, String.format("Unable to resolve %s for the provided Expression '%s'.", propertyName,
expression.getExpressionString()));
file = new File(path);
try {
return ResourceUtils.getFile(path);
}
catch (FileNotFoundException ex) {
throw new IllegalStateException(
String.format("Unable to resolve %s for the provided Expression '%s'.",
propertyName, expression.getExpressionString()),
ex);
}
}
else if (value instanceof Resource) {
try {
return ((Resource) value).getFile();
}
catch (IOException ex) {
throw new IllegalStateException(
String.format("Unable to resolve %s for the provided Expression '%s'.",
propertyName, expression.getExpressionString()),
ex);
}
}
else {
throw new IllegalStateException(String.format(
"The provided %s expression (%s) must evaluate to type java.io.File or String, not %s.", name,
"The provided %s expression (%s) must evaluate to type java.io.File, String " +
"or org.springframework.core.io.Resource, not %s.", propertyName,
expression.getExpressionString(), value.getClass().getName()));
}
return file;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<si:header-enricher>
<si:header name="#{T(org.springframework.integration.file.FileHeaders).FILENAME}" value="${test.file}"/>
</si:header-enricher>
<file:outbound-channel-adapter id="file-outbound-channel-adapter-within-chain" directory="${work.dir}"/>
<file:outbound-channel-adapter id="file-outbound-channel-adapter-within-chain" directory-expression="${work.dir}"/>
</si:chain>

<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,69 +22,47 @@
import java.io.IOException;
import java.util.Properties;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.util.FileCopyUtils;

/**
* //INT-2275
*
* @author Artem Bilan
* @author Gary Russell
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig
public class FileOutboundChannelAdapterInsideChainTests {

public static final String TEST_FILE_NAME = FileOutboundChannelAdapterInsideChainTests.class.getSimpleName();
static final String TEST_FILE_NAME = FileOutboundChannelAdapterInsideChainTests.class.getSimpleName();

public static final String WORK_DIR_NAME = System.getProperty("java.io.tmpdir") + "/" + FileOutboundChannelAdapterInsideChainTests.class.getSimpleName() + "Dir";
static final String SAMPLE_CONTENT = "test";

public static final String SAMPLE_CONTENT = "test";
@TempDir
static File WORK_DIR;

public static Properties placeholderProperties = new Properties();

static {
placeholderProperties.put("test.file", TEST_FILE_NAME);
placeholderProperties.put("work.dir", WORK_DIR_NAME);
}

@Autowired
private MessageChannel outboundChainChannel;

private static File workDir;

@BeforeClass
public static void setupClass() {
workDir = new File(WORK_DIR_NAME);
workDir.mkdir();
workDir.deleteOnExit();
}

@AfterClass
public static void cleanUp() {
if (workDir != null && workDir.exists()) {
for (File file : workDir.listFiles()) {
file.delete();
}
}
workDir.delete();
@BeforeAll
static void setupClass() {
placeholderProperties.put("test.file", TEST_FILE_NAME);
placeholderProperties.put("work.dir", "'file://" + WORK_DIR.getAbsolutePath() + '\'');
}

@Test //INT-2275
public void testFileOutboundChannelAdapterWithinChain() throws IOException {
@Test
void testFileOutboundChannelAdapterWithinChain() throws IOException {
Message<String> message = MessageBuilder.withPayload(SAMPLE_CONTENT).build();
outboundChainChannel.send(message);
File testFile = new File(workDir, TEST_FILE_NAME);
File testFile = new File(WORK_DIR, TEST_FILE_NAME);
assertThat(testFile.exists()).isTrue();
byte[] testFileContent = FileCopyUtils.copyToByteArray(testFile);
assertThat(SAMPLE_CONTENT).isEqualTo(new String(testFileContent));
Expand Down
Loading