diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractCollectionProvider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractCollectionProvider.groovy index d08d5ca..9fdf050 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractCollectionProvider.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractCollectionProvider.groovy @@ -40,6 +40,29 @@ abstract class AbstractCollectionProvider implements CollectionProvider { collectionProvider in this } + @Override + > boolean containsType(Class childCollectionProviderClass) { + if (childCollectionProviderClass.isAssignableFrom(this.class)) { + true + } else { + this.collectionProviderChildren.inject(false) { acc, childProvider -> + acc || childCollectionProviderClass.isAssignableFrom(childProvider.class) + || childProvider.containsType(childCollectionProviderClass) + } + } + } + + @Override + > Collection getChildrenOfType(Class childCollectionProviderClass) { + this.collectionProviderChildren.inject([] as Collection) { acc, childProvider -> + if (childCollectionProviderClass.isAssignableFrom(childProvider.class)) { + acc + childProvider.getChildrenOfType(childCollectionProviderClass) + (childProvider as C) + } else { + acc + childProvider.getChildrenOfType(childCollectionProviderClass) + } + } + } + @Override CollectionProvider plus(Provider other) { concat(this, other) @@ -50,11 +73,24 @@ abstract class AbstractCollectionProvider implements CollectionProvider { concat(this, other) } + private boolean searchProviderChildrenFor(Provider descendant) { + this.providerChildren.inject(false) { acc, childProvider -> + acc || descendant in childProvider + } + } + + private boolean searchCollectionProviderChildrenFor(Provider descendant) { + this.collectionProviderChildren.inject(false) { acc, childProvider -> + acc || descendant in childProvider + } + } + @Override boolean isCase(Provider provider) { - provider in this.providerChildren || this.providerChildren.inject(false) { acc, childProvider -> - acc || provider in childProvider - } + provider in this.providerChildren + || this.searchProviderChildrenFor(provider) + || this.searchCollectionProviderChildrenFor(provider) + } @Override diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractProvider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractProvider.groovy index 9d3272a..680ba38 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractProvider.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/AbstractProvider.groovy @@ -6,16 +6,30 @@ abstract class AbstractProvider implements Provider { Provider p0, Provider p1 ) { - new SupplierBasedCollectionProvider<>({ + new SupplierBasedCollectionProvider<>([], [p0, p1], { [p0.provide(), p1.provide()] }) } + static CollectionProvider concat( + Provider p0, + CollectionProvider p1 + ) { + new SupplierBasedCollectionProvider<>([p1], [p0], { + [p0.provide(), *p1.provide()] + }) + } + @Override CollectionProvider plus(Provider other) { concat(this, other) } + @Override + CollectionProvider plus(CollectionProvider other) { + concat(this, other) + } + @Override CollectionProvider asType(Class collectionProviderClass) { new SupplierBasedCollectionProvider<>({ diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.groovy deleted file mode 100644 index 03a6aa9..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package com.jessebrault.ssg.provider - -interface CollectionProvider { - Collection provide() - - boolean contains(Provider provider) - boolean contains(CollectionProvider collectionProvider) - - CollectionProvider plus(Provider other) - CollectionProvider plus(CollectionProvider other) - - boolean isCase(Provider provider) - boolean isCase(CollectionProvider collectionProvider) -} \ No newline at end of file diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.java b/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.java new file mode 100644 index 0000000..33a3969 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProvider.java @@ -0,0 +1,19 @@ +package com.jessebrault.ssg.provider; + +import java.util.Collection; + +public interface CollectionProvider { + Collection provide(); + + boolean contains(Provider provider); + boolean contains(CollectionProvider collectionProvider); + + > boolean containsType(Class childCollectionProviderClass); + > Collection getChildrenOfType(Class childCollectionProviderClass); + + CollectionProvider plus(Provider other); + CollectionProvider plus(CollectionProvider other); + + boolean isCase(Provider provider); + boolean isCase(CollectionProvider collectionProvider); +} \ No newline at end of file diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProviders.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProviders.groovy index 882746e..ee94772 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProviders.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/CollectionProviders.groovy @@ -19,7 +19,7 @@ final class CollectionProviders { new SupplierBasedCollectionProvider<>(supplier) } - static CollectionProvider fromDirectory( + static DirectoryCollectionProvider fromDirectory( File baseDirectory, BiFunction elementFunction ) { diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/DirectoryCollectionProvider.java b/api/src/main/groovy/com/jessebrault/ssg/provider/DirectoryCollectionProvider.java new file mode 100644 index 0000000..3a6da45 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/DirectoryCollectionProvider.java @@ -0,0 +1,11 @@ +package com.jessebrault.ssg.provider; + +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.BiFunction; + +public interface DirectoryCollectionProvider extends CollectionProvider { + File getBaseDirectory(); + BiFunction getMapper(); +} diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/EmptyProvider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/EmptyProvider.groovy index d1971af..f3072cf 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/EmptyProvider.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/EmptyProvider.groovy @@ -14,6 +14,13 @@ final class EmptyProvider implements Provider { throw new NullPointerException('EmptyProvider cannot provide a value.') } + @Override + CollectionProvider plus(CollectionProvider other) { + CollectionProviders.fromSupplier { + other.provide() + } + } + @Override CollectionProvider plus(Provider other) { CollectionProviders.fromSupplier { diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProvider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProvider.groovy index b158470..ba40869 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProvider.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProvider.groovy @@ -14,7 +14,7 @@ import java.util.function.BiFunction @PackageScope @NullCheck @EqualsAndHashCode(includeFields = true, callSuper = true) -final class FileBasedCollectionProvider extends AbstractCollectionProvider { +final class FileBasedCollectionProvider extends AbstractCollectionProvider implements DirectoryCollectionProvider { private static final Logger logger = LoggerFactory.getLogger(FileBasedCollectionProvider) @@ -27,6 +27,16 @@ final class FileBasedCollectionProvider extends AbstractCollectionProvider this.elementFunction = elementFunction } + @Override + File getBaseDirectory() { + this.baseDirectory + } + + @Override + BiFunction getMapper() { + this.elementFunction + } + @Override Collection provide() { if (!this.baseDirectory.isDirectory()) { diff --git a/api/src/main/groovy/com/jessebrault/ssg/provider/Provider.groovy b/api/src/main/groovy/com/jessebrault/ssg/provider/Provider.groovy index 4954a94..7a771a8 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/provider/Provider.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/provider/Provider.groovy @@ -3,5 +3,6 @@ package com.jessebrault.ssg.provider interface Provider { T provide() CollectionProvider plus(Provider other) + CollectionProvider plus(CollectionProvider other) CollectionProvider asType(Class collectionProviderClass) } \ No newline at end of file diff --git a/api/src/test/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProviderTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProviderTests.groovy index 1df3216..6380f56 100644 --- a/api/src/test/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProviderTests.groovy +++ b/api/src/test/groovy/com/jessebrault/ssg/provider/FileBasedCollectionProviderTests.groovy @@ -1,5 +1,9 @@ package com.jessebrault.ssg.provider +import org.junit.jupiter.api.Test + +import static org.junit.jupiter.api.Assertions.assertTrue + final class FileBasedCollectionProviderTests extends AbstractCollectionProviderTests { @Override @@ -18,4 +22,10 @@ final class FileBasedCollectionProviderTests extends AbstractCollectionProviderT }) } + @Test + void containsSelfType() { + def p = new FileBasedCollectionProvider(new File(''), { f -> '' }) + assertTrue(p.containsType(DirectoryCollectionProvider)) + } + } diff --git a/api/src/testFixtures/groovy/com/jessebrault/ssg/provider/AbstractCollectionProviderTests.groovy b/api/src/testFixtures/groovy/com/jessebrault/ssg/provider/AbstractCollectionProviderTests.groovy index d3a4818..3033aa7 100644 --- a/api/src/testFixtures/groovy/com/jessebrault/ssg/provider/AbstractCollectionProviderTests.groovy +++ b/api/src/testFixtures/groovy/com/jessebrault/ssg/provider/AbstractCollectionProviderTests.groovy @@ -3,17 +3,28 @@ package com.jessebrault.ssg.provider import org.junit.jupiter.api.DynamicTest import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestFactory +import org.mockito.Answers +import org.mockito.Mockito import org.slf4j.Logger import org.slf4j.LoggerFactory import java.util.function.Consumer +import static org.junit.jupiter.api.Assertions.assertEquals import static org.junit.jupiter.api.Assertions.assertTrue +import static org.mockito.ArgumentMatchers.any +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.when abstract class AbstractCollectionProviderTests { protected static final Logger logger = LoggerFactory.getLogger(AbstractCollectionProviderTests) + @SuppressWarnings('GrMethodMayBeStatic') + protected Provider getProvider(Integer t) { + Providers.of(t) + } + protected abstract CollectionProvider getCollectionProvider(Collection ts) @Test @@ -43,7 +54,6 @@ abstract class AbstractCollectionProviderTests { }) } - @SuppressWarnings('GrMethodMayBeStatic') @TestFactory Collection containsAndIsCaseCollectionProviderChildren() { def p0 = this.getCollectionProvider([]) @@ -63,10 +73,9 @@ abstract class AbstractCollectionProviderTests { } } - @SuppressWarnings('GrMethodMayBeStatic') @TestFactory Collection containsAndIsCaseProviderChildren() { - def p0 = this.getCollectionProvider([]) + def p0 = this.getProvider(0) def p1 = this.getCollectionProvider([]) def sum = p0 + p1 ([ @@ -83,4 +92,28 @@ abstract class AbstractCollectionProviderTests { } } + @Test + void containsDirectoryCollectionProvider() { + final CollectionProvider dirProvider = CollectionProviders.fromDirectory( + new File(''), + { 0 } + ) + final CollectionProvider dummy = CollectionProviders.getEmpty() + def sum = dirProvider + dummy + assertTrue(sum.containsType(DirectoryCollectionProvider)) + } + + @Test + void getDirectoryCollectionProviderChild() { + final CollectionProvider dirProvider = CollectionProviders.fromDirectory( + new File(''), + { 0 } + ) + final CollectionProvider dummy = CollectionProviders.getEmpty() + def sum = dirProvider + dummy + def children = + sum.>getChildrenOfType(DirectoryCollectionProvider) + assertTrue(dirProvider in children) + } + }