Skip to content

Commit

Permalink
Added composite conversion registry. Added map-based conversion registry
Browse files Browse the repository at this point in the history
  • Loading branch information
pkaramishev committed Mar 16, 2016
1 parent 1da854c commit 301fa08
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.excellentchoise.typeconversion.core.registry;

import io.excellentchoise.typeconversion.core.Conversion;
import io.excellentchoise.typeconversion.core.ConversionSignature;

import java.util.List;
import java.util.Optional;

/**
* Conversion registry which tries to find suitable conversion in one of the given registries.
*/
public class CompositeConversionRegistry implements ConversionRegistry {
private List<ConversionRegistry> registries;

public CompositeConversionRegistry(List<ConversionRegistry> registries) {
this.registries = registries;
}

@Override
public <Source, Result> Optional<Conversion<Source, Result>> findConversion(ConversionSignature<Source, Result> signature) {
for (ConversionRegistry registry : registries) {
Optional<Conversion<Source, Result>> possibleConversion = registry.findConversion(signature);
if (possibleConversion.isPresent()) {
return possibleConversion;
}
}

return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@
* based on some attribute of the signature or pre-configured set of conversions.
*/
public interface ConversionRegistry {
/**
* Create conversion registry which can't find any conversion.
* @return empty registry
*/
static ConversionRegistry empty() {
return new ConversionRegistry() {
@Override
public <Source, Result> Optional<Conversion<Source, Result>> findConversion(ConversionSignature<Source, Result> signature) {
return Optional.empty();
}
};
}

/**
* Seek conversion with the given signature in registry.
* @param signature conversion signature
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.excellentchoise.typeconversion.core.registry;

import io.excellentchoise.typeconversion.core.Conversion;
import io.excellentchoise.typeconversion.core.ConversionSignature;

import java.util.Map;
import java.util.Optional;

/**
* Conversion registry which performs simple lookup in map using the given signature.
*/
public class MapSearchingConversionRegistry implements ConversionRegistry {
private final Map<ConversionSignature<?, ?>, Conversion<?, ?>> conversions;

public MapSearchingConversionRegistry(Map<ConversionSignature<?, ?>, Conversion<?, ?>> conversions) {
this.conversions = conversions;
}

@Override
@SuppressWarnings("unchecked")
public <Source, Result> Optional<Conversion<Source, Result>> findConversion(ConversionSignature<Source, Result> signature) {
Conversion<Source, Result> resultConversion = (Conversion<Source, Result>) conversions.get(signature);

return Optional.ofNullable(resultConversion);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.excellentchoise.typeconversion.core.registry;

import io.excellentchoise.typeconversion.core.Conversion;
import io.excellentchoise.typeconversion.core.ConversionSignature;
import org.assertj.core.util.Lists;
import org.junit.Test;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

public class CompositeConversionRegistryTest {
@Test
public void whenAnyRegistryContainsConversionForGivenSignature_findConversion_shouldReturnNonEmptyOptional() {
ConversionSignature<Integer, String> signature = ConversionSignature.from(Integer.class, String.class);
ConversionRegistry empty = ConversionRegistry.empty();
ConversionRegistry nonEmpty = MockRegistries.returning(signature, x -> "str");
ConversionRegistry registry = new CompositeConversionRegistry(Lists.newArrayList(empty, nonEmpty));

Optional<Conversion<Integer, String>> conversion = registry.findConversion(signature);

assertThat(conversion).isPresent();
}

@Test
public void whenNoRegistryContainsConversionForGivenSignature_findConversion_shouldReturnEmptyOptional() {
ConversionSignature<Integer, String> signature = ConversionSignature.from(Integer.class, String.class);
ConversionRegistry internalRegistry = MockRegistries.returning(signature, x -> "str");
ConversionRegistry registry = new CompositeConversionRegistry(Lists.newArrayList(internalRegistry));

ConversionSignature<Thread, Integer> anotherSignature = ConversionSignature.from(Thread.class, Integer.class);
Optional<Conversion<Thread, Integer>> conversion = registry.findConversion(anotherSignature);

assertThat(conversion).isEmpty();
}

@Test
public void whenRegistryContainsMultipleConversionForGivenSignature_findConversion_shouldReturnConversionOfTheFirstRegistryInList() {
ConversionSignature<Integer, String> signature = ConversionSignature.from(Integer.class, String.class);
ConversionRegistry first = MockRegistries.returning(signature, x -> "first");
ConversionRegistry second = MockRegistries.returning(signature, x -> "second");
ConversionRegistry registry = new CompositeConversionRegistry(Lists.newArrayList(first, second));

Optional<Conversion<Integer, String>> conversion = registry.findConversion(signature);

assertThat(conversion).isPresent();
assertThat(conversion.get().convert(5)).isEqualTo("first");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.excellentchoise.typeconversion.core.registry;

import io.excellentchoise.typeconversion.core.Conversion;
import io.excellentchoise.typeconversion.core.ConversionSignature;
import org.junit.Test;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

public class MapSearchingConversionRegistryTest {
@Test
public void whenConversionExistsInMap_findConversion_shouldReturnNonEmptyOptional() {
ConversionSignature<Integer, String> signature = ConversionSignature.from(Integer.class, String.class);
Map<ConversionSignature<?, ?>, Conversion<?, ?>> map = Collections.singletonMap(signature, x -> "test");
ConversionRegistry registry = new MapSearchingConversionRegistry(map);

Optional<Conversion<Integer, String>> conversion = registry.findConversion(signature);

assertThat(conversion).isPresent();
}

@Test
public void whenConversionDoesntExistInMap_findConversion_shouldReturnEmptyOptional() {
ConversionSignature<Integer, String> signature = ConversionSignature.from(Integer.class, String.class);
Map<ConversionSignature<?, ?>, Conversion<?, ?>> map = Collections.emptyMap();
ConversionRegistry registry = new MapSearchingConversionRegistry(map);

Optional<Conversion<Integer, String>> conversion = registry.findConversion(signature);

assertThat(conversion).isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.excellentchoise.typeconversion.core.registry;

import io.excellentchoise.typeconversion.core.Conversion;
import io.excellentchoise.typeconversion.core.ConversionSignature;
import org.mockito.Mockito;

import java.util.Optional;

import static org.mockito.AdditionalMatchers.not;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MockRegistries {
@SuppressWarnings("unchecked")
public static <Source, Result> ConversionRegistry returning(
ConversionSignature<Source, Result> signature,
Conversion<Source, Result> conversion) {
ConversionRegistry registry = mock(ConversionRegistry.class);
when(registry.findConversion(eq(signature))).thenReturn(Optional.of(conversion));
when(registry.findConversion(not(eq(signature)))).thenReturn(Optional.empty());

return registry;
}
}

0 comments on commit 301fa08

Please sign in to comment.