ExtensionAdderProvidersTest.java
/**
* Copyright (c) 2020, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.commons.extensions;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.Test;
import com.google.auto.service.AutoService;
import com.powsybl.commons.PowsyblException;
class ExtensionAdderProvidersTest {
private interface SimpleExtendable extends Extendable<SimpleExtendable> {
}
private static class SimpleExtendableImpl2
extends AbstractExtendable<SimpleExtendable> implements SimpleExtendable {
@Override
public String getImplementationName() {
return "Custom";
}
}
private interface SimpleExtension extends Extension<SimpleExtendable> {
String NAME = "SimpleExtension";
default String getName() {
return NAME;
}
}
private static class SimpleExtensionImpl extends AbstractExtension<SimpleExtendable>
implements SimpleExtension {
}
private static class SimpleExtensionImpl2 extends AbstractExtension<SimpleExtendable>
implements SimpleExtension {
}
private interface SimpleExtensionAdder extends ExtensionAdder<SimpleExtendable, SimpleExtension> {
default Class<SimpleExtension> getExtensionClass() {
return SimpleExtension.class;
}
}
private static class SimpleExtensionAdderImpl
extends AbstractExtensionAdder<SimpleExtendable, SimpleExtension>
implements SimpleExtensionAdder {
protected SimpleExtensionAdderImpl(SimpleExtendable extendable) {
super(extendable);
}
@Override
protected SimpleExtensionImpl createExtension(SimpleExtendable extendable) {
return new SimpleExtensionImpl();
}
}
private static class SimpleExtensionAdderImpl2
extends AbstractExtensionAdder<SimpleExtendable, SimpleExtension>
implements SimpleExtensionAdder {
protected SimpleExtensionAdderImpl2(SimpleExtendable extendable) {
super(extendable);
}
@Override
protected SimpleExtensionImpl2 createExtension(SimpleExtendable extendable) {
return new SimpleExtensionImpl2();
}
}
private static class SimpleExtensionAdderImplProvider
implements
ExtensionAdderProvider<SimpleExtendable, SimpleExtension, SimpleExtensionAdderImpl> {
@Override
public String getImplementationName() {
return "Default";
}
@Override
public String getExtensionName() {
return SimpleExtension.NAME;
}
@Override
public Class<SimpleExtensionAdderImpl> getAdderClass() {
return SimpleExtensionAdderImpl.class;
}
@Override
public SimpleExtensionAdderImpl newAdder(SimpleExtendable extendable) {
return new SimpleExtensionAdderImpl(extendable);
}
}
@AutoService(ExtensionAdderProvider.class)
public static class SimpleExtensionAdderImpl2Provider implements
ExtensionAdderProvider<SimpleExtendable, SimpleExtension, SimpleExtensionAdderImpl2> {
@Override
public String getImplementationName() {
return "Custom";
}
@Override
public String getExtensionName() {
return SimpleExtension.NAME;
}
@Override
public Class<SimpleExtensionAdderImpl2> getAdderClass() {
return SimpleExtensionAdderImpl2.class;
}
@Override
public SimpleExtensionAdderImpl2 newAdder(SimpleExtendable extendable) {
return new SimpleExtensionAdderImpl2(extendable);
}
}
private interface GenericExtendable<G extends GenericExtendable<G>> extends Extendable<G> {
}
private static class GenericExtendableImpl2<G extends GenericExtendable<G>>
extends AbstractExtendable<G> implements GenericExtendable<G> {
@Override
public String getImplementationName() {
return "Custom";
}
}
private interface SpecificExtendable extends GenericExtendable<SpecificExtendable> {
}
private static class SpecificExtendableImpl2
extends AbstractExtendable<SpecificExtendable>
implements SpecificExtendable {
@Override
public String getImplementationName() {
return "Custom";
}
}
private interface GenericExtension<G extends GenericExtendable<G>> extends Extension<G> {
String NAME = "SimpleExtension";
default String getName() {
return NAME;
}
}
private static class GenericExtensionImpl<G extends GenericExtendable<G>>
extends AbstractExtension<G>
implements GenericExtension<G> {
}
private static class GenericExtensionImpl2<G extends GenericExtendable<G>>
extends AbstractExtension<G>
implements GenericExtension<G> {
}
private interface GenericExtensionAdder<G extends GenericExtendable<G>> extends ExtensionAdder<G, GenericExtension<G>> {
default Class<GenericExtension> getExtensionClass() {
return GenericExtension.class;
}
}
private static class GenericExtensionAdderImpl<G extends GenericExtendable<G>>
extends AbstractExtensionAdder<G, GenericExtension<G>>
implements GenericExtensionAdder<G> {
protected GenericExtensionAdderImpl(G extendable) {
super(extendable);
}
@Override
protected GenericExtensionImpl<G> createExtension(G genericExtendable) {
return new GenericExtensionImpl<>();
}
}
private static class GenericExtensionAdderImpl2<G extends GenericExtendable<G>>
extends AbstractExtensionAdder<G, GenericExtension<G>>
implements GenericExtensionAdder<G> {
protected GenericExtensionAdderImpl2(G extendable) {
super(extendable);
}
@Override
protected GenericExtensionImpl2<G> createExtension(G genericExtendable) {
return new GenericExtensionImpl2<>();
}
}
private static class GenericExtensionAdderImplProvider<G extends GenericExtendable<G>>
implements
ExtensionAdderProvider<G, GenericExtension<G>, GenericExtensionAdderImpl<G>> {
@Override
public String getImplementationName() {
return "Default";
}
@Override
public String getExtensionName() {
return GenericExtension.NAME;
}
@Override
public Class<GenericExtensionAdderImpl> getAdderClass() {
return GenericExtensionAdderImpl.class;
}
@Override
public GenericExtensionAdderImpl<G> newAdder(G extendable) {
return new GenericExtensionAdderImpl<>(extendable);
}
}
@AutoService(ExtensionAdderProvider.class)
public static class GenericExtensionAdderImpl2Provider<G extends GenericExtendable<G>>
implements
ExtensionAdderProvider<G, GenericExtension<G>, GenericExtensionAdderImpl2<G>> {
@Override
public String getImplementationName() {
return "Custom";
}
@Override
public String getExtensionName() {
return GenericExtension.NAME;
}
@Override
public Class<GenericExtensionAdderImpl2> getAdderClass() {
return GenericExtensionAdderImpl2.class;
}
@Override
public GenericExtensionAdderImpl2<G> newAdder(G extendable) {
return new GenericExtensionAdderImpl2<>(extendable);
}
}
@Test
void test() {
List<ExtensionAdderProvider> listProviders = Arrays.asList(
new SimpleExtensionAdderImplProvider(),
new SimpleExtensionAdderImpl2Provider(),
new GenericExtensionAdderImplProvider(),
new GenericExtensionAdderImpl2Provider());
ConcurrentMap<Pair<String, Class>, ExtensionAdderProvider> cache = new ConcurrentHashMap<>();
ConcurrentMap<String, List<ExtensionAdderProvider>> mapProviders = ExtensionAdderProviders.groupProvidersByName(listProviders);
ExtensionAdderProvider a = ExtensionAdderProviders.findCachedProvider("Default",
SimpleExtensionAdder.class, mapProviders, cache);
assertEquals("Default", a.getImplementationName());
assertEquals(SimpleExtensionAdderImplProvider.class, a.getClass());
assertEquals(1, cache.size());
ExtensionAdderProvider b = ExtensionAdderProviders.findCachedProvider("Custom",
SimpleExtensionAdder.class, mapProviders, cache);
assertEquals("Custom", b.getImplementationName());
assertEquals(SimpleExtensionAdderImpl2Provider.class, b.getClass());
assertEquals(2, cache.size());
// Do it again, it should work from the cache
assertEquals("Default", ExtensionAdderProviders.findCachedProvider("Default", SimpleExtensionAdder.class,
new ConcurrentHashMap<>(), cache).getImplementationName());
assertEquals("Custom", ExtensionAdderProviders.findCachedProvider("Custom", SimpleExtensionAdder.class,
new ConcurrentHashMap<>(), cache)
.getImplementationName());
}
@Test
void testMissing() {
try {
ExtensionAdderProviders.findCachedProvider("Default",
SimpleExtensionAdder.class, new ConcurrentHashMap<>(),
new ConcurrentHashMap<>());
fail("Should throw Missing Provider exception");
} catch (PowsyblException e) {
assertTrue(e.getMessage().contains("not found"), "Should throw Missing Provider exception");
}
}
@Test
void testMissingAlternate() {
try {
ConcurrentMap<String, List<ExtensionAdderProvider>> providersMap = ExtensionAdderProviders
.groupProvidersByName(Arrays.asList(new SimpleExtensionAdderImplProvider()));
ExtensionAdderProviders.findCachedProvider("Custom",
SimpleExtensionAdder.class, providersMap,
new ConcurrentHashMap<>());
fail("Should throw Missing Provider exception");
} catch (PowsyblException e) {
assertTrue(e.getMessage().contains("not found"), "Should throw Missing Provider exception");
}
}
@Test
void testMissingAlternate2() {
try {
ConcurrentMap<String, List<ExtensionAdderProvider>> providersMap = ExtensionAdderProviders
.groupProvidersByName(Arrays.asList(new GenericExtensionAdderImpl2Provider()));
ExtensionAdderProviders.findCachedProvider("Custom",
SimpleExtensionAdder.class, providersMap,
new ConcurrentHashMap<>());
fail("Should throw Missing Provider exception");
} catch (PowsyblException e) {
assertTrue(e.getMessage().contains("not found"), "Should throw Missing Provider exception");
}
}
@Test
void testMultiple() {
List<ExtensionAdderProvider> listProviders = Arrays.asList(
new SimpleExtensionAdderImplProvider(),
new SimpleExtensionAdderImplProvider());
ConcurrentMap<String, List<ExtensionAdderProvider>> mapProviders = ExtensionAdderProviders
.groupProvidersByName(listProviders);
try {
ExtensionAdderProviders.findCachedProvider("Default",
SimpleExtensionAdder.class, mapProviders, new ConcurrentHashMap<>());
fail("Should throw Multiple Provider exception");
} catch (PowsyblException e) {
assertTrue(e.getMessage().contains("Multiple"), "Should Mutliple Missing Provider exception");
}
}
@Test
void testAddingBase() {
Extendable<SimpleExtendable> a = new SimpleExtendableImpl2();
a.newExtension(SimpleExtensionAdder.class).add();
assertNotNull(a.getExtension(SimpleExtension.class));
}
@Test
void testAddingSimple() {
SimpleExtendable a = new SimpleExtendableImpl2();
a.newExtension(SimpleExtensionAdder.class).add();
assertNotNull(a.getExtension(SimpleExtension.class));
}
@Test
void testAddingGeneric1() {
SpecificExtendable b = new SpecificExtendableImpl2();
b.newExtension(GenericExtensionAdder.class).add();
assertNotNull(b.getExtension(GenericExtension.class));
}
@Test
void testAddingGeneric2() {
GenericExtendable<SpecificExtendable> b = new SpecificExtendableImpl2();
b.newExtension(GenericExtensionAdder.class).add();
assertNotNull(b.getExtension(GenericExtension.class));
}
@Test
void testAddingGeneric3() {
GenericExtendable<SpecificExtendable> b = new GenericExtendableImpl2();
b.newExtension(GenericExtensionAdder.class).add();
assertNotNull(b.getExtension(GenericExtension.class));
}
}