http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/LayerAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/LayerAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/LayerAssemblyImpl.java new file mode 100644 index 0000000..8b18426 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/LayerAssemblyImpl.java @@ -0,0 +1,630 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.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 java.util.function.Predicate; +import org.apache.polygene.api.activation.Activator; +import org.apache.polygene.api.common.MetaInfo; +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.api.service.ServiceImporter; +import org.apache.polygene.api.structure.Layer; +import org.apache.polygene.bootstrap.ApplicationAssembly; +import org.apache.polygene.bootstrap.AssemblyVisitor; +import org.apache.polygene.bootstrap.EntityAssembly; +import org.apache.polygene.bootstrap.EntityDeclaration; +import org.apache.polygene.bootstrap.ImportedServiceAssembly; +import org.apache.polygene.bootstrap.ImportedServiceDeclaration; +import org.apache.polygene.bootstrap.LayerAssembly; +import org.apache.polygene.bootstrap.ModuleAssembly; +import org.apache.polygene.bootstrap.ObjectAssembly; +import org.apache.polygene.bootstrap.ObjectDeclaration; +import org.apache.polygene.bootstrap.ServiceAssembly; +import org.apache.polygene.bootstrap.ServiceDeclaration; +import org.apache.polygene.bootstrap.TransientAssembly; +import org.apache.polygene.bootstrap.TransientDeclaration; +import org.apache.polygene.bootstrap.ValueAssembly; +import org.apache.polygene.bootstrap.ValueDeclaration; + +/** + * 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.apache.polygene.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( Predicate<? 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( Predicate<? 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( Predicate<? 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( Predicate<? 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( Predicate<? 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( Predicate<? 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 + "]"; + } +}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java new file mode 100644 index 0000000..62220a6 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ModuleAssemblyImpl.java @@ -0,0 +1,645 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.UndeclaredThrowableException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.polygene.api.activation.Activator; +import org.apache.polygene.api.common.MetaInfo; +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.api.composite.TransientComposite; +import org.apache.polygene.api.entity.EntityComposite; +import org.apache.polygene.api.identity.HasIdentity; +import org.apache.polygene.api.identity.Identity; +import org.apache.polygene.api.identity.IdentityGenerator; +import org.apache.polygene.api.identity.StringIdentity; +import org.apache.polygene.api.service.DuplicateServiceIdentityException; +import org.apache.polygene.api.structure.Module; +import org.apache.polygene.api.type.HasTypes; +import org.apache.polygene.api.type.MatchTypeSpecification; +import org.apache.polygene.api.unitofwork.UnitOfWorkFactory; +import org.apache.polygene.api.value.ValueComposite; +import org.apache.polygene.bootstrap.Assembler; +import org.apache.polygene.bootstrap.AssemblyException; +import org.apache.polygene.bootstrap.AssemblySpecifications; +import org.apache.polygene.bootstrap.AssemblyVisitor; +import org.apache.polygene.bootstrap.ConfigurationDeclaration; +import org.apache.polygene.bootstrap.EntityAssembly; +import org.apache.polygene.bootstrap.EntityDeclaration; +import org.apache.polygene.bootstrap.ImportedServiceAssembly; +import org.apache.polygene.bootstrap.ImportedServiceDeclaration; +import org.apache.polygene.bootstrap.LayerAssembly; +import org.apache.polygene.bootstrap.MetaInfoDeclaration; +import org.apache.polygene.bootstrap.MixinDeclaration; +import org.apache.polygene.bootstrap.ModuleAssembly; +import org.apache.polygene.bootstrap.ObjectAssembly; +import org.apache.polygene.bootstrap.ObjectDeclaration; +import org.apache.polygene.bootstrap.ServiceAssembly; +import org.apache.polygene.bootstrap.ServiceDeclaration; +import org.apache.polygene.bootstrap.TransientAssembly; +import org.apache.polygene.bootstrap.TransientDeclaration; +import org.apache.polygene.bootstrap.ValueAssembly; +import org.apache.polygene.bootstrap.ValueDeclaration; +import org.apache.polygene.bootstrap.identity.DefaultIdentityGeneratorAssembler; +import org.apache.polygene.bootstrap.unitofwork.DefaultUnitOfWorkAssembler; +import org.apache.polygene.runtime.activation.ActivatorsModel; +import org.apache.polygene.runtime.composite.TransientModel; +import org.apache.polygene.runtime.composite.TransientsModel; +import org.apache.polygene.runtime.entity.EntitiesModel; +import org.apache.polygene.runtime.entity.EntityModel; +import org.apache.polygene.runtime.object.ObjectModel; +import org.apache.polygene.runtime.object.ObjectsModel; +import org.apache.polygene.runtime.service.ImportedServiceModel; +import org.apache.polygene.runtime.service.ImportedServicesModel; +import org.apache.polygene.runtime.service.ServiceModel; +import org.apache.polygene.runtime.service.ServicesModel; +import org.apache.polygene.runtime.structure.LayerModel; +import org.apache.polygene.runtime.structure.ModuleModel; +import org.apache.polygene.runtime.value.ValueModel; +import org.apache.polygene.runtime.value.ValuesModel; + +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static java.util.stream.Collectors.toList; + +/** + * Assembly of a Module. This is where you register all objects, Composites, + * Services. Each "add" method returns a declaration that you can use to add + * additional information and metadata. If you call an "add" method with many + * parameters then the declared metadata will apply to all types in the method + * call. + */ +final class ModuleAssemblyImpl + implements ModuleAssembly +{ + private static HashMap<Class, Assembler> defaultAssemblers; + + private final LayerAssembly layerAssembly; + private String name; + private final MetaInfo metaInfo = new MetaInfo(); + + private final List<Class<? extends Activator<Module>>> activators = new ArrayList<>(); + private final List<ServiceAssemblyImpl> serviceAssemblies = new ArrayList<>(); + private final Map<Class<?>, ImportedServiceAssemblyImpl> importedServiceAssemblies = new LinkedHashMap<>(); + private final Map<Class<? extends EntityComposite>, EntityAssemblyImpl> entityAssemblies = new LinkedHashMap<>(); + private final Map<Class<? extends ValueComposite>, ValueAssemblyImpl> valueAssemblies = new LinkedHashMap<>(); + private final Map<Class<? extends TransientComposite>, TransientAssemblyImpl> transientAssemblies = new LinkedHashMap<>(); + + private final Map<Class<?>, ObjectAssemblyImpl> objectAssemblies = new LinkedHashMap<>(); + + private final MetaInfoDeclaration metaInfoDeclaration = new MetaInfoDeclaration(); + + static + { + defaultAssemblers = new HashMap<>(); + defaultAssemblers.put(UnitOfWorkFactory.class, new DefaultUnitOfWorkAssembler()); + defaultAssemblers.put(IdentityGenerator.class, new DefaultIdentityGeneratorAssembler()); + } + + ModuleAssemblyImpl(LayerAssembly layerAssembly, String name) + { + this.layerAssembly = layerAssembly; + this.name = name; + } + + @Override + public LayerAssembly layer() + { + return layerAssembly; + } + + @Override + public ModuleAssembly module(String layerName, String moduleName) + { + return layerAssembly.application().module(layerName, moduleName); + } + + @Override + public ModuleAssembly setName(String name) + { + this.name = name; + return this; + } + + @Override + public String name() + { + return name; + } + + public ModuleAssembly setMetaInfo(Object info) + { + metaInfo.set(info); + return this; + } + + @Override + @SafeVarargs + public final ModuleAssembly withActivators(Class<? extends Activator<Module>>... activators) + { + this.activators.addAll( asList( activators ) ); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public ValueDeclaration values(Class<?>... valueTypes) + { + List<ValueAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class valueType : valueTypes) + { + if (valueAssemblies.containsKey(valueType)) + { + assemblies.add(valueAssemblies.get(valueType)); + } + else + { + ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl(valueType); + valueAssemblies.put(valueType, valueAssembly); + assemblies.add(valueAssembly); + } + } + + return new ValueDeclarationImpl(assemblies); + } + + @Override + public ValueDeclaration values(Predicate<? super ValueAssembly> specification) + { + List<ValueAssemblyImpl> assemblies = valueAssemblies.values().stream() + .filter(specification::test) + .collect(toList()); + return new ValueDeclarationImpl(assemblies); + } + + @Override + @SuppressWarnings({"raw", "unchecked"}) + public TransientDeclaration transients(Class<?>... transientTypes) + { + List<TransientAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class valueType : transientTypes) + { + if (transientAssemblies.containsKey(valueType)) + { + assemblies.add(transientAssemblies.get(valueType)); + } + else + { + TransientAssemblyImpl transientAssembly = new TransientAssemblyImpl(valueType); + transientAssemblies.put(valueType, transientAssembly); + assemblies.add(transientAssembly); + } + } + + return new TransientDeclarationImpl(assemblies); + } + + @Override + public TransientDeclaration transients(Predicate<? super TransientAssembly> specification) + { + List<TransientAssemblyImpl> assemblies = transientAssemblies.values().stream() + .filter(specification::test) + .collect(toList()); + + return new TransientDeclarationImpl(assemblies); + } + + @Override + @SuppressWarnings({"raw", "unchecked"}) + public EntityDeclaration entities(Class<?>... entityTypes) + { + List<EntityAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class entityType : entityTypes) + { + if (entityAssemblies.containsKey(entityType)) + { + assemblies.add(entityAssemblies.get(entityType)); + } + else + { + EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl(entityType); + entityAssemblies.put(entityType, entityAssembly); + assemblies.add(entityAssembly); + } + } + + return new EntityDeclarationImpl(assemblies); + } + + @Override + public EntityDeclaration entities(Predicate<? super EntityAssembly> specification) + { + List<EntityAssemblyImpl> assemblies = entityAssemblies.values().stream() + .filter(specification::test) + .collect(toList()); + + return new EntityDeclarationImpl(assemblies); + } + + @Override + @SuppressWarnings("unchecked") + public ConfigurationDeclaration configurations(Class<?>... configurationTypes) + { + List<EntityAssemblyImpl> entityAssemblyList = new ArrayList<>(); + + for (Class entityType : configurationTypes) + { + if (this.entityAssemblies.containsKey(entityType)) + { + entityAssemblyList.add(this.entityAssemblies.get(entityType)); + } + else + { + EntityAssemblyImpl entityAssembly = new EntityAssemblyImpl(entityType); + this.entityAssemblies.put(entityType, entityAssembly); + entityAssemblyList.add(entityAssembly); + } + } + + List<ValueAssemblyImpl> valueAssemblyList = new ArrayList<>(); + + for (Class valueType : configurationTypes) + { + if (valueAssemblies.containsKey(valueType)) + { + valueAssemblyList.add(valueAssemblies.get(valueType)); + } + else + { + ValueAssemblyImpl valueAssembly = new ValueAssemblyImpl(valueType); + valueAssemblies.put(valueType, valueAssembly); + valueAssemblyList.add(valueAssembly); + valueAssembly.types.add(HasIdentity.class); + } + } + + return new ConfigurationDeclarationImpl(entityAssemblyList, valueAssemblyList); + } + + @Override + public ConfigurationDeclaration configurations(Predicate<HasTypes> specification) + { + Predicate<HasTypes> isConfigurationComposite = new MatchTypeSpecification(HasIdentity.class); + specification = specification.and(isConfigurationComposite); + List<EntityAssemblyImpl> entityAssmblyList = new ArrayList<>(); + for (EntityAssemblyImpl entityAssembly : entityAssemblies.values()) + { + if (specification.test(entityAssembly)) + { + entityAssmblyList.add(entityAssembly); + } + } + List<ValueAssemblyImpl> valueAssemblyList = new ArrayList<>(); + for (ValueAssemblyImpl transientAssembly : valueAssemblies.values()) + { + if (specification.test(transientAssembly)) + { + valueAssemblyList.add(transientAssembly); + } + } + return new ConfigurationDeclarationImpl(entityAssmblyList, valueAssemblyList); + } + + @Override + public ObjectDeclaration objects(Class<?>... objectTypes) + throws AssemblyException + { + List<ObjectAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class<?> objectType : objectTypes) + { + if (objectType.isInterface()) + { + throw new AssemblyException("Interfaces can not be Polygene Objects."); + } + if (objectAssemblies.containsKey(objectType)) + { + assemblies.add(objectAssemblies.get(objectType)); + } + else + { + ObjectAssemblyImpl objectAssembly = new ObjectAssemblyImpl(objectType); + objectAssemblies.put(objectType, objectAssembly); + assemblies.add(objectAssembly); + } + } + + return new ObjectDeclarationImpl(assemblies); + } + + @Override + public ObjectDeclaration objects(Predicate<? super ObjectAssembly> specification) + { + List<ObjectAssemblyImpl> assemblies = objectAssemblies.values().stream() + .filter(specification::test) + .collect(toList()); + + return new ObjectDeclarationImpl(assemblies); + } + + @Override + public ServiceDeclaration addServices(Class<?>... serviceTypes) + { + List<ServiceAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class<?> serviceType : serviceTypes) + { + ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl(serviceType); + serviceAssemblies.add(serviceAssembly); + assemblies.add(serviceAssembly); + } + + return new ServiceDeclarationImpl(assemblies); + } + + @Override + public ServiceDeclaration services(Class<?>... serviceTypes) + { + List<ServiceAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class<?> serviceType : serviceTypes) + { + if( serviceAssemblies.stream().anyMatch( AssemblySpecifications.ofAnyType( serviceType ) ) ) + { + serviceAssemblies.stream().filter( AssemblySpecifications.ofAnyType( serviceType ) ) + .forEach( assemblies::add ); + } + else + { + ServiceAssemblyImpl serviceAssembly = new ServiceAssemblyImpl(serviceType); + serviceAssemblies.add(serviceAssembly); + assemblies.add(serviceAssembly); + } + } + + return new ServiceDeclarationImpl(assemblies); + } + + @Override + public ServiceDeclaration services(Predicate<? super ServiceAssembly> specification) + { + List<ServiceAssemblyImpl> assemblies = serviceAssemblies.stream() + .filter(specification::test) + .collect(toList()); + return new ServiceDeclarationImpl(assemblies); + } + + @Override + public ImportedServiceDeclaration importedServices(Class<?>... serviceTypes) + { + List<ImportedServiceAssemblyImpl> assemblies = new ArrayList<>(); + + for (Class<?> serviceType : serviceTypes) + { + if (importedServiceAssemblies.containsKey(serviceType)) + { + assemblies.add(importedServiceAssemblies.get(serviceType)); + } + else + { + ImportedServiceAssemblyImpl serviceAssembly = new ImportedServiceAssemblyImpl(serviceType, this); + importedServiceAssemblies.put(serviceType, serviceAssembly); + assemblies.add(serviceAssembly); + } + } + + return new ImportedServiceDeclarationImpl(assemblies); + } + + @Override + public ImportedServiceDeclaration importedServices(Predicate<? super ImportedServiceAssembly> specification) + { + List<ImportedServiceAssemblyImpl> assemblies = importedServiceAssemblies.values().stream() + .filter(specification::test) + .collect(toList()); + + return new ImportedServiceDeclarationImpl(assemblies); + } + + @Override + public <T> MixinDeclaration<T> forMixin(Class<T> mixinType) + { + return metaInfoDeclaration.on(mixinType); + } + + @Override + public <ThrowableType extends Throwable> void visit(AssemblyVisitor<ThrowableType> visitor) + throws ThrowableType + { + visitor.visitModule( this ); + + for( TransientAssemblyImpl compositeDeclaration : transientAssemblies.values() ) + { + visitor.visitComposite( new TransientDeclarationImpl( singleton( compositeDeclaration ) ) ); + } + + for( EntityAssemblyImpl entityDeclaration : entityAssemblies.values() ) + { + visitor.visitEntity( new EntityDeclarationImpl( singleton( entityDeclaration ) ) ); + } + + for( ObjectAssemblyImpl objectDeclaration : objectAssemblies.values() ) + { + visitor.visitObject( new ObjectDeclarationImpl( singleton( objectDeclaration ) ) ); + } + + for( ServiceAssemblyImpl serviceDeclaration : serviceAssemblies ) + { + visitor.visitService( new ServiceDeclarationImpl( singleton( serviceDeclaration ) ) ); + } + + for( ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values() ) + { + visitor.visitImportedService( new ImportedServiceDeclarationImpl( singleton( importedServiceDeclaration ) ) ); + } + + for( ValueAssemblyImpl valueDeclaration : valueAssemblies.values() ) + { + visitor.visitValue( new ValueDeclarationImpl( singleton( valueDeclaration ) ) ); + } + } + + @SuppressWarnings("OptionalGetWithoutIsPresent") + ModuleModel assembleModule(LayerModel layerModel, AssemblyHelper helper) + throws AssemblyException + { + addDefaultAssemblers(); + List<TransientModel> transientModels = new ArrayList<>(); + List<ObjectModel> objectModels = new ArrayList<>(); + List<ValueModel> valueModels = new ArrayList<>(); + List<ServiceModel> serviceModels = new ArrayList<>(); + List<ImportedServiceModel> importedServiceModels = new ArrayList<>(); + List<EntityModel> entityModels = new ArrayList<>(); + ModuleModel moduleModel = new ModuleModel(name, + metaInfo, + layerModel, + new ActivatorsModel<>(activators), + new TransientsModel(transientModels), + new EntitiesModel(entityModels), + new ObjectsModel(objectModels), + new ValuesModel(valueModels), + new ServicesModel(serviceModels), + new ImportedServicesModel(importedServiceModels)); + + if (name == null) + { + throw new AssemblyException("Module must have name set"); + } + + transientModels.addAll(transientAssemblies.values().stream() + .map(composite -> composite.newTransientModel(moduleModel, metaInfoDeclaration, helper)) + .collect(toList())); + + valueModels.addAll(valueAssemblies.values().stream() + .map(value -> value.newValueModel(moduleModel, metaInfoDeclaration, helper)) + .collect(toList())); + + entityModels.addAll(entityAssemblies.values().stream() + .map(entityDeclaration -> entityDeclaration.newEntityModel(moduleModel, + metaInfoDeclaration, + metaInfoDeclaration, + metaInfoDeclaration, + metaInfoDeclaration, + helper)) + .collect(Collectors.toList())); + + for (ObjectAssemblyImpl objectDeclaration : objectAssemblies.values()) + { + objectDeclaration.addObjectModel(moduleModel, objectModels); + } + + for (ServiceAssemblyImpl serviceDeclaration : serviceAssemblies) + { + if (serviceDeclaration.identity == null) + { + serviceDeclaration.identity = generateId(serviceDeclaration.types()); + } + + serviceModels.add(serviceDeclaration.newServiceModel(moduleModel, metaInfoDeclaration, helper)); + } + + for (ImportedServiceAssemblyImpl importedServiceDeclaration : importedServiceAssemblies.values()) + { + importedServiceDeclaration.addImportedServiceModel(moduleModel, importedServiceModels); + } + + // Check for duplicate service identities + Set<String> identities = new HashSet<>(); + for (ServiceModel serviceModel : serviceModels) + { + String identity = serviceModel.identity().toString(); + if (identities.contains(identity)) + { + throw new DuplicateServiceIdentityException( + "Duplicated service reference: " + identity + " in module " + moduleModel.name() + ); + } + identities.add(identity); + } + for (ImportedServiceModel serviceModel : importedServiceModels) + { + String identity = serviceModel.identity().toString(); + if (identities.contains(identity)) + { + throw new DuplicateServiceIdentityException( + "Duplicated service reference: " + identity + " in module " + moduleModel.name() + ); + } + identities.add(identity); + } + + importedServiceModels + .stream() + .filter( + importedServiceModel -> + objectModels.stream().noneMatch( model -> model.types().findFirst().get() + .equals( importedServiceModel.serviceImporter() ) ) ) + .forEach( + importedServiceModel -> + objectModels.add( new ObjectModel( moduleModel, importedServiceModel.serviceImporter(), + Visibility.module, new MetaInfo() ) ) ); + + return moduleModel; + } + + private void addDefaultAssemblers() + throws AssemblyException + { + try + { + defaultAssemblers.entrySet().stream() + .filter(entry -> serviceAssemblies.stream().noneMatch(serviceAssembly -> serviceAssembly.hasType(entry.getKey()))) + .forEach(entry -> + { + try + { + entry.getValue().assemble(this); + } + catch (AssemblyException e) + { + throw new UndeclaredThrowableException(e); + } + }); + } + catch (UndeclaredThrowableException e) + { + throw (AssemblyException) e.getUndeclaredThrowable(); + } + } + + private Identity generateId(Stream<Class<?>> serviceTypes) + { + // Find service reference that is not yet used + Class<?> serviceType = serviceTypes.findFirst() + .orElse(null); // Use the first, which *SHOULD* be the main serviceType + int idx = 0; + Identity id = new StringIdentity(serviceType.getSimpleName()); + boolean invalid; + do + { + invalid = false; + for (ServiceAssemblyImpl serviceAssembly : serviceAssemblies) + { + if (serviceAssembly.identity() != null && serviceAssembly.identity().equals(id)) + { + idx++; + id = new StringIdentity(serviceType.getSimpleName() + "_" + idx); + invalid = true; + break; + } + } + } + while (invalid); + return id; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectAssemblyImpl.java new file mode 100644 index 0000000..50a4256 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectAssemblyImpl.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.stream.Stream; +import org.apache.polygene.api.common.InvalidApplicationException; +import org.apache.polygene.api.common.MetaInfo; +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.api.composite.Composite; +import org.apache.polygene.api.structure.ModuleDescriptor; +import org.apache.polygene.bootstrap.ObjectAssembly; +import org.apache.polygene.runtime.object.ObjectModel; + +/** + * Assembly of an Object. + */ +public final class ObjectAssemblyImpl + implements ObjectAssembly +{ + private Class<?> objectType; + MetaInfo metaInfo = new MetaInfo(); + Visibility visibility = Visibility.module; + + public ObjectAssemblyImpl( Class<?> clazz ) + { + // best try to find out if the class is a concrete class + if( clazz.isEnum() || + ( !Composite.class.isAssignableFrom( clazz ) && Modifier.isAbstract( clazz.getModifiers() ) ) ) + { + throw new IllegalArgumentException( "Declared objects must be concrete classes: " + clazz ); + } + this.objectType = clazz; + } + + @Override + public Stream<Class<?>> types() + { + return Stream.of( objectType ); + } + + void addObjectModel( ModuleDescriptor module, List<ObjectModel> objectModels ) + { + try + { + ObjectModel objectModel = new ObjectModel( module, objectType, visibility, metaInfo ); + objectModels.add( objectModel ); + } + catch( Throwable e ) + { + throw new InvalidApplicationException( "Could not register " + objectType.getName(), e ); + } + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectDeclarationImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectDeclarationImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectDeclarationImpl.java new file mode 100644 index 0000000..bba3faa --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ObjectDeclarationImpl.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.bootstrap.ObjectDeclaration; + +/** + * Declaration of an Object. Created by {@link org.apache.polygene.runtime.bootstrap.ModuleAssemblyImpl#objects(Class[])}. + */ +public final class ObjectDeclarationImpl + implements ObjectDeclaration +{ + private final Iterable<ObjectAssemblyImpl> assemblies; + + public ObjectDeclarationImpl( Iterable<ObjectAssemblyImpl> assemblies ) + { + this.assemblies = assemblies; + } + + @Override + public ObjectDeclaration setMetaInfo( Object info ) + { + for( ObjectAssemblyImpl assembly : assemblies ) + { + assembly.metaInfo.set( info ); + } + return this; + } + + @Override + public ObjectDeclaration visibleIn( Visibility visibility ) + throws IllegalStateException + { + for( ObjectAssemblyImpl assembly : assemblies ) + { + assembly.visibility = visibility; + } + return this; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/OrAppliesToFilter.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/OrAppliesToFilter.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/OrAppliesToFilter.java new file mode 100644 index 0000000..77d9c39 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/OrAppliesToFilter.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.Method; +import org.apache.polygene.api.common.AppliesToFilter; + +/** + * JAVADOC + */ +final class OrAppliesToFilter + implements AppliesToFilter +{ + private final AppliesToFilter left; + private final AppliesToFilter right; + + OrAppliesToFilter( AppliesToFilter left, AppliesToFilter right ) + { + this.left = left; + this.right = right; + } + + @Override + public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ) + { + return left.appliesTo( method, mixin, compositeType, fragmentClass ) || + right.appliesTo( method, mixin, compositeType, fragmentClass ); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceAssemblyImpl.java new file mode 100644 index 0000000..dab0b31 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceAssemblyImpl.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.polygene.api.activation.Activator; +import org.apache.polygene.api.activation.Activators; +import org.apache.polygene.api.common.InvalidApplicationException; +import org.apache.polygene.api.identity.Identity; +import org.apache.polygene.api.service.ServiceComposite; +import org.apache.polygene.api.util.Annotations; +import org.apache.polygene.api.util.Classes; +import org.apache.polygene.bootstrap.ServiceAssembly; +import org.apache.polygene.bootstrap.StateDeclarations; +import org.apache.polygene.runtime.activation.ActivatorsModel; +import org.apache.polygene.runtime.service.ServiceModel; +import org.apache.polygene.runtime.structure.ModuleModel; + +/** + * Assembly of a Service. + */ +public final class ServiceAssemblyImpl extends CompositeAssemblyImpl + implements ServiceAssembly +{ + Identity identity; + boolean instantiateOnStartup = false; + List<Class<? extends Activator<?>>> activators = new ArrayList<>(); + + public ServiceAssemblyImpl( Class<?> serviceType ) + { + super( serviceType ); + // The composite must always implement ServiceComposite, as a marker interface + if( !ServiceComposite.class.isAssignableFrom( serviceType ) ) + { + types.add( ServiceComposite.class ); + } + } + + @Override + public Identity identity() + { + return identity; + } + + @SuppressWarnings( { "raw", "unchecked" } ) + ServiceModel newServiceModel( ModuleModel module, StateDeclarations stateDeclarations, AssemblyHelper helper ) + { + try + { + buildComposite( helper, stateDeclarations ); + List<Class<? extends Activator<?>>> activatorClasses = Stream + .concat( activators.stream(), activatorsDeclarations( types ) ) + .collect( Collectors.toList() ); + return new ServiceModel( module, types, visibility, metaInfo, + new ActivatorsModel( activatorClasses ), + mixinsModel, stateModel, compositeMethodsModel, + identity, instantiateOnStartup ); + } + catch( Exception e ) + { + throw new InvalidApplicationException( "Could not register " + types, e ); + } + } + + private Stream<Class<? extends Activator<?>>> activatorsDeclarations( List<? extends Class<?>> types ) + { + return types.stream() + .flatMap( Classes::typesOf ) + //.filter( type -> Annotations.annotationOn( type, Activators.class ) == null ) + .flatMap( this::getAnnotations ); + } + + private Stream<? extends Class<? extends Activator<?>>> getAnnotations( Type type ) + { + Activators activators = Annotations.annotationOn( type, Activators.class ); + if( activators == null ) + { + return Stream.empty(); + } + return Arrays.stream( activators.value() ); + } + + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceDeclarationImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceDeclarationImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceDeclarationImpl.java new file mode 100644 index 0000000..9fe0cb0 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ServiceDeclarationImpl.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.util.ArrayList; +import java.util.List; +import org.apache.polygene.api.activation.Activator; +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.api.identity.StringIdentity; +import org.apache.polygene.api.service.qualifier.ServiceTags; +import org.apache.polygene.bootstrap.ServiceDeclaration; + +import static java.util.Arrays.asList; + +/** + * Declaration of a Service. Created by {@link org.apache.polygene.runtime.bootstrap.ModuleAssemblyImpl#services(Class[])}. + */ +public final class ServiceDeclarationImpl + implements ServiceDeclaration +{ + private final Iterable<ServiceAssemblyImpl> serviceAssemblies; + + public ServiceDeclarationImpl( Iterable<ServiceAssemblyImpl> serviceAssemblies ) + { + this.serviceAssemblies = serviceAssemblies; + } + + @Override + public ServiceDeclaration visibleIn( Visibility visibility ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.visibility = visibility; + } + return this; + } + + @Override + public ServiceDeclaration identifiedBy( String identity ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.identity = new StringIdentity( identity ); + } + return this; + } + + @Override + public ServiceDeclaration taggedWith( String... tags ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + ServiceTags previousTags = serviceAssembly.metaInfo.get( ServiceTags.class ); + if( previousTags != null ) + { + List<String> tagList = new ArrayList<>(); + tagList.addAll( asList( previousTags.tags() ) ); + tagList.addAll( asList( tags ) ); + serviceAssembly.metaInfo.set( new ServiceTags( tagList.toArray( new String[ tagList.size() ] ) ) ); + } + else + { + serviceAssembly.metaInfo.set( new ServiceTags( tags ) ); + } + } + + return this; + } + + @Override + public ServiceDeclaration instantiateOnStartup() + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.instantiateOnStartup = true; + } + return this; + } + + @Override + public ServiceDeclaration setMetaInfo( Object serviceAttribute ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.metaInfo.set( serviceAttribute ); + } + return this; + } + + @Override + public ServiceDeclaration withConcerns( Class<?>... concerns ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.concerns.addAll( asList( concerns ) ); + } + return this; + } + + @Override + public ServiceDeclaration withSideEffects( Class<?>... sideEffects ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.sideEffects.addAll( asList( sideEffects ) ); + } + return this; + } + + @Override + public ServiceDeclaration withMixins( Class<?>... mixins ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.mixins.addAll( asList( mixins ) ); + } + return this; + } + + @Override + public ServiceDeclaration withTypes( Class<?>... types ) + { + for( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) + { + serviceAssembly.types.addAll( asList( types ) ); + } + return this; + } + + @Override + @SafeVarargs + public final ServiceDeclaration withActivators( Class<? extends Activator<?>>... activators ) + { + for ( ServiceAssemblyImpl serviceAssembly : serviceAssemblies ) { + serviceAssembly.activators.addAll( asList( activators ) ); + } + return this; + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientAssemblyImpl.java new file mode 100644 index 0000000..11c0230 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientAssemblyImpl.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import org.apache.polygene.api.common.InvalidApplicationException; +import org.apache.polygene.api.composite.TransientComposite; +import org.apache.polygene.api.structure.ModuleDescriptor; +import org.apache.polygene.bootstrap.StateDeclarations; +import org.apache.polygene.bootstrap.TransientAssembly; +import org.apache.polygene.runtime.composite.TransientModel; + +/** + * Declaration of a TransientComposite. + */ +public final class TransientAssemblyImpl extends CompositeAssemblyImpl + implements TransientAssembly +{ + public TransientAssemblyImpl( Class<?> transientType ) + { + super( transientType ); + + // The composite must always implement TransientComposite, as a marker interface + if( !TransientComposite.class.isAssignableFrom( transientType ) ) + { + types.add( TransientComposite.class ); + } + + // If type is a class, register it as a mixin + if( !transientType.isInterface() ) + { + mixins.add( transientType ); + } + } + + TransientModel newTransientModel( ModuleDescriptor module, + StateDeclarations stateDeclarations, + AssemblyHelper helper + ) + { + try + { + buildComposite( helper, stateDeclarations ); + return new TransientModel( + module, types, visibility, metaInfo, mixinsModel, stateModel, compositeMethodsModel ); + } + catch( Exception e ) + { + throw new InvalidApplicationException( "Could not register " + types, e ); + } + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientDeclarationImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientDeclarationImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientDeclarationImpl.java new file mode 100644 index 0000000..75a07b1 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TransientDeclarationImpl.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.bootstrap.TransientDeclaration; + +import static java.util.Arrays.asList; + +/** + * Declaration of a Composite. Created by {@link org.apache.polygene.bootstrap.ModuleAssembly#transients(Class[])}. + */ +public final class TransientDeclarationImpl + implements TransientDeclaration +{ + private final Iterable<TransientAssemblyImpl> assemblies; + + public TransientDeclarationImpl( Iterable<TransientAssemblyImpl> assemblies ) + { + this.assemblies = assemblies; + } + + @Override + public TransientDeclaration setMetaInfo( Object info ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.metaInfo.set( info ); + } + return this; + } + + @Override + public TransientDeclaration visibleIn( Visibility visibility ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.visibility = visibility; + } + return this; + } + + @Override + public TransientDeclaration withConcerns( Class<?>... concerns ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.concerns.addAll( asList( concerns ) ); + } + return this; + } + + @Override + public TransientDeclaration withSideEffects( Class<?>... sideEffects ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.sideEffects.addAll( asList( sideEffects ) ); + } + return this; + } + + @Override + public TransientDeclaration withMixins( Class<?>... mixins ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.mixins.addAll( asList( mixins ) ); + } + return this; + } + + @Override + public TransientDeclaration withTypes( Class<?>... types ) + { + for( TransientAssemblyImpl assembly : assemblies ) + { + assembly.types.addAll( asList( types ) ); + } + return this; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypeCheckAppliesToFilter.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypeCheckAppliesToFilter.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypeCheckAppliesToFilter.java new file mode 100644 index 0000000..9fcac21 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypeCheckAppliesToFilter.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.Method; +import org.apache.polygene.api.common.AppliesToFilter; + +/** + * JAVADOC + */ +final class TypeCheckAppliesToFilter + implements AppliesToFilter +{ + @SuppressWarnings( "raw" ) + private final Class type; + + @SuppressWarnings( "raw" ) + TypeCheckAppliesToFilter( Class type ) + { + this.type = type; + } + + @Override + @SuppressWarnings( "unchecked" ) + public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ) + { + return type.isAssignableFrom( compositeType ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypedFragmentAppliesToFilter.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypedFragmentAppliesToFilter.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypedFragmentAppliesToFilter.java new file mode 100644 index 0000000..bd6c8f7 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/TypedFragmentAppliesToFilter.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import java.lang.reflect.Method; +import org.apache.polygene.api.common.AppliesToFilter; + +/** + * JAVADOC + */ +final class TypedFragmentAppliesToFilter + implements AppliesToFilter +{ + @Override + public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ) + { + return method.getDeclaringClass().isAssignableFrom( fragmentClass ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueAssemblyImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueAssemblyImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueAssemblyImpl.java new file mode 100644 index 0000000..408da07 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueAssemblyImpl.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import org.apache.polygene.api.common.InvalidApplicationException; +import org.apache.polygene.api.structure.ModuleDescriptor; +import org.apache.polygene.api.value.ValueComposite; +import org.apache.polygene.bootstrap.StateDeclarations; +import org.apache.polygene.bootstrap.ValueAssembly; +import org.apache.polygene.runtime.association.AssociationsModel; +import org.apache.polygene.runtime.association.ManyAssociationsModel; +import org.apache.polygene.runtime.association.NamedAssociationsModel; +import org.apache.polygene.runtime.composite.StateModel; +import org.apache.polygene.runtime.value.ValueModel; +import org.apache.polygene.runtime.value.ValueStateModel; + +/** + * Declaration of a ValueComposite. + */ +public final class ValueAssemblyImpl + extends CompositeAssemblyImpl + implements ValueAssembly +{ + private AssociationsModel associationsModel; + private ManyAssociationsModel manyAssociationsModel; + private NamedAssociationsModel namedAssociationsModel; + + public ValueAssemblyImpl( Class<?> compositeType ) + { + super( compositeType ); + // The composite must always implement ValueComposite, as a marker interface + if( !ValueComposite.class.isAssignableFrom( compositeType ) ) + { + types.add( ValueComposite.class ); + } + } + + @Override + protected StateModel createStateModel() + { + return new ValueStateModel( propertiesModel, associationsModel, manyAssociationsModel, namedAssociationsModel ); + } + + ValueModel newValueModel( ModuleDescriptor module, + StateDeclarations stateDeclarations, + AssemblyHelper helper + ) + { + try + { + associationsModel = new AssociationsModel(); + manyAssociationsModel = new ManyAssociationsModel(); + namedAssociationsModel = new NamedAssociationsModel(); + buildComposite( helper, stateDeclarations ); + return new ValueModel( + module, types, visibility, metaInfo, mixinsModel, (ValueStateModel) stateModel, compositeMethodsModel ); + } + catch( Exception e ) + { + throw new InvalidApplicationException( "Could not register " + types, e ); + } + } + + protected AssociationsModel associationsModel() + { + return associationsModel; + } + + protected ManyAssociationsModel manyAssociationsModel() + { + return manyAssociationsModel; + } + + protected NamedAssociationsModel namedAssociationsModel() + { + return namedAssociationsModel; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueDeclarationImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueDeclarationImpl.java b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueDeclarationImpl.java new file mode 100644 index 0000000..0227a4c --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/bootstrap/ValueDeclarationImpl.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.bootstrap; + +import org.apache.polygene.api.common.Visibility; +import org.apache.polygene.bootstrap.ValueDeclaration; + +import static java.util.Arrays.asList; + +/** + * Declaration of a ValueComposite. + */ +public final class ValueDeclarationImpl + implements ValueDeclaration +{ + private final Iterable<ValueAssemblyImpl> assemblies; + + public ValueDeclarationImpl( Iterable<ValueAssemblyImpl> assemblies ) + { + this.assemblies = assemblies; + } + + @Override + public ValueDeclaration setMetaInfo( Object info ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.metaInfo.set( info ); + } + return this; + } + + @Override + public ValueDeclaration visibleIn( Visibility visibility ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.visibility = visibility; + } + return this; + } + + @Override + public ValueDeclaration withConcerns( Class<?>... concerns ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.concerns.addAll( asList( concerns ) ); + } + return this; + } + + @Override + public ValueDeclaration withSideEffects( Class<?>... sideEffects ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.sideEffects.addAll( asList( sideEffects ) ); + } + return this; + } + + @Override + public ValueDeclaration withMixins( Class<?>... mixins ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.mixins.addAll( asList( mixins ) ); + } + return this; + } + + @Override + public ValueDeclaration withTypes( Class<?>... types ) + { + for( ValueAssemblyImpl assembly : assemblies ) + { + assembly.types.addAll( asList( types ) ); + } + return this; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/runtime/src/main/java/org/apache/polygene/runtime/composite/AbstractConstraintModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/composite/AbstractConstraintModel.java b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/AbstractConstraintModel.java new file mode 100644 index 0000000..0c058bd --- /dev/null +++ b/core/runtime/src/main/java/org/apache/polygene/runtime/composite/AbstractConstraintModel.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.polygene.runtime.composite; + +import java.lang.annotation.Annotation; +import org.apache.polygene.api.constraint.ConstraintDescriptor; +import org.apache.polygene.api.util.Visitable; +import org.apache.polygene.api.util.Visitor; + +/** + * JAVADOC + */ +public abstract class AbstractConstraintModel + implements ConstraintDescriptor, Visitable<ConstraintDescriptor> +{ + protected final Annotation annotation; + + public AbstractConstraintModel( Annotation annotation ) + { + this.annotation = annotation; + } + + @Override + public Annotation annotation() + { + return annotation; + } + + public abstract ConstraintInstance<?, ?> newInstance(); + + @Override + public <ThrowableType extends Throwable> boolean accept( Visitor<? super ConstraintDescriptor, ThrowableType> modelVisitor ) + throws ThrowableType + { + return modelVisitor.visit( this ); + } +} \ No newline at end of file
