| /* |
| * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. |
| * Copyright (c) 2012, Paul Merlin. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package org.qi4j.runtime.bootstrap; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| import org.qi4j.api.activation.Activator; |
| import org.qi4j.api.common.MetaInfo; |
| import org.qi4j.api.common.Visibility; |
| import org.qi4j.api.service.ServiceImporter; |
| import org.qi4j.api.structure.Layer; |
| import org.qi4j.bootstrap.ApplicationAssembly; |
| import org.qi4j.bootstrap.AssemblyVisitor; |
| import org.qi4j.bootstrap.EntityAssembly; |
| import org.qi4j.bootstrap.EntityDeclaration; |
| import org.qi4j.bootstrap.ImportedServiceAssembly; |
| import org.qi4j.bootstrap.ImportedServiceDeclaration; |
| import org.qi4j.bootstrap.LayerAssembly; |
| import org.qi4j.bootstrap.ModuleAssembly; |
| import org.qi4j.bootstrap.ObjectAssembly; |
| import org.qi4j.bootstrap.ObjectDeclaration; |
| import org.qi4j.bootstrap.ServiceAssembly; |
| import org.qi4j.bootstrap.ServiceDeclaration; |
| import org.qi4j.bootstrap.TransientAssembly; |
| import org.qi4j.bootstrap.TransientDeclaration; |
| import org.qi4j.bootstrap.ValueAssembly; |
| import org.qi4j.bootstrap.ValueDeclaration; |
| import org.qi4j.functional.Specification; |
| |
| /** |
| * Assembly of a Layer. From here you can create more ModuleAssemblies for |
| * the Layer that is being assembled. It is also here that you define |
| * what other Layers this Layer is using by calling {@link org.qi4j.runtime.bootstrap.LayerAssemblyImpl#uses()}. |
| */ |
| public final class LayerAssemblyImpl |
| implements LayerAssembly |
| { |
| private final ApplicationAssembly applicationAssembly; |
| private final HashMap<String, ModuleAssemblyImpl> moduleAssemblies; |
| private final Set<LayerAssembly> uses; |
| |
| private String name; |
| private final MetaInfo metaInfo = new MetaInfo(); |
| private final List<Class<? extends Activator<Layer>>> activators = new ArrayList<>(); |
| |
| public LayerAssemblyImpl( ApplicationAssembly applicationAssembly, String name ) |
| { |
| this.applicationAssembly = applicationAssembly; |
| this.name = name; |
| |
| moduleAssemblies = new LinkedHashMap<>(); |
| uses = new LinkedHashSet<>(); |
| } |
| |
| @Override |
| public ModuleAssembly module( String name ) |
| { |
| if( name != null ) |
| { |
| ModuleAssemblyImpl existing = moduleAssemblies.get( name ); |
| if( existing != null ) |
| { |
| return existing; |
| } |
| } |
| ModuleAssemblyImpl moduleAssembly = new ModuleAssemblyImpl( this, name ); |
| moduleAssemblies.put( name, moduleAssembly ); |
| return moduleAssembly; |
| } |
| |
| @Override |
| public ApplicationAssembly application() |
| { |
| return applicationAssembly; |
| } |
| |
| @Override |
| public LayerAssembly setName( String name ) |
| { |
| this.name = name; |
| return this; |
| } |
| |
| @Override |
| public LayerAssembly setMetaInfo( Object info ) |
| { |
| metaInfo.set( info ); |
| return this; |
| } |
| |
| @Override |
| public LayerAssembly uses( LayerAssembly... layerAssembly ) |
| throws IllegalArgumentException |
| { |
| uses.addAll( Arrays.asList( layerAssembly ) ); |
| return this; |
| } |
| |
| @Override |
| @SafeVarargs |
| public final LayerAssembly withActivators( Class<? extends Activator<Layer>>... activators ) |
| { |
| this.activators.addAll( Arrays.asList( activators ) ); |
| return this; |
| } |
| |
| @Override |
| public <ThrowableType extends Throwable> void visit( AssemblyVisitor<ThrowableType> visitor ) |
| throws ThrowableType |
| { |
| visitor.visitLayer( this ); |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| moduleAssembly.visit( visitor ); |
| } |
| } |
| |
| @Override |
| public EntityDeclaration entities( Specification<? super EntityAssembly> specification ) |
| { |
| final List<EntityDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.entities( specification ) ); |
| } |
| |
| return new EntityDeclaration() |
| { |
| @Override |
| public EntityDeclaration setMetaInfo( Object info ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( info ); |
| } |
| return this; |
| } |
| |
| @Override |
| public EntityDeclaration visibleIn( Visibility visibility ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| |
| @Override |
| public EntityDeclaration withConcerns( Class<?>... concerns ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.withConcerns( concerns ); |
| } |
| return this; |
| } |
| |
| @Override |
| public EntityDeclaration withSideEffects( Class<?>... sideEffects ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.withSideEffects( sideEffects ); |
| } |
| return this; |
| } |
| |
| @Override |
| public EntityDeclaration withMixins( Class<?>... mixins ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.withMixins( mixins ); |
| } |
| return this; |
| } |
| |
| @Override |
| public EntityDeclaration withTypes( Class<?>... types ) |
| { |
| for( EntityDeclaration declaration : declarations ) |
| { |
| declaration.withTypes( types ); |
| } |
| return this; |
| } |
| }; |
| } |
| |
| @Override |
| public ServiceDeclaration services( Specification<? super ServiceAssembly> specification ) |
| { |
| final List<ServiceDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.services( specification ) ); |
| } |
| |
| return new ServiceDeclaration() |
| { |
| @Override |
| public ServiceDeclaration setMetaInfo( Object serviceAttribute ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( serviceAttribute ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration visibleIn( Visibility visibility ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration withConcerns( Class<?>... concerns ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.withConcerns( concerns ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration withSideEffects( Class<?>... sideEffects ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.withSideEffects( sideEffects ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration withMixins( Class<?>... mixins ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.withMixins( mixins ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration withTypes( Class<?>... types ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.withTypes( types ); |
| } |
| return this; |
| } |
| |
| @Override |
| @SafeVarargs |
| public final ServiceDeclaration withActivators( Class<? extends Activator<?>>... activators ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.withActivators( activators ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration identifiedBy( String identity ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.identifiedBy( identity ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration taggedWith( String... tags ) |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.taggedWith( tags ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ServiceDeclaration instantiateOnStartup() |
| { |
| for( ServiceDeclaration declaration : declarations ) |
| { |
| declaration.instantiateOnStartup(); |
| } |
| |
| return this; |
| } |
| }; |
| } |
| |
| @Override |
| public TransientDeclaration transients( Specification<? super TransientAssembly> specification ) |
| { |
| final List<TransientDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.transients( specification ) ); |
| } |
| |
| return new TransientDeclaration() |
| { |
| @Override |
| public TransientDeclaration setMetaInfo( Object info ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( info ); |
| } |
| return this; |
| } |
| |
| @Override |
| public TransientDeclaration visibleIn( Visibility visibility ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| |
| @Override |
| public TransientDeclaration withConcerns( Class<?>... concerns ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.withConcerns( concerns ); |
| } |
| return this; |
| } |
| |
| @Override |
| public TransientDeclaration withSideEffects( Class<?>... sideEffects ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.withSideEffects( sideEffects ); |
| } |
| return this; |
| } |
| |
| @Override |
| public TransientDeclaration withMixins( Class<?>... mixins ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.withMixins( mixins ); |
| } |
| return this; |
| } |
| |
| @Override |
| public TransientDeclaration withTypes( Class<?>... types ) |
| { |
| for( TransientDeclaration declaration : declarations ) |
| { |
| declaration.withTypes( types ); |
| } |
| return this; |
| } |
| }; |
| } |
| |
| @Override |
| public ValueDeclaration values( Specification<? super ValueAssembly> specification ) |
| { |
| final List<ValueDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.values( specification ) ); |
| } |
| return new ValueDeclaration() |
| { |
| @Override |
| public ValueDeclaration setMetaInfo( Object info ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( info ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ValueDeclaration visibleIn( Visibility visibility ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ValueDeclaration withConcerns( Class<?>... concerns ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.withConcerns( concerns ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ValueDeclaration withSideEffects( Class<?>... sideEffects ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.withSideEffects( sideEffects ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ValueDeclaration withMixins( Class<?>... mixins ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.withMixins( mixins ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ValueDeclaration withTypes( Class<?>... types ) |
| { |
| for( ValueDeclaration declaration : declarations ) |
| { |
| declaration.withTypes( types ); |
| } |
| return this; |
| } |
| }; |
| } |
| |
| @Override |
| public ObjectDeclaration objects( Specification<? super ObjectAssembly> specification ) |
| { |
| final List<ObjectDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.objects( specification ) ); |
| } |
| return new ObjectDeclaration() |
| { |
| @Override |
| public ObjectDeclaration setMetaInfo( Object info ) |
| { |
| for( ObjectDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( info ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ObjectDeclaration visibleIn( Visibility visibility ) |
| throws IllegalStateException |
| { |
| for( ObjectDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| }; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration importedServices( Specification<? super ImportedServiceAssembly> specification ) |
| { |
| final List<ImportedServiceDeclaration> declarations = new ArrayList<>(); |
| |
| for( ModuleAssemblyImpl moduleAssembly : moduleAssemblies.values() ) |
| { |
| declarations.add( moduleAssembly.importedServices( specification ) ); |
| } |
| return new ImportedServiceDeclaration() |
| { |
| |
| @Override |
| public ImportedServiceDeclaration importOnStartup() |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.importOnStartup(); |
| } |
| return this; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration visibleIn( Visibility visibility ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.visibleIn( visibility ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration importedBy( Class<? extends ServiceImporter> serviceImporterClass ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.importedBy( serviceImporterClass ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration identifiedBy( String identity ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.identifiedBy( identity ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration taggedWith( String... tags ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.taggedWith( tags ); |
| } |
| return this; |
| } |
| |
| @Override |
| public ImportedServiceDeclaration setMetaInfo( Object serviceAttribute ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.setMetaInfo( serviceAttribute ); |
| } |
| return this; |
| } |
| |
| @Override |
| @SafeVarargs |
| public final ImportedServiceDeclaration withActivators( Class<? extends Activator<?>>... activators ) |
| { |
| for( ImportedServiceDeclaration declaration : declarations ) |
| { |
| declaration.withActivators( activators ); |
| } |
| return this; |
| } |
| |
| }; |
| } |
| |
| Collection<ModuleAssemblyImpl> moduleAssemblies() |
| { |
| return moduleAssemblies.values(); |
| } |
| |
| Set<LayerAssembly> uses() |
| { |
| return uses; |
| } |
| |
| public MetaInfo metaInfo() |
| { |
| return metaInfo; |
| } |
| |
| @Override |
| public String name() |
| { |
| return name; |
| } |
| |
| public List<Class<? extends Activator<Layer>>> activators() |
| { |
| return activators; |
| } |
| |
| @Override |
| public final String toString() |
| { |
| return "LayerAssembly [" + name + "]"; |
| } |
| } |