New way to structure the bootstrap code, to make it easier than the low-level primitives that are required under the hood. It betters suits the mental model, rather than the internal programming model.
Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/b86b66d4 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/b86b66d4 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/b86b66d4 Branch: refs/heads/develop Commit: b86b66d4ec80e51dceb0f608082a5b0b4062d16c Parents: 454154e Author: Niclas Hedhman <[email protected]> Authored: Wed Jun 17 10:39:36 2015 +0800 Committer: Niclas Hedhman <[email protected]> Committed: Wed Jun 17 10:39:36 2015 +0800 ---------------------------------------------------------------------- core/bootstrap/src/docs/bootstrap.txt | 86 +++++++-- .../bootstrap/builder/ApplicationBuilder.java | 19 +- .../qi4j/bootstrap/layered/LayerAssembler.java | 10 + .../layered/LayeredApplicationAssembler.java | 189 +++++++++++++++++++ .../layered/LayeredLayerAssembler.java | 62 ++++++ .../qi4j/bootstrap/layered/ModuleAssembler.java | 11 ++ .../LayeredApplicationAssemblerTest.java | 23 +++ .../bootstrap/assembly/TestApplication.java | 43 +++++ .../assembly/config/ConfigurationLayer.java | 15 ++ .../connectivity/ConnectivityLayer.java | 17 ++ .../bootstrap/assembly/domain/DomainLayer.java | 17 ++ .../assembly/domain/InvoicingModule.java | 17 ++ .../bootstrap/assembly/domain/OrderModule.java | 38 ++++ .../assembly/infrastructure/IndexingModule.java | 26 +++ .../infrastructure/InfrastructureLayer.java | 29 +++ .../infrastructure/SerializationModule.java | 18 ++ .../assembly/infrastructure/StorageModule.java | 26 +++ .../assembly/service/ServiceLayer.java | 17 ++ 18 files changed, 647 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/docs/bootstrap.txt ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/docs/bootstrap.txt b/core/bootstrap/src/docs/bootstrap.txt index 80da48e..22165c9 100644 --- a/core/bootstrap/src/docs/bootstrap.txt +++ b/core/bootstrap/src/docs/bootstrap.txt @@ -30,7 +30,8 @@ to a module and visibility rules define default behaviors, enforcement of archit The _assembly_ is preceeded by the creation of the _Qi4j Runtime_. The _assembly_ can be declared fully by defining all modules and layers, and how the layers are sitting on top of each other, OR one can utilize one of the two convenience assemblies, one for a _pancake_ pattern, where all layers are top on each other, or one with a single module -in a single layer, useful for small applications, spikes and tests. +in a single layer, useful for small applications, spikes and tests. The +bootstrap+ system has several ways to acheive +this, and they are listed below in <<core-bootstrap-assembly-layered>>. During _assembly_, the application (JVM level) architecture and the application model is defined. You define which layers exist and how they relate to each other. For each layer, you define which modules it contains. And for each @@ -125,15 +126,6 @@ tag=properties-defaults == Setting meta information on assembled types == -== Facilities == - -=== Assembly Specifications === - -=== Class Scanner === - -=== Application Builder === - - == Using Assemblers == Many <<libraries,libraries>> and <<extensions,extensions>> provides a cookie-cutter _Assembler_, to simplify the set up of such component. Often these are suitable, but sometimes they won't fit the application in hand, in which case the @@ -173,6 +165,44 @@ tag=UsingAssembler -------------- +[[core-bootstrap-assembly-layered,Layered Application Assembler]] +== Layered Application Assembler (RECOMMENDED!) == + +In 2.1, a new way to instantiate Qi4j applications was introduced. It starts with subclassing the ++LayeredApplicationAssembler+, and implementing the +assembleLayers()+ method. + +In the +assembleLayers()+ method, one is epected to either call the +createLayer()+ method in the super class +with the Class of the LayerAssembler, + +[source,java] +---- + LayerAssembly domainLayer = createLayer( DomainLayer.class ); +---- + +OR manually instantiate and call the LayerAssembler. + +[source,java] +---- + LayerAssembly infraLayer = new InfrastructureLayer( configModule ).assemble( assembly.layer( InfrastructureLayer.NAME )); +---- + +This is to make the normal case as simple as possible, yet allow the special needs that occssionally surfaces. + +Each LayerAssembler implementation may optionally extend the +LayeredLayerAssembler+, to get access to the ++createModule()+ method, which again simplifies the creation of modules in the +assemble()+ method. + +[source,java] +---- + createModule( layer, InvoicingModule.class ); +---- + ++ModuleAssembler+ implementations typically use +Assembler+ classes to put together, or call the +entities()+, ++values()+ methods described elsewhere on this page. There is no superclass to use. + ++ModuleAssembler+ implementations should have a name ending with "Module" and the naming will insert a human-readable +space within the module name, e.g. +InvoicingModule+ will be named "Invoicing Module". + +For example code, see the tutorial <<howto-assemble-application>>. == Singleton Assembler == @@ -193,7 +223,39 @@ Once the SingletonAssembler constructor returns, the Qi4j application is up and The SingletonAssembler also makes common system resources available from the bootstrap code, such as Module, UnitOfWorkFactory and others. This is possible since there is only one Module. - +== Application Builder == +Some applications has no need for runtime determination of the exact application structure, and no need for +advanced alterations to a staright-forward layered application structure. By using the +ApplicationBuilder+ +it is possible to define the application structure from a JSON document, AND call the provided +main()+ class, +taking the JSON document as input on +System.in+. + +The format of the JSON document, directly reflects the application structure, such as +[source,json] +---- +{ + "name": "Build from JSON test.", + "layers": [ + { "name": "service", "uses": [ "domain", "config"] }, + { "name": "donfig" }, + { + "name": "domain", + "modules" : [ + { + "name" : "Invoicing", + "assemblers" : [ + "org.hedhman.niclas.bootstrap.InvoicingAssembler" + ] + } + ] + } + ] +} +---- + +At the moment, the JSON format only support +Assembler+ classes to do the work. + +Another way to use the +ApplicationBuilder+ is to subclass it, optionally use the +configureFromJSON()+ method, +and then programmatically enhance the structure before calling +newApplication()+. == Pancake Assembly == There is one case that stands out as a common case, and forms a reasonable middle-ground. It is where each layer sits @@ -210,8 +272,6 @@ source=core/bootstrap/src/test/java/org/qi4j/bootstrap/DocumentationSupport.java tag=pancake -------------- - - == Full Assembly == Full Assembly means that you have the opportunity to create any layer/module hierarchy that are within the rules of the Qi4j runtime. It requires more support in your code to be useful, and the example below is by no means a recommended way http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java index c008e5f..d68a3d5 100644 --- a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java @@ -180,6 +180,19 @@ public class ApplicationBuilder { String applicationName = root.getString( "name" ); ApplicationBuilder builder = new ApplicationBuilder( applicationName ); + builder.configureWithJson( root ); + return builder; + } + + /** Configures the application struucture from a JSON document. + * + * @param root The JSON document root. + * @throws JSONException if the JSON document isn't valid. + * @throws AssemblyException if probelms in the Assemblers provided in the JSON document. + */ + protected void configureWithJson( JSONObject root ) + throws JSONException, AssemblyException + { JSONArray layers = root.optJSONArray( "layers" ); if( layers != null ) { @@ -187,7 +200,7 @@ public class ApplicationBuilder { JSONObject layerObject = layers.getJSONObject( i ); String layerName = layerObject.getString( "name" ); - LayerDeclaration layerDeclaration = builder.withLayer( layerName ); + LayerDeclaration layerDeclaration = withLayer( layerName ); JSONArray using = layerObject.optJSONArray( "uses" ); if( using != null ) { @@ -209,14 +222,14 @@ public class ApplicationBuilder { for( int m = 0; m < assemblers.length(); m++ ) { - moduleDeclaration.withAssembler( assemblers.getString( m ) ); + String string = assemblers.getString( m ); + moduleDeclaration.withAssembler( string ); } } } } } } - return builder; } /** http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java new file mode 100644 index 0000000..b922b98 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java @@ -0,0 +1,10 @@ +package org.qi4j.bootstrap.layered; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; + +public interface LayerAssembler +{ + LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException; +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java new file mode 100644 index 0000000..7eb00d5 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java @@ -0,0 +1,189 @@ +package org.qi4j.bootstrap.layered; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.activation.PassivationException; +import org.qi4j.api.structure.Application; +import org.qi4j.api.structure.ApplicationDescriptor; +import org.qi4j.bootstrap.ApplicationAssembler; +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.ApplicationAssemblyFactory; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.Energy4Java; +import org.qi4j.bootstrap.LayerAssembly; + +public abstract class LayeredApplicationAssembler + implements ApplicationAssembler +{ + protected Application application; + protected String name; + protected String version; + private final Application.Mode mode; + private ApplicationAssembly assembly; + + private HashMap<Class<? extends LayerAssembler>, LayerAssembler> assemblers = new HashMap<>(); + + public LayeredApplicationAssembler( String name, String version, Application.Mode mode ) + throws AssemblyException + { + this.name = name; + this.version = version; + this.mode = mode; + Energy4Java qi4j = new Energy4Java(); + ApplicationDescriptor model = qi4j.newApplicationModel( this ); + onModelCreated( model ); + instantiateApplication( qi4j, model ); + } + + /** + * This method is called from the constructor to instantiate the Qi4j application from the application model. + * + * <p> + * The default implementation simply calls; + * <pre><code> + * application = model.newInstance( qi4j.spi() ); + * </code></pre> + * </p> + * + * @param qi4j The Qi4j runtime engine. + * @param model The application model descriptor. + */ + protected void instantiateApplication( Energy4Java qi4j, ApplicationDescriptor model ) + { + application = model.newInstance( qi4j.spi() ); + } + + /** + * This method is called after the Application Model has been created, before the instantiation of the Qi4j + * application. + * + * <p> + * The default implementation does nothing. Applications may have advanced features to inspect or + * modify the model prior to instantiation, and this is the place where such advanced manipulation is + * expected to take place. + * </p> + * + * @param model + */ + protected void onModelCreated( ApplicationDescriptor model ) + { + } + + public Application application() + { + return application; + } + + public void start() + throws ActivationException + { + application.activate(); + } + + public void stop() + throws PassivationException + { + application.passivate(); + } + + @Override + public ApplicationAssembly assemble( ApplicationAssemblyFactory applicationFactory ) + throws AssemblyException + { + assembly = applicationFactory.newApplicationAssembly(); + assembly.setName( name ); + assembly.setVersion( version ); + assembly.setMode( mode ); + assembleLayers( assembly ); + return assembly; + } + + protected LayerAssembly createLayer( Class<? extends LayerAssembler> layerAssemblerClass ) + throws IllegalArgumentException + { + try + { + String classname = layerAssemblerClass.getSimpleName(); + if( classname.endsWith( "Layer" ) ) + { + classname = classname.substring( 0, classname.length() - 5 ) + " Layer"; + } + setNameIfPresent( layerAssemblerClass, classname ); + LayerAssembly layer = assembly.layer( classname ); + + LayerAssembler layerAssembler = instantiateAssembler( layerAssemblerClass, layer ); + assemblers.put( layerAssemblerClass, layerAssembler ); + LayerAssembly assembly = layerAssembler.assemble( layer ); + if( assembly == null ) + { + // Assume that people forgot, and let's not require a "return layer", since we can do that ourselves. + return layer; + } + return assembly; + } + catch( Exception e ) + { + throw new IllegalArgumentException( "Unable to instantiate layer with " + layerAssemblerClass.getSimpleName(), e ); + } + } + + private LayerAssembler instantiateAssembler( Class<? extends LayerAssembler> layerAssemblerClass, + LayerAssembly layer + ) + throws InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException + { + LayerAssembler layerAssembler; + try + { + Constructor<? extends LayerAssembler> assemblyConstructor = layerAssemblerClass.getConstructor( LayerAssembly.class ); + layerAssembler = assemblyConstructor.newInstance( layer ); + } + catch( NoSuchMethodException e ) + { + // Use default constructor then. + layerAssembler = layerAssemblerClass.newInstance(); + } + return layerAssembler; + } + + static void setNameIfPresent( Class<?> clazz, String classname ) + throws IllegalAccessException + { + try + { + Field field = clazz.getDeclaredField( "NAME" ); + if( Modifier.isStatic( field.getModifiers() ) ) + { + field.setAccessible( true ); + field.set( null, classname ); + } + } + catch( Exception e ) + { + // Ignore and consider normal. + } + } + + @SuppressWarnings( "unchecked" ) + protected <T extends LayerAssembler> T assemblerOf( Class<T> layerAssemblerClass ) + { + return (T) assemblers.get( layerAssemblerClass ); + } + + /** + * Called from the constructor to assemble the layers in the applcation. + * + * <p> + * This method must be implemented, and is typically a list of LayerAssmebler instantitations, followed + * by {@link LayerAssembly#uses(LayerAssembly...)} declarations. + * <pre><code> + * + * </code></pre> + * </p> + */ + protected abstract void assembleLayers( ApplicationAssembly assembly ) + throws AssemblyException; +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java new file mode 100644 index 0000000..91ca286 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java @@ -0,0 +1,62 @@ +package org.qi4j.bootstrap.layered; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; + +public abstract class LayeredLayerAssembler + implements LayerAssembler +{ + private HashMap<Class<? extends ModuleAssembler>, ModuleAssembler> assemblers = new HashMap<>(); + + protected ModuleAssembly createModule( LayerAssembly layer, Class<? extends ModuleAssembler> modulerAssemblerClass ) + { + try + { + ModuleAssembler moduleAssembler = instantiateAssembler( layer, modulerAssemblerClass ); + String classname = modulerAssemblerClass.getSimpleName(); + if( classname.endsWith( "Module" ) ) + { + classname = classname.substring( 0, classname.length() - 6 ) + " Module"; + } + LayeredApplicationAssembler.setNameIfPresent( modulerAssemblerClass, classname ); + ModuleAssembly module = layer.module( classname ); + assemblers.put( modulerAssemblerClass, moduleAssembler ); + ModuleAssembly assembly = moduleAssembler.assemble( layer, module ); + if( assembly == null ) + { + return module; + } + return assembly; + } + catch( Exception e ) + { + throw new IllegalArgumentException( "Unable to instantiate module with " + modulerAssemblerClass.getSimpleName(), e ); + } + } + + private ModuleAssembler instantiateAssembler( LayerAssembly layer, + Class<? extends ModuleAssembler> modulerAssemblerClass + ) + throws InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException + { + ModuleAssembler moduleAssembler; + try + { + Constructor<? extends ModuleAssembler> assemblyConstructor = modulerAssemblerClass.getConstructor( ModuleAssembly.class ); + moduleAssembler = assemblyConstructor.newInstance( layer ); + } + catch( NoSuchMethodException e ) + { + moduleAssembler = modulerAssemblerClass.newInstance(); + } + return moduleAssembler; + } + + @SuppressWarnings( "unchecked" ) + protected <T extends ModuleAssembler> T assemblerOf( Class<T> moduleAssemblerType ) + { + return (T) assemblers.get( moduleAssemblerType ); + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java new file mode 100644 index 0000000..d09bac5 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java @@ -0,0 +1,11 @@ +package org.qi4j.bootstrap.layered; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; + +public interface ModuleAssembler +{ + ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException; +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/LayeredApplicationAssemblerTest.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/LayeredApplicationAssemblerTest.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/LayeredApplicationAssemblerTest.java new file mode 100644 index 0000000..c63a3bd --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/LayeredApplicationAssemblerTest.java @@ -0,0 +1,23 @@ +package org.qi4j.bootstrap.assembly; + +import org.junit.Test; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.structure.Application; +import org.qi4j.bootstrap.AssemblyException; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; + +public class LayeredApplicationAssemblerTest +{ + @Test + public void validateThatAssemblerCreatesApplication() + throws AssemblyException, ActivationException + { + TestApplication assembler = new TestApplication( "Test Application", "1.0.1", Application.Mode.test ); + assembler.start(); + + assertThat( assembler.application().name(), equalTo("Test Application") ); + assertThat( assembler.application().version(), equalTo("1.0.1") ); + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/TestApplication.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/TestApplication.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/TestApplication.java new file mode 100644 index 0000000..4f44c7f --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/TestApplication.java @@ -0,0 +1,43 @@ +package org.qi4j.bootstrap.assembly; + +import org.qi4j.api.structure.Application; +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.layered.LayeredApplicationAssembler; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.assembly.config.ConfigurationLayer; +import org.qi4j.bootstrap.assembly.connectivity.ConnectivityLayer; +import org.qi4j.bootstrap.assembly.domain.DomainLayer; +import org.qi4j.bootstrap.assembly.infrastructure.InfrastructureLayer; +import org.qi4j.bootstrap.assembly.service.ServiceLayer; + +// START SNIPPET: application +public class TestApplication extends LayeredApplicationAssembler +{ + + public TestApplication( String name, String version, Application.Mode mode ) + throws AssemblyException + { + super( name, version, mode ); + } + + @Override + protected void assembleLayers( ApplicationAssembly assembly ) + throws AssemblyException + { + LayerAssembly configLayer = createLayer( ConfigurationLayer.class ); + ModuleAssembly configModule = configLayer.module( "Configuration Module" ); + LayerAssembly infraLayer = new InfrastructureLayer( configModule ).assemble( assembly.layer( InfrastructureLayer.NAME )); + LayerAssembly domainLayer = createLayer( DomainLayer.class ); + LayerAssembly serviceLayer = createLayer( ServiceLayer.class ); + LayerAssembly connectivityLayer = createLayer( ConnectivityLayer.class ); + + connectivityLayer.uses( serviceLayer ); + connectivityLayer.uses( domainLayer ); + serviceLayer.uses( domainLayer ); + domainLayer.uses( infraLayer ); + infraLayer.uses( configLayer ); + } +} +// END SNIPPET: application http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/config/ConfigurationLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/config/ConfigurationLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/config/ConfigurationLayer.java new file mode 100644 index 0000000..419a789 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/config/ConfigurationLayer.java @@ -0,0 +1,15 @@ +package org.qi4j.bootstrap.assembly.config; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.layered.LayerAssembler; +import org.qi4j.bootstrap.LayerAssembly; + +public class ConfigurationLayer implements LayerAssembler +{ + @Override + public LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException + { + return layer; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/connectivity/ConnectivityLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/connectivity/ConnectivityLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/connectivity/ConnectivityLayer.java new file mode 100644 index 0000000..5631a68 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/connectivity/ConnectivityLayer.java @@ -0,0 +1,17 @@ +package org.qi4j.bootstrap.assembly.connectivity; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.layered.LayerAssembler; +import org.qi4j.bootstrap.LayerAssembly; + +public class ConnectivityLayer implements LayerAssembler +{ + public static final String NAME = "Connectivity"; + + @Override + public LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException + { + return null; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/DomainLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/DomainLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/DomainLayer.java new file mode 100644 index 0000000..ea7a12f --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/DomainLayer.java @@ -0,0 +1,17 @@ +package org.qi4j.bootstrap.assembly.domain; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.layered.LayeredLayerAssembler; + +public class DomainLayer extends LayeredLayerAssembler +{ + @Override + public LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException + { + createModule( layer, InvoicingModule.class ); + createModule( layer, OrderModule.class ); + return layer; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/InvoicingModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/InvoicingModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/InvoicingModule.java new file mode 100644 index 0000000..0a654b5 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/InvoicingModule.java @@ -0,0 +1,17 @@ +package org.qi4j.bootstrap.assembly.domain; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.ModuleAssembler; + +public class InvoicingModule + implements ModuleAssembler +{ + @Override + public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException + { + return module; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/OrderModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/OrderModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/OrderModule.java new file mode 100644 index 0000000..b721332 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/domain/OrderModule.java @@ -0,0 +1,38 @@ +package org.qi4j.bootstrap.assembly.domain; + +import org.qi4j.api.association.Association; +import org.qi4j.api.property.Property; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.ModuleAssembler; + +public class OrderModule + implements ModuleAssembler +{ + @Override + public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException + { + module.entities( Order.class, Customer.class ); + module.values( Address.class ); + return module; + } + + public interface Order + { + Association<Customer> customer(); + + Property<Address> invoicingAddress(); + + Property<Address> deliveryAddress(); + } + + public interface Customer + { + } + + public interface Address + { + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java new file mode 100644 index 0000000..a06a0f7 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/IndexingModule.java @@ -0,0 +1,26 @@ +package org.qi4j.bootstrap.assembly.infrastructure; + +import org.qi4j.api.common.Visibility; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.ModuleAssembler; + +public class IndexingModule + implements ModuleAssembler +{ + public static final String NAME = "Indexing Module"; + private final ModuleAssembly configModule; + + public IndexingModule( ModuleAssembly configModule ) + { + this.configModule = configModule; + } + + @Override + public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException + { + return module; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java new file mode 100644 index 0000000..5ba33ba --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/InfrastructureLayer.java @@ -0,0 +1,29 @@ +package org.qi4j.bootstrap.assembly.infrastructure; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.LayerAssembler; +import org.qi4j.bootstrap.layered.LayeredLayerAssembler; + +public class InfrastructureLayer extends LayeredLayerAssembler + implements LayerAssembler +{ + public static final String NAME = "Infrastructure Layer"; + private final ModuleAssembly configModule; + + public InfrastructureLayer( ModuleAssembly configModule ) + { + this.configModule = configModule; + } + + @Override + public LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException + { + new StorageModule( configModule ).assemble( layer, layer.module( StorageModule.NAME ) ); + new IndexingModule( configModule ).assemble( layer, layer.module( IndexingModule.NAME ) ); + createModule( layer, SerializationModule.class ); + return layer; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java new file mode 100644 index 0000000..19edd6f --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/SerializationModule.java @@ -0,0 +1,18 @@ +package org.qi4j.bootstrap.assembly.infrastructure; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.ModuleAssembler; + +public class SerializationModule + implements ModuleAssembler +{ + @Override + public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module + ) + throws AssemblyException + { + return null; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java new file mode 100644 index 0000000..424c653 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/infrastructure/StorageModule.java @@ -0,0 +1,26 @@ +package org.qi4j.bootstrap.assembly.infrastructure; + +import org.qi4j.api.common.Visibility; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.bootstrap.layered.ModuleAssembler; + +public class StorageModule + implements ModuleAssembler +{ + public static final String NAME = "Storage Module"; + private final ModuleAssembly configModule; + + public StorageModule( ModuleAssembly configModule ) + { + this.configModule = configModule; + } + + @Override + public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException + { + return module; + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b86b66d4/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java new file mode 100644 index 0000000..14f6ae1 --- /dev/null +++ b/core/bootstrap/src/test/java/org/qi4j/bootstrap/assembly/service/ServiceLayer.java @@ -0,0 +1,17 @@ +package org.qi4j.bootstrap.assembly.service; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.layered.LayerAssembler; +import org.qi4j.bootstrap.LayerAssembly; + +public class ServiceLayer implements LayerAssembler +{ + public static final String NAME = "Service"; + + @Override + public LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException + { + return null; + } +}
