Components automatically added to root scope and instantiated via objectFactory.

This commit is contained in:
JesseBrault0709 2024-05-30 10:43:22 +02:00
parent 31a6c79929
commit b5a7b1f67d
2 changed files with 80 additions and 26 deletions

View File

@ -15,11 +15,17 @@ import com.jessebrault.ssg.view.PageView
import com.jessebrault.ssg.view.WvcPageView
import groovy.transform.TupleConstructor
import groowt.util.di.RegistryObjectFactory
import groowt.util.fp.either.Either
import groowt.view.component.ComponentTemplate
import groowt.view.component.ViewComponent
import groowt.view.component.compiler.ComponentTemplateClassFactory
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration
import groowt.view.component.compiler.SimpleComponentTemplateClassFactory
import groowt.view.component.compiler.source.ComponentTemplateSource
import groowt.view.component.factory.ComponentFactories
import groowt.view.component.web.DefaultWebViewComponentContext
import groowt.view.component.web.DefaultWebViewComponentScope
import groowt.view.component.web.WebViewComponent
import groowt.view.component.web.compiler.DefaultWebViewComponentTemplateCompileUnit
import io.github.classgraph.ClassGraph
import org.slf4j.Logger
@ -65,6 +71,31 @@ class DefaultStaticSiteGenerator implements StaticSiteGenerator {
texts
}
protected Either<Diagnostic, ComponentTemplate> compileTemplate(
Class<? extends ViewComponent> componentClass,
String resourceName,
ComponentTemplateCompilerConfiguration compilerConfiguration,
ComponentTemplateClassFactory templateClassFactory
) {
def templateUrl = componentClass.getResource(resourceName)
if (templateUrl == null) {
return Either.left(new Diagnostic(
"Could not find templateResource: $it.templateResource"
))
}
def source = ComponentTemplateSource.of(templateUrl)
def compileUnit = new DefaultWebViewComponentTemplateCompileUnit(
source.descriptiveName,
componentClass,
source,
componentClass.packageName
)
def compileResult = compileUnit.compile(compilerConfiguration)
def templateClass = templateClassFactory.getTemplateClass(compileResult)
def componentTemplate = templateClass.getConstructor().newInstance()
return Either.right(componentTemplate)
}
@Override
Collection<Diagnostic> doBuild(
File projectDir,
@ -131,10 +162,11 @@ class DefaultStaticSiteGenerator implements StaticSiteGenerator {
}
def classgraph = new ClassGraph()
.enableAnnotationInfo()
.addClassLoader(groovyClassLoader)
.addClassLoader(this.groovyClassLoader)
basePackages.each { classgraph.acceptPackages(it) }
def pages = [] as Set<Page>
def allWvc = [] as Set<Class<? extends WebViewComponent>>
try (def scanResult = classgraph.scan()) {
// single pages
@ -168,6 +200,12 @@ class DefaultStaticSiteGenerator implements StaticSiteGenerator {
def pageFactory = objectFactory.createInstance(pageFactoryType)
pages.addAll(pageFactory.create())
}
// get all web view components
def wvcInfoList = scanResult.getClassesImplementing(WebViewComponent)
wvcInfoList.each {
allWvc << it.loadClass(WebViewComponent)
}
}
// Configure for PageView instantiation
@ -206,28 +244,52 @@ class DefaultStaticSiteGenerator implements StaticSiteGenerator {
configureRootScope {
// TODO: scan components in same package, add them to the scope with factories which
// use the object factory to construct the component
// also: automatically set template like below for pages
allWvc.each { wvcClass ->
//noinspection GroovyAssignabilityCheck
add(wvcClass, ComponentFactories.ofClosureClassType(wvcClass) { Map attr, Object[] args ->
WebViewComponent component
if (!attr.isEmpty() && args.length > 0) {
component = objectFactory.createInstance(wvcClass, attr, *args)
} else if (!attr.isEmpty()) {
component = objectFactory.createInstance(wvcClass, attr)
} else if (args.length > 0) {
component = objectFactory.createInstance(wvcClass, *args)
} else {
component = objectFactory.createInstance(wvcClass)
}
if (component.componentTemplate == null) {
def compileResult = this.compileTemplate(
wvcClass,
wvcClass.simpleName + 'Template.wvc',
wvcCompilerConfiguration,
componentTemplateClassFactory
)
if (compileResult.isRight()) {
component.componentTemplate = compileResult.getRight()
} else {
diagnostics << compileResult.getLeft()
}
}
return component
})
}
}
}
if (pageView.componentTemplate == null) {
def templateUrl = pageView.class.getResource(it.templateResource)
if (templateUrl == null) {
diagnostics.add(new Diagnostic(
"Could not find templateResource: $it.templateResource"
))
def compileResult = this.compileTemplate(
pageView.class,
it.templateResource,
wvcCompilerConfiguration,
componentTemplateClassFactory
)
if (compileResult.isRight()) {
pageView.componentTemplate = compileResult.getRight()
} else {
diagnostics << compileResult.getLeft()
return
}
def source = ComponentTemplateSource.of(templateUrl)
def compileUnit = new DefaultWebViewComponentTemplateCompileUnit(
source.descriptiveName,
pageView.class,
source,
pageView.class.packageName
)
def compileResult = compileUnit.compile(wvcCompilerConfiguration)
def templateClass = componentTemplateClassFactory.getTemplateClass(compileResult)
def componentTemplate = templateClass.getConstructor().newInstance()
pageView.componentTemplate = componentTemplate
}
}

View File

@ -4,7 +4,6 @@ import com.jessebrault.ssg.di.InjectText
import com.jessebrault.ssg.page.PageSpec
import com.jessebrault.ssg.text.Text
import com.jessebrault.ssg.view.WvcPageView
import groowt.view.component.web.WebViewComponentScope
import jakarta.inject.Inject
@PageSpec(name = 'Biography', path = '/biography')
@ -19,11 +18,4 @@ class Biography extends WvcPageView {
this.biographyText = biographyText
}
@Override
protected void beforeRender() {
context.configureRootScope(WebViewComponentScope) {
addWithAttr(Head)
}
}
}