Browse Source
Add ByteBufferConverter that is registered by default with the DefaultConversionService. Allows conversion from/to a ByteBuffer and byte[] or to any type that can be converted via a byte[]. Issue: SPR-10712pull/308/head
3 changed files with 229 additions and 0 deletions
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
/* |
||||
* Copyright 2002-2013 the original author or authors. |
||||
* |
||||
* Licensed 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.springframework.core.convert.support; |
||||
|
||||
import java.nio.ByteBuffer; |
||||
import java.util.Collections; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.TypeDescriptor; |
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter; |
||||
|
||||
/** |
||||
* Converts a {@link ByteBuffer} directly to and from {@code byte[]}s and indirectly to |
||||
* any type that the {@link ConversionService} support via {@code byte[]}. |
||||
* |
||||
* @author Phillip Webb |
||||
*/ |
||||
public class ByteBufferConverter implements ConditionalGenericConverter { |
||||
|
||||
private static final TypeDescriptor BYTE_BUFFER_TYPE = TypeDescriptor.valueOf(ByteBuffer.class); |
||||
|
||||
private static final TypeDescriptor BYTE_ARRAY_TYPE = TypeDescriptor.valueOf(byte[].class); |
||||
|
||||
private static final Set<ConvertiblePair> CONVERTIBLE_PAIRS; |
||||
static { |
||||
Set<ConvertiblePair> convertiblePairs = new HashSet<ConvertiblePair>(); |
||||
convertiblePairs.add(new ConvertiblePair(ByteBuffer.class, Object.class)); |
||||
convertiblePairs.add(new ConvertiblePair(Object.class, ByteBuffer.class)); |
||||
CONVERTIBLE_PAIRS = Collections.unmodifiableSet(convertiblePairs); |
||||
} |
||||
|
||||
|
||||
private ConversionService conversionService; |
||||
|
||||
|
||||
public ByteBufferConverter(ConversionService conversionService) { |
||||
this.conversionService = conversionService; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Set<ConvertiblePair> getConvertibleTypes() { |
||||
return CONVERTIBLE_PAIRS; |
||||
} |
||||
|
||||
@Override |
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
||||
if (sourceType.isAssignableTo(BYTE_BUFFER_TYPE)) { |
||||
return matchesFromByteBuffer(targetType); |
||||
} |
||||
if (targetType.isAssignableTo(BYTE_BUFFER_TYPE)) { |
||||
return matchesToByteBuffer(sourceType); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private boolean matchesFromByteBuffer(TypeDescriptor targetType) { |
||||
return (targetType.isAssignableTo(BYTE_ARRAY_TYPE) || this.conversionService.canConvert( |
||||
BYTE_ARRAY_TYPE, targetType)); |
||||
} |
||||
|
||||
private boolean matchesToByteBuffer(TypeDescriptor sourceType) { |
||||
return (sourceType.isAssignableTo(BYTE_ARRAY_TYPE) || this.conversionService.canConvert( |
||||
sourceType, BYTE_ARRAY_TYPE)); |
||||
} |
||||
|
||||
@Override |
||||
public Object convert(Object source, TypeDescriptor sourceType, |
||||
TypeDescriptor targetType) { |
||||
if (sourceType.isAssignableTo(BYTE_BUFFER_TYPE)) { |
||||
return convertFromByteBuffer((ByteBuffer) source, targetType); |
||||
} |
||||
if (targetType.isAssignableTo(BYTE_BUFFER_TYPE)) { |
||||
return convertToByteBuffer(source, sourceType); |
||||
} |
||||
// Should not happen
|
||||
throw new IllegalStateException("Unexpected source/target types"); |
||||
} |
||||
|
||||
private Object convertFromByteBuffer(ByteBuffer source, TypeDescriptor targetType) { |
||||
byte[] bytes = new byte[source.remaining()]; |
||||
source.get(bytes); |
||||
if (targetType.isAssignableTo(BYTE_ARRAY_TYPE)) { |
||||
return bytes; |
||||
} |
||||
return this.conversionService.convert(bytes, BYTE_ARRAY_TYPE, targetType); |
||||
} |
||||
|
||||
private Object convertToByteBuffer(Object source, TypeDescriptor sourceType) { |
||||
byte[] bytes = (byte[]) (source instanceof byte[] ? source |
||||
: this.conversionService.convert(source, sourceType, BYTE_ARRAY_TYPE)); |
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); |
||||
byteBuffer.put(bytes); |
||||
byteBuffer.rewind(); |
||||
return byteBuffer; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
/* |
||||
* Copyright 2002-2013 the original author or authors. |
||||
* |
||||
* Licensed 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.springframework.core.convert.support; |
||||
|
||||
import java.nio.ByteBuffer; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.core.convert.converter.Converter; |
||||
|
||||
import static org.hamcrest.Matchers.*; |
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* Tests for {@link ByteBufferConverter}. |
||||
* |
||||
* @author Phillip Webb |
||||
*/ |
||||
public class ByteBufferConverterTests { |
||||
|
||||
private GenericConversionService conversionService; |
||||
|
||||
@Before |
||||
public void setup() { |
||||
this.conversionService = new GenericConversionService(); |
||||
this.conversionService.addConverter(new ByteBufferConverter(conversionService)); |
||||
this.conversionService.addConverter(new ByteArrayToOtherTypeConverter()); |
||||
this.conversionService.addConverter(new OtherTypeToByteArrayConverter()); |
||||
} |
||||
|
||||
@Test |
||||
public void byteArrayToByteBuffer() throws Exception { |
||||
byte[] bytes = new byte[] { 1, 2, 3 }; |
||||
ByteBuffer convert = this.conversionService.convert(bytes, ByteBuffer.class); |
||||
assertThat(bytes, not(sameInstance(convert.array()))); |
||||
assertThat(bytes, equalTo(convert.array())); |
||||
} |
||||
|
||||
@Test |
||||
public void byteBufferToByteArray() throws Exception { |
||||
byte[] bytes = new byte[] { 1, 2, 3 }; |
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); |
||||
byte[] convert = this.conversionService.convert(byteBuffer, byte[].class); |
||||
assertThat(bytes, not(sameInstance(convert))); |
||||
assertThat(bytes, equalTo(convert)); |
||||
} |
||||
|
||||
@Test |
||||
public void byteBufferToOtherType() throws Exception { |
||||
byte[] bytes = new byte[] { 1, 2, 3 }; |
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); |
||||
OtherType convert = this.conversionService.convert(byteBuffer, OtherType.class); |
||||
assertThat(bytes, not(sameInstance(convert.bytes))); |
||||
assertThat(bytes, equalTo(convert.bytes)); |
||||
} |
||||
|
||||
@Test |
||||
public void otherTypeToByteBuffer() throws Exception { |
||||
byte[] bytes = new byte[] { 1, 2, 3 }; |
||||
OtherType otherType = new OtherType(bytes); |
||||
ByteBuffer convert = this.conversionService.convert(otherType, ByteBuffer.class); |
||||
assertThat(bytes, not(sameInstance(convert.array()))); |
||||
assertThat(bytes, equalTo(convert.array())); |
||||
} |
||||
|
||||
private static class OtherType { |
||||
|
||||
private byte[] bytes; |
||||
|
||||
public OtherType(byte[] bytes) { |
||||
this.bytes = bytes; |
||||
} |
||||
|
||||
} |
||||
|
||||
private static class ByteArrayToOtherTypeConverter implements |
||||
Converter<byte[], OtherType> { |
||||
|
||||
@Override |
||||
public OtherType convert(byte[] source) { |
||||
return new OtherType(source); |
||||
} |
||||
} |
||||
|
||||
private static class OtherTypeToByteArrayConverter implements |
||||
Converter<OtherType, byte[]> { |
||||
|
||||
@Override |
||||
public byte[] convert(OtherType source) { |
||||
return source.bytes; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue