@Override @SuppressWarnings("unchecked") public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) { final Class<?> erasedType = GenericTypes.getErasedType(type); if (erasedType.isArray()) { Class<?> elementType = erasedType.getComponentType(); return elementTypeMapper(elementType, config) .map(elementMapper -> new ArrayColumnMapper(elementMapper, elementType)); } JdbiCollectors collectorRegistry = config.get(JdbiCollectors.class); return (Optional) collectorRegistry.findFor(type) .flatMap(collector -> collectorRegistry.findElementTypeFor(type) .flatMap(elementType -> elementTypeMapper(elementType, config)) .map(elementMapper -> new CollectorColumnMapper(elementMapper, collector))); }
public JdbiCollectors() { // TODO move to BuiltInSupportPlugin register(new MapCollectorFactory()); register(new OptionalCollectorFactory()); register(new ListCollectorFactory()); register(new SetCollectorFactory()); register(new OptionalPrimitiveCollectorFactory()); register(new ArrayCollectorFactory()); register(new EnumSetCollectorFactory()); }
@Override public JdbiCollectors createCopy() { return new JdbiCollectors(this); } }
/** * Obtain a collector for the given type. * * @param containerType the container type. * @return a Collector for the given container type, or empty null if no collector is registered for the given type. */ public Optional<Collector<?, ?, ?>> findCollectorFor(Type containerType) { return getConfig(JdbiCollectors.class).findFor(containerType); }
/** * Returns the element type for the given container type. * * @param containerType the container type. * @return the element type for the given container type, if available. */ public Optional<Type> findElementTypeFor(Type containerType) { return getConfig(JdbiCollectors.class).findElementTypeFor(containerType); }
/** * Obtain a collector for the given type. * * @param containerType the container type. * @return a Collector for the given container type, or empty null if no collector is registered for the given type. */ public Optional<Collector<?, ?, ?>> findFor(Type containerType) { return findFactoryFor(containerType) .map(f -> f.build(containerType)); }
/** * Obtain a collector for the given type. * * @param containerType the container type. * @return a Collector for the given container type, or empty null if no collector is registered for the given type. */ public Optional<Collector<?,?,?>> findCollectorFor(Type containerType) { return getConfig(JdbiCollectors.class).findFor(containerType); }
/** * Returns the element type for the given container type. * * @param containerType the container type. * @return the element type for the given container type, if available. */ public Optional<Type> findElementTypeFor(Type containerType) { return getConfig(JdbiCollectors.class).findElementTypeFor(containerType); }
/** * Returns the element type for the given container type. * * @param containerType the container type. * @return the element type for the given container type, if available. */ public Optional<Type> findElementTypeFor(Type containerType) { return findFactoryFor(containerType) .flatMap(f -> f.elementType(containerType)); }
@SuppressWarnings("unchecked") private <M extends Map<Long, String>> void testMapCollector(Class<? extends Map> erasedType, GenericType<M> genericType) { JdbiCollectors registry = dbRule.getJdbi().getConfig(JdbiCollectors.class); assertThat(registry.findElementTypeFor(genericType.getType())) .contains(new GenericType<Map.Entry<Long, String>>(){}.getType()); Collector<Map.Entry<Long, String>, ?, M> collector = (Collector<Map.Entry<Long, String>, ?, M>) registry .findFor(genericType.getType()) .orElseThrow(() -> new IllegalStateException("Missing collector for " + genericType)); M map = Stream.of(entry(1L, "foo"), entry(2L, "bar")).collect(collector); assertThat(map) .isInstanceOf(erasedType) .containsExactly(entry(1L, "foo"), entry(2L, "bar")); }
/** * Convenience method for {@code getConfig(JdbiCollectors.class).register(factory)} * * @param factory collector factory * @return this */ default This registerCollector(CollectorFactory factory) { return configure(JdbiCollectors.class, c -> c.register(factory)); }
/** * Obtain a collector for the given type. * * @param containerType the container type. * @return a Collector for the given container type, or empty null if no collector is registered for the given type. */ public Optional<Collector<?, ?, ?>> findFor(Type containerType) { return findFactoryFor(containerType) .map(f -> f.build(containerType)); }
@Override public JdbiCollectors createCopy() { return new JdbiCollectors(this); } }
@SuppressWarnings("unchecked") private <M extends Multimap<Long, String>> void testMultimapCollector(Class<? extends Multimap> erasedType, GenericType<M> genericType) { JdbiCollectors registry = dbRule.getJdbi().getConfig(JdbiCollectors.class); assertThat(registry.findElementTypeFor(genericType.getType())) .contains(new GenericType<Map.Entry<Long, String>>(){}.getType()); Collector<Map.Entry<Long, String>, ?, M> collector = (Collector<Map.Entry<Long, String>, ?, M>) registry .findFor(genericType.getType()) .orElseThrow(() -> new IllegalStateException("Missing collector for " + genericType)); M map = Stream.of(entry(1L, "foo"), entry(2L, "bar")).collect(collector); assertThat(map) .isInstanceOf(erasedType) .containsAllEntriesOf(ImmutableMultimap.of(1L, "foo", 2L, "bar")); } }
@Override public void configureForType(ConfigRegistry registry, Annotation annotation, Class<?> sqlObjectType) { RegisterCollectorFactory registerCollectorFactory = (RegisterCollectorFactory) annotation; JdbiCollectors collectors = registry.get(JdbiCollectors.class); Class<? extends CollectorFactory> type = registerCollectorFactory.value(); try { collectors.register(type.newInstance()); } catch (InstantiationException | IllegalAccessException e) { throw new IllegalStateException("Unable to instantiate container factory", e); } } }
/** * Returns the element type for the given container type. * * @param containerType the container type. * @return the element type for the given container type, if available. */ public Optional<Type> findElementTypeFor(Type containerType) { return findFactoryFor(containerType) .flatMap(f -> f.elementType(containerType)); }
@SuppressWarnings("unchecked") private <M extends Multimap<Long, String>> void testMultimapCollector(Class<? extends Multimap> erasedType, GenericType<M> genericType) { JdbiCollectors registry = dbRule.getJdbi().getConfig(JdbiCollectors.class); assertThat(registry.findElementTypeFor(genericType.getType())) .contains(new GenericType<Map.Entry<Long, String>>(){}.getType()); Collector<Map.Entry<Long, String>, ?, M> collector = (Collector<Map.Entry<Long, String>, ?, M>) registry .findFor(genericType.getType()) .orElseThrow(() -> new IllegalStateException("Missing collector for " + genericType)); M map = Stream.of(entry(1L, "foo"), entry(2L, "bar")).collect(collector); assertThat(map) .isInstanceOf(erasedType) .containsAllEntriesOf(ImmutableMultimap.of(1L, "foo", 2L, "bar")); } }
/** * Convenience method for {@code getConfig(JdbiCollectors.class).register(factory)} * * @param factory collector factory * @return this */ default This registerCollector(CollectorFactory factory) { return configure(JdbiCollectors.class, c -> c.register(factory)); }
@SuppressWarnings("unchecked") private <M extends Map<Long, String>> void testMapCollector(Class<? extends Map> erasedType, GenericType<M> genericType) { JdbiCollectors registry = dbRule.getJdbi().getConfig(JdbiCollectors.class); assertThat(registry.findElementTypeFor(genericType.getType())) .contains(new GenericType<Map.Entry<Long, String>>(){}.getType()); Collector<Map.Entry<Long, String>, ?, M> collector = (Collector<Map.Entry<Long, String>, ?, M>) registry .findFor(genericType.getType()) .orElseThrow(() -> new IllegalStateException("Missing collector for " + genericType)); M map = Stream.of(entry(1L, "foo"), entry(2L, "bar")).collect(collector); assertThat(map) .isInstanceOf(erasedType) .containsExactly(entry(1L, "foo"), entry(2L, "bar")); }