Skip to content

Commit 8273edd

Browse files
garyrussellartembilan
authored andcommitted
INT-3779: Codec Support Part I - Transformers
JIRA: https://jira.spring.io/browse/INT-3779 MessageConverters and Docs to follow.
1 parent 09fb4f7 commit 8273edd

File tree

3 files changed

+222
-0
lines changed

3 files changed

+222
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.integration.transformer;
17+
18+
import org.springframework.expression.Expression;
19+
import org.springframework.expression.spel.support.StandardEvaluationContext;
20+
import org.springframework.integration.codec.Codec;
21+
import org.springframework.integration.context.IntegrationContextUtils;
22+
import org.springframework.messaging.Message;
23+
import org.springframework.util.Assert;
24+
25+
/**
26+
* {@link AbstractPayloadTransformer} that delegates to a codec to decode the
27+
* payload from a byte[].
28+
*
29+
* @author Gary Russell
30+
* @since 4.2
31+
*
32+
*/
33+
public class DecodingTransformer<T> extends AbstractTransformer {
34+
35+
private final Codec codec;
36+
37+
private final Class<T> type;
38+
39+
private final Expression typeExpression;
40+
41+
private volatile StandardEvaluationContext evaluationContext;
42+
43+
/**
44+
* Construct an instance to use the supplied codec to decode to the supplied type.
45+
* @param codec the codec.
46+
* @param type the type.
47+
*/
48+
public DecodingTransformer(Codec codec, Class<T> type) {
49+
Assert.notNull(codec, "'codec' cannot be null");
50+
Assert.notNull(type, "'type' cannot be null");
51+
this.codec = codec;
52+
this.type = type;
53+
this.typeExpression = null;
54+
}
55+
56+
/**
57+
* Construct an instance to use the supplied codec to decode to the supplied type.
58+
* @param codec the codec.
59+
* @param typeExpression an expression that evaluates to a {@link Class}.
60+
*/
61+
public DecodingTransformer(Codec codec, Expression typeExpression) {
62+
Assert.notNull(codec, "'codec' cannot be null");
63+
Assert.notNull(typeExpression, "'typeExpression' cannot be null");
64+
this.codec = codec;
65+
this.type = null;
66+
this.typeExpression = typeExpression;
67+
}
68+
69+
public void setEvaluationContext(StandardEvaluationContext evaluationContext) {
70+
this.evaluationContext = evaluationContext;
71+
}
72+
73+
@Override
74+
protected void onInit() throws Exception {
75+
if (this.evaluationContext == null) {
76+
this.evaluationContext = IntegrationContextUtils.getEvaluationContext(getBeanFactory());
77+
}
78+
}
79+
80+
@Override
81+
protected T doTransform(Message<?> message) throws Exception {
82+
Assert.isTrue(message.getPayload() instanceof byte[], "Message payload must be byte[]");
83+
byte[] bytes = (byte[]) message.getPayload();
84+
return codec.decode(bytes, this.type != null ? this.type : type(message));
85+
}
86+
87+
@SuppressWarnings("unchecked")
88+
private Class<T> type(Message<?> message) {
89+
Assert.state(this.evaluationContext != null, "EvaluationContext required");
90+
return this.typeExpression.getValue(this.evaluationContext, message, Class.class);
91+
}
92+
93+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.integration.transformer;
17+
18+
import org.springframework.integration.codec.Codec;
19+
import org.springframework.util.Assert;
20+
21+
/**
22+
* {@link AbstractPayloadTransformer} that delegates to a codec to encode the
23+
* payload into a byte[].
24+
*
25+
* @author Gary Russell
26+
* @since 4.2
27+
*
28+
*/
29+
public class EncodingPayloadTransformer<T> extends AbstractPayloadTransformer<T, byte[]> {
30+
31+
private final Codec codec;
32+
33+
public EncodingPayloadTransformer(Codec codec) {
34+
Assert.notNull(codec, "'codec' cannot be null");
35+
this.codec = codec;
36+
}
37+
38+
@Override
39+
protected byte[] transformPayload(T payload) throws Exception {
40+
return codec.encode(payload);
41+
}
42+
43+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.integration.transformer;
17+
18+
import static org.junit.Assert.assertArrayEquals;
19+
import static org.junit.Assert.assertEquals;
20+
21+
import java.io.IOException;
22+
import java.io.InputStream;
23+
import java.io.OutputStream;
24+
import java.util.Collections;
25+
26+
import org.junit.Test;
27+
28+
import org.springframework.expression.spel.standard.SpelExpressionParser;
29+
import org.springframework.expression.spel.support.StandardEvaluationContext;
30+
import org.springframework.integration.codec.Codec;
31+
import org.springframework.messaging.Message;
32+
import org.springframework.messaging.support.GenericMessage;
33+
34+
/**
35+
* @author Gary Russell
36+
* @since 4.2
37+
*
38+
*/
39+
public class CodecTransformerTests {
40+
41+
@Test
42+
public void testCodec() throws Exception {
43+
MyCodec codec = new MyCodec();
44+
EncodingPayloadTransformer<String> enc = new EncodingPayloadTransformer<String>(codec);
45+
Message<?> message = new GenericMessage<String>("bar");
46+
byte[] transformed = enc.doTransform(message);
47+
assertArrayEquals("foo".getBytes(), transformed);
48+
DecodingTransformer<?> dec = new DecodingTransformer<String>(codec, String.class);
49+
assertEquals("foo", dec.doTransform(new GenericMessage<byte[]>(transformed)));
50+
51+
dec = new DecodingTransformer<Integer>(codec, new SpelExpressionParser().parseExpression("T(Integer)"));
52+
dec.setEvaluationContext(new StandardEvaluationContext());
53+
assertEquals(42, dec.doTransform(new GenericMessage<byte[]>(transformed)));
54+
55+
dec = new DecodingTransformer<Integer>(codec, new SpelExpressionParser().parseExpression("headers['type']"));
56+
dec.setEvaluationContext(new StandardEvaluationContext());
57+
assertEquals(42, dec.doTransform(new GenericMessage<byte[]>(transformed,
58+
Collections.singletonMap("type", Integer.class))));
59+
}
60+
61+
public static class MyCodec implements Codec {
62+
63+
@Override
64+
public void encode(Object object, OutputStream outputStream) throws IOException {
65+
}
66+
67+
@Override
68+
public byte[] encode(Object object) throws IOException {
69+
return "foo".getBytes();
70+
}
71+
72+
@Override
73+
public <T> T decode(InputStream inputStream, Class<T> type) throws IOException {
74+
return null;
75+
}
76+
77+
@SuppressWarnings("unchecked")
78+
@Override
79+
public <T> T decode(byte[] bytes, Class<T> type) throws IOException {
80+
return (T) (type.equals(String.class) ? new String(bytes) :
81+
type.equals(Integer.class) ? Integer.valueOf(42) : Integer.valueOf(43));
82+
}
83+
84+
}
85+
86+
}

0 commit comments

Comments
 (0)