Skip to content
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

Add abstract delegate converter class #366

Merged
merged 2 commits into from
Nov 13, 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
29 changes: 29 additions & 0 deletions src/main/java/org/scijava/convert/AbstractDelegateConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

package org.scijava.convert;

import org.scijava.plugin.Parameter;

/**
* Abstract superclass for {@link Converter} plugins that delegate to other
* converters to chain two conversion steps together.
*
* @author Jan Eglinger
* @param <I> the input type
* @param <D> the delegate type
* @param <O> the output type
*/
public abstract class AbstractDelegateConverter<I, D, O> extends
AbstractConverter<I, O>
{

@Parameter
private ConvertService convertService;

@Override
public <T> T convert(Object src, Class<T> dest) {
D delegate = convertService.convert(src, getDelegateType());
return convertService.convert(delegate, dest);
}

protected abstract Class<D> getDelegateType();
}
118 changes: 118 additions & 0 deletions src/test/java/org/scijava/convert/DelegateConverterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.scijava.convert;

import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.scijava.Context;
import org.scijava.plugin.Plugin;


public class DelegateConverterTest {
private Context context;

@Before
public void setUp() {
context = new Context();
}

@After
public void tearDown() {
context.dispose();
context = null;
}

@Test
public void testDelegateConverters() {
ConvertService convertService = context.getService(ConvertService.class);

// Test conversion from AType to BType
AType a = new AType();
assertTrue(convertService.supports(a, BType.class));
BType b = convertService.convert(a, BType.class);
assertSame(BType.class, b.getClass());

// Test conversion from BType to CType
assertTrue(convertService.supports(b, CType.class));
CType c = convertService.convert(b, CType.class);
assertSame(CType.class, c.getClass());

// Test chained conversion
assertTrue(convertService.supports(a, CType.class));
CType converted = convertService.convert(a, CType.class);
assertSame(c.getClass(), converted.getClass());
}

public static class AType {
// empty class
}

public static class BType {
// empty class
}

public static class CType {
// empty class
}

@Plugin(type=Converter.class)
public static class ABConverter extends AbstractConverter<AType, BType> {

@SuppressWarnings("unchecked")
@Override
public <T> T convert(Object src, Class<T> dest) {
return (T) new BType();
}

@Override
public Class<BType> getOutputType() {
return BType.class;
}

@Override
public Class<AType> getInputType() {
return AType.class;
}
}

@Plugin(type=Converter.class)
public static class BCConverter extends AbstractConverter<BType, CType> {

@SuppressWarnings("unchecked")
@Override
public <T> T convert(Object src, Class<T> dest) {
return (T) new CType();
}

@Override
public Class<CType> getOutputType() {
return CType.class;
}

@Override
public Class<BType> getInputType() {
return BType.class;
}
}

@Plugin(type=Converter.class)
public static class DelegateConverter extends AbstractDelegateConverter<AType, BType, CType> {

@Override
public Class<CType> getOutputType() {
return CType.class;
}

@Override
public Class<AType> getInputType() {
return AType.class;
}

@Override
protected Class<BType> getDelegateType() {
return BType.class;
}
}
}