http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerInstance.java index dec81c1..b515e38 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerInstance.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerInstance.java @@ -20,16 +20,11 @@ import java.util.stream.Stream; import org.apache.zest.api.activation.ActivationEventListener; import org.apache.zest.api.activation.ActivationException; import org.apache.zest.api.activation.PassivationException; -import org.apache.zest.api.common.Visibility; -import org.apache.zest.api.composite.TransientDescriptor; -import org.apache.zest.api.entity.EntityDescriptor; -import org.apache.zest.api.object.ObjectDescriptor; -import org.apache.zest.api.service.ServiceReference; +import org.apache.zest.api.structure.Application; import org.apache.zest.api.structure.Layer; +import org.apache.zest.api.structure.LayerDescriptor; import org.apache.zest.api.structure.Module; -import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.runtime.activation.ActivationDelegate; -import org.apache.zest.spi.structure.ModelModule; /** * Instance of a Zest application layer. Contains a list of modules which are managed by this layer. @@ -41,20 +36,18 @@ public class LayerInstance // Constructor parameters private final LayerModel layerModel; private final ApplicationInstance applicationInstance; - private final UsedLayersInstance usedLayersInstance; + // Eager instance objects private final ActivationDelegate activation; private final List<ModuleInstance> moduleInstances; public LayerInstance( LayerModel model, - ApplicationInstance applicationInstance, - UsedLayersInstance usedLayersInstance + ApplicationInstance applicationInstance ) { // Constructor parameters this.layerModel = model; this.applicationInstance = applicationInstance; - this.usedLayersInstance = usedLayersInstance; // Eager instance objects activation = new ActivationDelegate( this ); @@ -74,6 +67,12 @@ public class LayerInstance return layerModel.name(); } + @Override + public Application application() + { + return applicationInstance; + } + // Implementation of MetaInfoHolder @Override public <T> T metaInfo( Class<T> infoType ) @@ -114,51 +113,21 @@ public class LayerInstance return moduleInstances.stream(); } - // Other methods - /* package */ void addModule( ModuleInstance module ) - { - module.registerActivationEventListener( activation ); - moduleInstances.add( module ); - } - - /* package */ LayerModel model() + @Override + public LayerDescriptor descriptor() { return layerModel; } - public ApplicationInstance applicationInstance() - { - return applicationInstance; - } - - /* package */ UsedLayersInstance usedLayersInstance() + void addModule( ModuleInstance module ) { - return usedLayersInstance; - } - - /* package */ Stream<ModelModule<ObjectDescriptor>> visibleObjects( final Visibility visibility ) - { - return moduleInstances.stream().flatMap( module -> module.visibleObjects( visibility ) ); - } - - /* package */ Stream<ModelModule<TransientDescriptor>> visibleTransients( final Visibility visibility ) - { - return moduleInstances.stream().flatMap( module -> module.visibleTransients( visibility ) ); - } - - /* package */ Stream<ModelModule<EntityDescriptor>> visibleEntities( final Visibility visibility ) - { - return moduleInstances.stream().flatMap( module -> module.visibleEntities( visibility ) ); - } - - /* package */ Stream<ModelModule<ValueDescriptor>> visibleValues( final Visibility visibility ) - { - return moduleInstances.stream().flatMap( module -> module.visibleValues( visibility ) ); + module.registerActivationEventListener( activation ); + moduleInstances.add( module ); } - /* package */ Stream<ServiceReference<?>> visibleServices( final Visibility visibility ) + public LayerModel model() { - return moduleInstances.stream().flatMap( module -> module.visibleServices( visibility ) ); + return layerModel; } /* package */ ModuleInstance findModule( String moduleName )
http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerModel.java index 8592122..d883bfe 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerModel.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/LayerModel.java @@ -16,10 +16,17 @@ package org.apache.zest.runtime.structure; import java.util.List; +import java.util.stream.Stream; import org.apache.zest.api.activation.ActivationException; import org.apache.zest.api.common.MetaInfo; +import org.apache.zest.api.common.Visibility; +import org.apache.zest.api.composite.ModelDescriptor; +import org.apache.zest.api.composite.TransientDescriptor; +import org.apache.zest.api.entity.EntityDescriptor; +import org.apache.zest.api.object.ObjectDescriptor; import org.apache.zest.api.structure.Layer; import org.apache.zest.api.structure.LayerDescriptor; +import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.functional.HierarchicalVisitor; import org.apache.zest.functional.VisitableHierarchy; import org.apache.zest.runtime.activation.ActivatorsInstance; @@ -37,6 +44,7 @@ public final class LayerModel private final UsedLayersModel usedLayersModel; private final ActivatorsModel<Layer> activatorsModel; private final List<ModuleModel> modules; + private LayerInstance layerInstance; public LayerModel( String name, MetaInfo metaInfo, @@ -100,20 +108,57 @@ public final class LayerModel return modelVisitor.visitLeave( this ); } - // Context - public LayerInstance newInstance( ApplicationInstance applicationInstance, UsedLayersInstance usedLayerInstance ) + @Override + public Layer instance() { - LayerInstance layerInstance = new LayerInstance( this, applicationInstance, usedLayerInstance ); + return layerInstance; + } + + public LayerInstance newInstance( ApplicationInstance applicationInstance ) + { + layerInstance = new LayerInstance( this, applicationInstance ); for( ModuleModel module : modules ) { - ModuleInstance moduleInstance = module.newInstance( layerInstance ); + ModuleInstance moduleInstance = module.newInstance( this ); layerInstance.addModule( moduleInstance ); } - return layerInstance; } @Override + public Stream<? extends ObjectDescriptor> visibleObjects( final Visibility visibility ) + { + return modules.stream().flatMap( module -> module.visibleObjects( visibility ) ); + } + + @Override + public Stream<? extends TransientDescriptor> visibleTransients( final Visibility visibility ) + { + return modules.stream().flatMap( module -> module.visibleTransients( visibility ) ); + } + + @Override + public Stream<? extends EntityDescriptor> visibleEntities( final Visibility visibility ) + { + return modules.stream().flatMap( module -> module.visibleEntities( visibility ) ); + } + + /* package */ + @Override + public Stream<? extends ValueDescriptor> visibleValues( final Visibility visibility ) + { + return modules.stream().flatMap( module -> module.visibleValues( visibility ) ); + } + + /* package */ + @Override + public Stream<? extends ModelDescriptor> visibleServices( final Visibility visibility ) + { + return modules.stream().flatMap( module -> module.visibleServices( visibility ) ); + } + + + @Override public String toString() { return name; http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleClassLoader.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleClassLoader.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleClassLoader.java new file mode 100644 index 0000000..341dc79 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleClassLoader.java @@ -0,0 +1,182 @@ +/* + * 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.zest.runtime.structure; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; +import java.util.stream.Stream; +import org.apache.zest.api.common.Visibility; +import org.apache.zest.api.composite.AmbiguousTypeException; +import org.apache.zest.api.composite.ModelDescriptor; + +import static java.util.stream.Stream.concat; +import static org.apache.zest.api.common.Visibility.application; +import static org.apache.zest.api.common.Visibility.module; +import static org.apache.zest.api.util.Classes.modelTypeSpecification; + +// Module ClassLoader +class ModuleClassLoader + extends ClassLoader +{ + + private final ModuleModel moduleModel; + private final ConcurrentHashMap<String, Class<?>> classes = new ConcurrentHashMap<>(); + + ModuleClassLoader( ModuleModel moduleModel, ClassLoader classLoader ) + { + super( classLoader ); + this.moduleModel = moduleModel; + } + + @Override + protected Class<?> findClass( String className ) + throws ClassNotFoundException + { + try + { + Class<?> resultingClass = classes.computeIfAbsent( className, name -> + { + Predicate<ModelDescriptor> modelTypeSpecification = modelTypeSpecification( name ); + Stream<? extends ModelDescriptor> moduleModels = concat( + moduleModel.visibleObjects( Visibility.module ), + concat( + moduleModel.visibleEntities( Visibility.module ), + concat( + moduleModel.visibleTransients( Visibility.module ), + moduleModel.visibleValues( Visibility.module ) + ) + ) + ).filter( modelTypeSpecification ); + + Class<?> clazz = null; + Iterator<? extends ModelDescriptor> iterator = moduleModels.iterator(); + if( iterator.hasNext() ) + { + clazz = iterator.next().types().findFirst().orElse( null ); + + if( iterator.hasNext() ) + { + // Ambiguous exception + new AmbiguousTypeException( + "More than one model matches the classname " + name + ":" + iterator.next() + ); + } + } + + // Check layer + if( clazz == null ) + { + Stream<? extends ModelDescriptor> modelsInLayer1 = concat( + moduleModel.layer().visibleObjects( Visibility.layer ), + concat( + moduleModel.layer().visibleEntities( Visibility.layer ), + concat( + moduleModel.layer().visibleTransients( Visibility.layer ), + moduleModel.layer().visibleValues( Visibility.layer ) + ) + ) + ); + // TODO: What does this actually represents?? Shouldn't 'application' visible models already be handed back from lasyerInstance().visibleXyz() ?? + Stream<? extends ModelDescriptor> modelsInLayer2 = concat( + moduleModel.layer().visibleObjects( Visibility.application ), + concat( + moduleModel.layer().visibleEntities( Visibility.application ), + concat( + moduleModel.layer().visibleTransients( Visibility.application ), + moduleModel.layer().visibleValues( Visibility.application ) + ) + ) + ); + Stream<? extends ModelDescriptor> layerModels = concat( + modelsInLayer1, + modelsInLayer2 + ).filter( modelTypeSpecification ); + + Iterator<? extends ModelDescriptor> layerModelsIter = layerModels.iterator(); + if( layerModelsIter.hasNext() ) + { + clazz = layerModelsIter.next().types().findFirst().orElse( null ); + + if( layerModelsIter.hasNext() ) + { + // Ambiguous exception + new AmbiguousTypeException( + "More than one model matches the classname " + name + ":" + layerModelsIter.next() + ); + } + } + } + + // Check used layers + if( clazz == null ) + { + Stream<? extends ModelDescriptor> usedLayersModels = concat( + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleObjects( module ) ), + concat( + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleEntities( Visibility.layer ) ), + concat( + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleTransients( application ) ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleValues( application ) ) + ) + ) + ).filter( modelTypeSpecification ); + + Iterator<? extends ModelDescriptor> usedLayersModelsIter = usedLayersModels.iterator(); + if( usedLayersModelsIter.hasNext() ) + { + clazz = usedLayersModelsIter.next().types().findFirst().orElse( null ); + + if( usedLayersModelsIter.hasNext() ) + { + // Ambiguous exception + new AmbiguousTypeException( + "More than one model matches the classname " + name + ":" + usedLayersModelsIter.next() + ); + } + } + } + return clazz; + } ); + if( resultingClass == null ) + { + throw new ClassNotFoundException(); + } + return resultingClass; + } + catch( AmbiguousTypeException e ) + { + throw new ClassNotFoundException( className, e ); + } + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java index 4bf431f..a24e768 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleInstance.java @@ -19,28 +19,24 @@ package org.apache.zest.runtime.structure; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.NoSuchElementException; import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Stream; +import java.util.stream.Collectors; import org.apache.zest.api.activation.Activation; import org.apache.zest.api.activation.ActivationEventListener; import org.apache.zest.api.activation.ActivationException; import org.apache.zest.api.activation.PassivationException; import org.apache.zest.api.association.AssociationDescriptor; import org.apache.zest.api.common.ConstructionException; -import org.apache.zest.api.common.Visibility; -import org.apache.zest.api.composite.AmbiguousTypeException; import org.apache.zest.api.composite.Composite; import org.apache.zest.api.composite.ModelDescriptor; import org.apache.zest.api.composite.NoSuchTransientException; import org.apache.zest.api.composite.TransientBuilder; import org.apache.zest.api.composite.TransientDescriptor; -import org.apache.zest.api.entity.EntityDescriptor; import org.apache.zest.api.entity.EntityReference; import org.apache.zest.api.entity.IdentityGenerator; import org.apache.zest.api.metrics.MetricsProvider; @@ -50,11 +46,12 @@ import org.apache.zest.api.property.Property; import org.apache.zest.api.property.PropertyDescriptor; import org.apache.zest.api.query.QueryBuilder; import org.apache.zest.api.query.QueryBuilderFactory; -import org.apache.zest.api.service.ImportedServiceDescriptor; import org.apache.zest.api.service.NoSuchServiceException; -import org.apache.zest.api.service.ServiceDescriptor; import org.apache.zest.api.service.ServiceReference; +import org.apache.zest.api.structure.LayerDescriptor; import org.apache.zest.api.structure.Module; +import org.apache.zest.api.structure.ModuleDescriptor; +import org.apache.zest.api.structure.TypeLookup; import org.apache.zest.api.unitofwork.UnitOfWorkException; import org.apache.zest.api.unitofwork.UnitOfWorkFactory; import org.apache.zest.api.util.NullArgumentException; @@ -69,12 +66,9 @@ import org.apache.zest.runtime.composite.FunctionStateResolver; import org.apache.zest.runtime.composite.StateResolver; import org.apache.zest.runtime.composite.TransientBuilderInstance; import org.apache.zest.runtime.composite.TransientStateInstance; -import org.apache.zest.runtime.composite.TransientsModel; import org.apache.zest.runtime.composite.UsesInstance; -import org.apache.zest.runtime.entity.EntitiesModel; import org.apache.zest.runtime.injection.InjectionContext; import org.apache.zest.runtime.object.ObjectModel; -import org.apache.zest.runtime.object.ObjectsModel; import org.apache.zest.runtime.property.PropertyInstance; import org.apache.zest.runtime.property.PropertyModel; import org.apache.zest.runtime.query.QueryBuilderFactoryImpl; @@ -86,17 +80,11 @@ import org.apache.zest.runtime.value.ValueBuilderInstance; import org.apache.zest.runtime.value.ValueBuilderWithPrototype; import org.apache.zest.runtime.value.ValueBuilderWithState; import org.apache.zest.runtime.value.ValueInstance; -import org.apache.zest.runtime.value.ValuesModel; import org.apache.zest.spi.entitystore.EntityStore; import org.apache.zest.spi.metrics.MetricsProviderAdapter; import org.apache.zest.spi.module.ModuleSpi; -import org.apache.zest.spi.structure.ModelModule; -import org.apache.zest.valueserialization.orgjson.OrgJsonValueSerialization; -import static java.util.stream.Stream.concat; -import static org.apache.zest.api.util.Classes.modelTypeSpecification; import static org.apache.zest.functional.Iterables.iterable; -import static org.apache.zest.runtime.legacy.Specifications.translate; /** * Instance of a Zest Module. Contains the various composites for this Module. @@ -106,18 +94,13 @@ public class ModuleInstance { // Constructor parameters private final ModuleModel model; - private final LayerInstance layer; - private final TransientsModel transients; - private final ValuesModel values; - private final ObjectsModel objects; - private final EntitiesModel entities; + private final LayerDescriptor layer; + private final TypeLookup typeLookup; private final ServicesInstance services; private final ImportedServicesInstance importedServices; // Eager instance objects private final ActivationDelegate activation; - private final TypeLookupImpl typeLookup; private final QueryBuilderFactory queryBuilderFactory; - private final ClassLoader classLoader; // Lazy assigned on accessors private EntityStore store; private IdentityGenerator generator; @@ -126,26 +109,20 @@ public class ModuleInstance private UnitOfWorkFactory uowf; @SuppressWarnings( "LeakingThisInConstructor" ) - public ModuleInstance( ModuleModel moduleModel, LayerInstance layerInstance, TransientsModel transientsModel, - EntitiesModel entitiesModel, ObjectsModel objectsModel, ValuesModel valuesModel, + public ModuleInstance( ModuleModel moduleModel, LayerDescriptor layer, TypeLookup typeLookup, ServicesModel servicesModel, ImportedServicesModel importedServicesModel ) { // Constructor parameters model = moduleModel; - layer = layerInstance; - transients = transientsModel; - values = valuesModel; - entities = entitiesModel; - services = servicesModel.newInstance( this ); - objects = objectsModel; - importedServices = importedServicesModel.newInstance( this ); + this.layer = layer; + this.typeLookup = typeLookup; + services = servicesModel.newInstance( moduleModel ); + importedServices = importedServicesModel.newInstance( moduleModel ); // Eager instance objects activation = new ActivationDelegate( this ); - typeLookup = new TypeLookupImpl( this ); queryBuilderFactory = new QueryBuilderFactoryImpl( this ); - classLoader = new ModuleClassLoader( this, Thread.currentThread().getContextClassLoader() ); // Activation services.registerActivationEventListener( activation ); @@ -158,129 +135,17 @@ public class ModuleInstance return model.toString(); } - // Implementation of Module - @Override - public String name() - { - return model.name(); - } - - @Override - public ClassLoader classLoader() - { - return classLoader; - } - - @Override - public EntityDescriptor entityDescriptor( String name ) - { - try - { - Class<?> type = classLoader().loadClass( name ); - ModelModule<EntityDescriptor> entityModel = typeLookup.lookupEntityModel( type ); - if( entityModel == null ) - { - return null; - } - return entityModel.model(); - } - catch( ClassNotFoundException e ) - { - return null; - } - } - - @Override - public ObjectDescriptor objectDescriptor( String typeName ) - { - try - { - Class<?> type = classLoader().loadClass( typeName ); - ModelModule<ObjectDescriptor> objectModel = typeLookup.lookupObjectModel( type ); - if( objectModel == null ) - { - return null; - } - return objectModel.model(); - } - catch( ClassNotFoundException e ) - { - return null; - } - } - - @Override - public TransientDescriptor transientDescriptor( String name ) - { - try - { - Class<?> type = classLoader().loadClass( name ); - ModelModule<TransientDescriptor> transientModel = typeLookup.lookupTransientModel( type ); - if( transientModel == null ) - { - return null; - } - return transientModel.model(); - } - catch( ClassNotFoundException e ) - { - return null; - } - } - @Override - public ValueDescriptor valueDescriptor( String name ) + public ModuleDescriptor descriptor() { - try - { - Class<?> type = classLoader().loadClass( name ); - ModelModule<ValueDescriptor> valueModel = typeLookup.lookupValueModel( type ); - if( valueModel == null ) - { - return null; - } - return valueModel.model(); - } - catch( ClassNotFoundException e ) - { - return null; - } - } - - @Override - public Stream<? extends TransientDescriptor> transientComposites() - { - return transients.stream(); - } - - @Override - public Stream<? extends ValueDescriptor> valueComposites() - { - return values.stream(); - } - - @Override - public Stream<? extends ServiceDescriptor> serviceComposites() - { - return services.stream(); - } - - @Override - public Stream<? extends EntityDescriptor> entityComposites() - { - return entities.stream(); - } - - @Override - public Stream<? extends ImportedServiceDescriptor> importedServices() - { - return importedServices.stream(); + return model; } + // Implementation of Module @Override - public Stream<? extends ObjectDescriptor> objects() + public String name() { - return objects.stream(); + return model.name(); } // Implementation of MetaInfoHolder @@ -296,15 +161,15 @@ public class ModuleInstance throws NoSuchObjectException { NullArgumentException.validateNotNull( "mixinType", mixinType ); - ModelModule<ObjectDescriptor> modelModule = typeLookup.lookupObjectModel( mixinType ); + ObjectDescriptor model = typeLookup.lookupObjectModel( mixinType ); - if( modelModule == null ) + if( model == null ) { throw new NoSuchObjectException( mixinType.getName(), name(), typeLookup.allVisibleObjects() ); } - InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) ); - return mixinType.cast( ( (ObjectModel) modelModule.model() ).newInstance( injectionContext ) ); + InjectionContext injectionContext = new InjectionContext( model.module(), UsesInstance.EMPTY_USES.use( uses ) ); + return mixinType.cast( ( (ObjectModel) model ).newInstance( injectionContext ) ); } @Override @@ -312,15 +177,15 @@ public class ModuleInstance throws ConstructionException { NullArgumentException.validateNotNull( "instance", instance ); - ModelModule<ObjectDescriptor> modelModule = typeLookup.lookupObjectModel( instance.getClass() ); + ObjectDescriptor model = typeLookup.lookupObjectModel( instance.getClass() ); - if( modelModule == null ) + if( model == null ) { throw new NoSuchObjectException( instance.getClass().getName(), name(), typeLookup.allVisibleObjects() ); } - InjectionContext injectionContext = new InjectionContext( modelModule.module(), UsesInstance.EMPTY_USES.use( uses ) ); - ( (ObjectModel) modelModule.model() ).inject( injectionContext, instance ); + InjectionContext injectionContext = new InjectionContext( model.module(), UsesInstance.EMPTY_USES.use( uses ) ); + ( (ObjectModel) model ).inject( injectionContext, instance ); } // Implementation of TransientBuilderFactory @@ -329,25 +194,25 @@ public class ModuleInstance throws NoSuchTransientException { NullArgumentException.validateNotNull( "mixinType", mixinType ); - ModelModule<TransientDescriptor> modelModule = typeLookup.lookupTransientModel( mixinType ); + TransientDescriptor model = typeLookup.lookupTransientModel( mixinType ); - if( modelModule == null ) + if( model == null ) { throw new NoSuchTransientException( mixinType.getName(), name() ); } Map<AccessibleObject, Property<?>> properties = new HashMap<>(); - modelModule.model().state().properties().forEach( + model.state().properties().forEach( propertyModel -> { Property<?> property = new PropertyInstance<>( ( (PropertyModel) propertyModel ).getBuilderInfo(), - propertyModel.initialValue( modelModule.module() ) ); + propertyModel.initialValue( model.module() ) ); properties.put( propertyModel.accessor(), property ); } ); TransientStateInstance state = new TransientStateInstance( properties ); - return new TransientBuilderInstance<>( modelModule, state, UsesInstance.EMPTY_USES ); + return new TransientBuilderInstance<>( model, state, UsesInstance.EMPTY_USES ); } @Override @@ -370,7 +235,7 @@ public class ModuleInstance throws NoSuchValueException { NullArgumentException.validateNotNull( "mixinType", mixinType ); - ModelModule<ValueDescriptor> compositeModelModule = typeLookup.lookupValueModel( mixinType ); + ValueDescriptor compositeModelModule = typeLookup.lookupValueModel( mixinType ); if( compositeModelModule == null ) { @@ -394,7 +259,7 @@ public class ModuleInstance NullArgumentException.validateNotNull( "manyAssociationFunction", manyAssociationFunction ); NullArgumentException.validateNotNull( "namedAssociationFunction", namedAssociationFunction ); - ModelModule<ValueDescriptor> compositeModelModule = typeLookup.lookupValueModel( mixinType ); + ValueDescriptor compositeModelModule = typeLookup.lookupValueModel( mixinType ); if( compositeModelModule == null ) { @@ -410,9 +275,9 @@ public class ModuleInstance private static class InitialStateResolver implements StateResolver { - private final Module module; + private final ModuleDescriptor module; - private InitialStateResolver( Module module ) + private InitialStateResolver( ModuleDescriptor module ) { this.module = module; } @@ -451,14 +316,14 @@ public class ModuleInstance ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) prototype ); Class<Composite> valueType = (Class<Composite>) valueInstance.types().findFirst().orElse( null ); - ModelModule<ValueDescriptor> modelModule = typeLookup.lookupValueModel( valueType ); + ValueDescriptor model = typeLookup.lookupValueModel( valueType ); - if( modelModule == null ) + if( model == null ) { throw new NoSuchValueException( valueType.getName(), name() ); } - return new ValueBuilderWithPrototype<>( modelModule, this, prototype ); + return new ValueBuilderWithPrototype<>( model, this, prototype ); } @Override @@ -466,16 +331,16 @@ public class ModuleInstance throws NoSuchValueException, ConstructionException { NullArgumentException.validateNotNull( "mixinType", mixinType ); - ModelModule<ValueDescriptor> modelModule = typeLookup.lookupValueModel( mixinType ); + ValueDescriptor model = typeLookup.lookupValueModel( mixinType ); - if( modelModule == null ) + if( model == null ) { throw new NoSuchValueException( mixinType.getName(), name() ); } try { - return valueSerialization().deserialize( modelModule.model().valueType(), serializedState ); + return valueSerialization().deserialize( model.module(), model.valueType(), serializedState ); } catch( ValueSerializationException ex ) { @@ -490,29 +355,59 @@ public class ModuleInstance return queryBuilderFactory.newQueryBuilder( resultType ); } - // Implementation of ServiceFinder @Override public <T> ServiceReference<T> findService( Class<T> serviceType ) + throws NoSuchServiceException { - return typeLookup.lookupServiceReference( serviceType ); + return findService( (Type) serviceType ); } @Override public <T> ServiceReference<T> findService( Type serviceType ) { - return typeLookup.lookupServiceReference( serviceType ); + ModelDescriptor serviceModel = typeLookup.lookupServiceModel( serviceType ); + if( serviceModel == null ) + { + throw new NoSuchServiceException( serviceType.getTypeName(), name() ); + } + ModuleInstance serviceLocation = (ModuleInstance) serviceModel.module().instance(); + try + { + //noinspection unchecked + return serviceLocation.services + .references() + .filter( ref -> ref.hasType( serviceType ) ) + .map( ref -> (ServiceReference<T>) ref ) + .findAny().get(); + } + catch( NoSuchElementException e ) + { + throw new NoSuchServiceException( serviceType.getTypeName(), name() ); + } } @Override public <T> Iterable<ServiceReference<T>> findServices( Class<T> serviceType ) { - return typeLookup.lookupServiceReferences( serviceType ); + return findServices( (Type) serviceType ); } @Override public <T> Iterable<ServiceReference<T>> findServices( Type serviceType ) { - return typeLookup.lookupServiceReferences( serviceType ); + List<? extends ModelDescriptor> serviceModels = typeLookup.lookupServiceModels( serviceType ); + if( serviceModels == null ) + { + return Collections.emptyList(); + } + //noinspection unchecked + return serviceModels.stream() + .flatMap( + model -> ( (ModuleInstance) model.module().instance() ).services.references() + ) + .filter( ref -> ref.hasType( serviceType ) ) + .map( ref -> (ServiceReference<T>) ref ) + .collect( Collectors.toList() ); } // Implementation of Activation @@ -544,18 +439,18 @@ public class ModuleInstance } // Other methods - /* package */ ModuleModel model() + ModuleModel model() { return model; } - public LayerInstance layerInstance() + public LayerDescriptor layer() { return layer; } @Override - public TypeLookupImpl typeLookup() + public TypeLookup typeLookup() { return typeLookup; } @@ -566,16 +461,15 @@ public class ModuleInstance { if( store == null ) { - ServiceReference<EntityStore> service = null; try { - service = findService( EntityStore.class ); + ServiceReference<EntityStore> service = findService( EntityStore.class ); + store = service.get(); } catch( NoSuchServiceException e ) { throw new UnitOfWorkException( "No EntityStore service available in module " + name() ); } - store = service.get(); } } return store; @@ -587,16 +481,15 @@ public class ModuleInstance { if( uowf == null ) { - ServiceReference<UnitOfWorkFactory> service = null; try { - service = findService( UnitOfWorkFactory.class ); + ServiceReference<UnitOfWorkFactory> service = findService( UnitOfWorkFactory.class ); + uowf = service.get(); } catch( NoSuchServiceException e ) { throw new UnitOfWorkException( "No UnitOfWorkFactory service available in module " + name() ); } - uowf = service.get(); } } return uowf; @@ -628,7 +521,7 @@ public class ModuleInstance } catch( NoSuchServiceException e ) { - valueSerialization = new OrgJsonValueSerialization( layer.applicationInstance(), this, this ); + throw new ValueSerializationException( "No ValueSeriaservice available in module " + name() ); } } } @@ -655,242 +548,24 @@ public class ModuleInstance return metrics; } - public Stream<ModelModule<ObjectDescriptor>> visibleObjects( Visibility visibility ) - { - return objects.stream() - .filter( new Visibilitypredicate( visibility ) ) - .map( ModelModule.<ObjectDescriptor>modelModuleFunction( this ) ); - } - - public Stream<ModelModule<TransientDescriptor>> visibleTransients( Visibility visibility ) - { - return transients.models() - .filter( new Visibilitypredicate( visibility ) ) - .map( ModelModule.<TransientDescriptor>modelModuleFunction( this ) ); - } - - public Stream<ModelModule<EntityDescriptor>> visibleEntities( Visibility visibility ) - { - return entities.models() - .filter( new Visibilitypredicate( visibility ) ) - .map( ModelModule.<EntityDescriptor>modelModuleFunction( this ) ); - } - - public Stream<ModelModule<ValueDescriptor>> visibleValues( Visibility visibility ) - { - return values.models() - .filter( new Visibilitypredicate( visibility ) ) - .map( ModelModule.<ValueDescriptor>modelModuleFunction( this ) ); - } - - public Stream<ServiceReference<?>> visibleServices( Visibility visibility ) - { - return concat( services.visibleServices( visibility ), - importedServices.visibleServices( visibility ) ); - } - - // Module ClassLoader - private static class ModuleClassLoader - extends ClassLoader - { - - private final ModuleInstance moduleInstance; - private final Map<String, Class<?>> classes = new ConcurrentHashMap<>(); - - private ModuleClassLoader( ModuleInstance moduleInstance, ClassLoader classLoader ) - { - super( classLoader ); - this.moduleInstance = moduleInstance; - } - - @Override - protected Class<?> findClass( String name ) - throws ClassNotFoundException - { - Class<?> clazz = classes.get( name ); - if( clazz == null ) - { - Predicate<ModelDescriptor> modelTypeSpecification = modelTypeSpecification( name ); - Predicate<ModelModule<? extends ModelDescriptor>> translation = translate( ModelModule.modelFunction(), modelTypeSpecification ); - Stream<ModelModule<? extends ModelDescriptor>> moduleModels = concat( - moduleInstance.visibleObjects( Visibility.module ), - concat( - moduleInstance.visibleEntities( Visibility.module ), - concat( - moduleInstance.visibleTransients( Visibility.module ), - moduleInstance.visibleValues( Visibility.module ) - ) - ) - ).filter( translation ); - - Iterator<ModelModule<? extends ModelDescriptor>> moduleModelsIter = moduleModels.iterator(); - if( moduleModelsIter.hasNext() ) - { - clazz = moduleModelsIter.next().model().types().findFirst().orElse( null ); - - if( moduleModelsIter.hasNext() ) - { - // Ambiguous exception - throw new ClassNotFoundException( - name, - new AmbiguousTypeException( - "More than one model matches the classname " + name + ":" + moduleModelsIter.next() - ) - ); - } - } - - // Check layer - if( clazz == null ) - { - Stream<ModelModule<? extends ModelDescriptor>> modelsInLayer1 = concat( - moduleInstance.layerInstance().visibleObjects( Visibility.layer ), - concat( - moduleInstance.layerInstance().visibleEntities( Visibility.layer ), - concat( - moduleInstance.layerInstance().visibleTransients( Visibility.layer ), - moduleInstance.layerInstance().visibleValues( Visibility.layer ) - ) - ) - ); - // TODO: What does this actually represents?? Shouldn't 'application' visible models already be handed back from lasyerInstance().visibleXyz() ?? - Stream<ModelModule<? extends ModelDescriptor>> modelsInLayer2 = concat( - moduleInstance.layerInstance().visibleObjects( Visibility.application ), - concat( - moduleInstance.layerInstance().visibleEntities( Visibility.application ), - concat( - moduleInstance.layerInstance().visibleTransients( Visibility.application ), - moduleInstance.layerInstance().visibleValues( Visibility.application ) - ) - ) - ); - Stream<ModelModule<? extends ModelDescriptor>> layerModels = concat( - modelsInLayer1, - modelsInLayer2 - ).filter( translation ); - - Iterator<ModelModule<? extends ModelDescriptor>> layerModelsIter = layerModels.iterator(); - if( layerModelsIter.hasNext() ) - { - clazz = layerModelsIter.next().model().types().findFirst().orElse( null ); - - if( layerModelsIter.hasNext() ) - { - // Ambiguous exception - throw new ClassNotFoundException( - name, - new AmbiguousTypeException( - "More than one model matches the classname " + name + ":" + layerModelsIter.next() ) - ); - } - } - } - - // Check used layers - if( clazz == null ) - { - Stream<ModelModule<? extends ModelDescriptor>> usedLayersModels = concat( - moduleInstance.layerInstance().usedLayersInstance().visibleObjects(), - concat( - moduleInstance.layerInstance().usedLayersInstance().visibleEntities(), - concat( - moduleInstance.layerInstance().usedLayersInstance().visibleTransients(), - moduleInstance.layerInstance().usedLayersInstance().visibleValues() - ) - ) - ).filter( translation ); - - Iterator<ModelModule<? extends ModelDescriptor>> usedLayersModelsIter = usedLayersModels.iterator(); - if( usedLayersModelsIter.hasNext() ) - { - clazz = usedLayersModelsIter.next().model().types().findFirst().orElse( null ); - - if( usedLayersModelsIter.hasNext() ) - { - // Ambiguous exception - throw new ClassNotFoundException( - name, - new AmbiguousTypeException( - "More than one model matches the classname " + name + ":" + usedLayersModelsIter.next() - ) - ); - } - } - } - - if( clazz == null ) - { - throw new ClassNotFoundException( name ); - } - classes.put( name, clazz ); - } - - return clazz; - } - } - - public Stream<ModelModule<? extends ModelDescriptor>> findVisibleValueTypes() - { - return concat( visibleValues( Visibility.module ), - concat( - layerInstance().visibleValues( Visibility.layer ), - concat( - layerInstance().visibleValues( Visibility.application ), - layerInstance().usedLayersInstance().visibleValues() - ) - ) - ); - } - - public Stream<ModelModule<? extends ModelDescriptor>> findVisibleEntityTypes() - { - return concat( visibleEntities( Visibility.module ), - concat( - layerInstance().visibleEntities( Visibility.layer ), - concat( - layerInstance().visibleEntities( Visibility.application ), - layerInstance().usedLayersInstance().visibleEntities() - ) - ) - ); - } - - public Stream<ModelModule<? extends ModelDescriptor>> findVisibleTransientTypes() - { - return concat( visibleTransients( Visibility.module ), - concat( - layerInstance().visibleTransients( Visibility.layer ), - concat( - layerInstance().visibleTransients( Visibility.application ), - layerInstance().usedLayersInstance().visibleTransients() - ) - ) - ); - } - - public Stream<ServiceReference<?>> findVisibleServiceTypes() - { - return concat( visibleServices( Visibility.module ), - concat( - layerInstance().visibleServices( Visibility.layer ), - concat( - layerInstance().visibleServices( Visibility.application ), - layerInstance().usedLayersInstance().visibleServices() - ) - ) - ); - } - - public Stream<ModelModule<? extends ModelDescriptor>> findVisibleObjectTypes() - { - return concat( visibleObjects( Visibility.module ), - concat( - layerInstance().visibleObjects( Visibility.layer ), - concat( - layerInstance().visibleObjects( Visibility.application ), - layerInstance().usedLayersInstance().visibleObjects() - ) - ) - ); - } +// public Stream<ServiceReference<?>> visibleServices( Visibility visibility ) +// { +// return concat( services.visibleServices( visibility ), +// importedServices.visibleServices( visibility ) ); +// } +// +// +// +// public Stream<ServiceReference<?>> findVisibleServiceTypes() +// { +// return concat( visibleServices( Visibility.module ), +// concat( +// layer().visibleServices( Visibility.layer ), +// concat( +// layer().visibleServices( Visibility.application ), +// layer().usedLayers().layers().flatMap( layer -> layer.visibleServices(Visibility.application) ) +// ) +// ) +// ); +// } } http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleModel.java index 49e3670..85fceec 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleModel.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/ModuleModel.java @@ -15,10 +15,21 @@ */ package org.apache.zest.runtime.structure; +import java.util.stream.Stream; import org.apache.zest.api.activation.ActivationException; import org.apache.zest.api.common.MetaInfo; +import org.apache.zest.api.common.Visibility; +import org.apache.zest.api.composite.ModelDescriptor; +import org.apache.zest.api.composite.TransientDescriptor; +import org.apache.zest.api.entity.EntityDescriptor; +import org.apache.zest.api.object.ObjectDescriptor; +import org.apache.zest.api.service.ImportedServiceDescriptor; +import org.apache.zest.api.service.ServiceDescriptor; +import org.apache.zest.api.structure.LayerDescriptor; import org.apache.zest.api.structure.Module; import org.apache.zest.api.structure.ModuleDescriptor; +import org.apache.zest.api.structure.TypeLookup; +import org.apache.zest.api.value.ValueDescriptor; import org.apache.zest.functional.HierarchicalVisitor; import org.apache.zest.functional.VisitableHierarchy; import org.apache.zest.runtime.activation.ActivatorsInstance; @@ -30,12 +41,18 @@ import org.apache.zest.runtime.service.ImportedServicesModel; import org.apache.zest.runtime.service.ServicesModel; import org.apache.zest.runtime.value.ValuesModel; +import static java.util.stream.Stream.concat; +import static org.apache.zest.api.common.Visibility.application; +import static org.apache.zest.api.common.Visibility.layer; +import static org.apache.zest.api.common.Visibility.module; + /** * JAVADOC */ public class ModuleModel implements ModuleDescriptor, VisitableHierarchy<Object, Object> { + private final LayerDescriptor layerModel; private final ActivatorsModel<Module> activatorsModel; private final TransientsModel transientsModel; private final EntitiesModel entitiesModel; @@ -43,12 +60,16 @@ public class ModuleModel private final ValuesModel valuesModel; private final ServicesModel servicesModel; private final ImportedServicesModel importedServicesModel; + private final TypeLookupImpl typeLookup; + private final ClassLoader classLoader; private final String name; private final MetaInfo metaInfo; + private ModuleInstance moduleInstance; public ModuleModel( String name, MetaInfo metaInfo, + LayerDescriptor layerModel, ActivatorsModel<Module> activatorsModel, TransientsModel transientsModel, EntitiesModel entitiesModel, @@ -60,6 +81,7 @@ public class ModuleModel { this.name = name; this.metaInfo = metaInfo; + this.layerModel = layerModel; this.activatorsModel = activatorsModel; this.transientsModel = transientsModel; this.entitiesModel = entitiesModel; @@ -67,6 +89,8 @@ public class ModuleModel this.valuesModel = valuesModel; this.servicesModel = servicesModel; this.importedServicesModel = importedServicesModel; + typeLookup = new TypeLookupImpl( this ); + classLoader = new ModuleClassLoader( this, Thread.currentThread().getContextClassLoader() ); } @Override @@ -80,6 +104,18 @@ public class ModuleModel return metaInfo.get( infoType ); } + @Override + public LayerDescriptor layer() + { + return layerModel; + } + + @Override + public ClassLoader classLoader() + { + return classLoader; + } + public ActivatorsInstance<Module> newActivatorsInstance() throws ActivationException { @@ -87,6 +123,237 @@ public class ModuleModel } @Override + public EntityDescriptor entityDescriptor( String name ) + { + try + { + Class<?> type = classLoader().loadClass( name ); + EntityDescriptor entityModel = typeLookup.lookupEntityModel( type ); + if( entityModel == null ) + { + return null; + } + return entityModel; + } + catch( ClassNotFoundException e ) + { + return null; + } + } + + @Override + public ObjectDescriptor objectDescriptor( String typeName ) + { + try + { + Class<?> type = classLoader().loadClass( typeName ); + ObjectDescriptor objectModel = typeLookup.lookupObjectModel( type ); + if( objectModel == null ) + { + return null; + } + return objectModel; + } + catch( ClassNotFoundException e ) + { + return null; + } + } + + @Override + public TransientDescriptor transientDescriptor( String name ) + { + try + { + Class<?> type = classLoader().loadClass( name ); + TransientDescriptor transientModel = typeLookup.lookupTransientModel( type ); + if( transientModel == null ) + { + return null; + } + return transientModel; + } + catch( ClassNotFoundException e ) + { + return null; + } + } + + @Override + public ValueDescriptor valueDescriptor( String name ) + { + try + { + Class<?> type = classLoader().loadClass( name ); + ValueDescriptor valueModel = typeLookup.lookupValueModel( type ); + if( valueModel == null ) + { + return null; + } + return valueModel; + } + catch( ClassNotFoundException e ) + { + return null; + } + } + + @Override + public Module instance() + { + return moduleInstance; + } + + @Override + public TypeLookup typeLookup() + { + return typeLookup; + } + + public ModuleInstance newInstance( LayerDescriptor layerInstance ) + { + moduleInstance = new ModuleInstance( this, layerInstance, typeLookup, servicesModel, importedServicesModel ); + return moduleInstance; + } + + @Override + public Stream<? extends TransientDescriptor> transientComposites() + { + return transientsModel.stream(); + } + + @Override + public Stream<? extends ValueDescriptor> valueComposites() + { + return valuesModel.stream(); + } + + @Override + public Stream<? extends ServiceDescriptor> serviceComposites() + { + return servicesModel.models(); + } + + @Override + public Stream<? extends EntityDescriptor> entityComposites() + { + return entitiesModel.stream(); + } + + @Override + public Stream<? extends ImportedServiceDescriptor> importedServices() + { + return importedServicesModel.models(); + } + + @Override + public Stream<? extends ObjectDescriptor> objects() + { + return objectsModel.models(); + } + + public Stream<? extends ValueDescriptor> findVisibleValueTypes() + { + return concat( visibleValues( module ), + concat( + layer().visibleValues( layer ), + concat( + layer().visibleValues( application ), + layer().usedLayers().layers().flatMap( layer1 -> layer1.visibleValues( application ) ) + ) + ) + ); + } + + public Stream<? extends EntityDescriptor> findVisibleEntityTypes() + { + return concat( visibleEntities( module ), + concat( + layer().visibleEntities( layer ), + concat( + layer().visibleEntities( application ), + layer().usedLayers().layers().flatMap( layer1 -> layer1.visibleEntities( application ) ) + ) + ) + ); + } + + public Stream<? extends TransientDescriptor> findVisibleTransientTypes() + { + return concat( visibleTransients( module ), + concat( + layer().visibleTransients( layer ), + concat( + layer().visibleTransients( application ), + layer().usedLayers() + .layers() + .flatMap( layer1 -> layer1.visibleTransients( application ) ) + ) + ) + ); + } + + public Stream<? extends ModelDescriptor> findVisibleServiceTypes() + { + return concat( visibleServices( module ), + concat( + layer().visibleServices( layer ), + concat( + layer().visibleServices( application ), + layer().usedLayers().layers().flatMap( layer1 -> layer1.visibleServices( application ) ) + ) + ) + ); + } + + public Stream<? extends ObjectDescriptor> findVisibleObjectTypes() + { + return concat( visibleObjects( module ), + concat( + layer().visibleObjects( layer ), + concat( + layer().visibleObjects( application ), + layer().usedLayers().layers().flatMap( layer -> layer.visibleObjects( application ) ) + ) + ) + ); + } + + public Stream<? extends ObjectDescriptor> visibleObjects( Visibility visibility ) + { + return objectsModel.models() + .filter( new Visibilitypredicate( visibility ) ); + } + + public Stream<? extends TransientDescriptor> visibleTransients( Visibility visibility ) + { + return transientsModel.models() + .filter( new Visibilitypredicate( visibility ) ); + } + + public Stream<? extends EntityDescriptor> visibleEntities( Visibility visibility ) + { + return entitiesModel.models() + .filter( new Visibilitypredicate( visibility ) ); + } + + public Stream<? extends ValueDescriptor> visibleValues( Visibility visibility ) + { + return valuesModel.models() + .filter( new Visibilitypredicate( visibility ) ); + } + + public Stream<? extends ModelDescriptor> visibleServices( Visibility visibility ) + { + return concat( + servicesModel.models() + .filter( new Visibilitypredicate( visibility ) ), + importedServicesModel.models() + .filter( new Visibilitypredicate( visibility ) ) + ); + } + + @Override public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> modelVisitor ) throws ThrowableType { @@ -115,13 +382,6 @@ public class ModuleModel return modelVisitor.visitLeave( this ); } - // Context - - public ModuleInstance newInstance( LayerInstance layerInstance ) - { - return new ModuleInstance( this, layerInstance, transientsModel, entitiesModel, objectsModel, valuesModel, servicesModel, importedServicesModel ); - } - @Override public String toString() { http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java index 7835aaa..0d3c740 100755 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookupImpl.java @@ -22,9 +22,7 @@ package org.apache.zest.runtime.structure; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; -import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -35,18 +33,14 @@ import org.apache.zest.api.composite.ModelDescriptor; import org.apache.zest.api.composite.TransientDescriptor; import org.apache.zest.api.entity.EntityDescriptor; import org.apache.zest.api.object.ObjectDescriptor; -import org.apache.zest.api.service.NoSuchServiceException; -import org.apache.zest.api.service.ServiceReference; +import org.apache.zest.api.structure.ModuleDescriptor; +import org.apache.zest.api.structure.TypeLookup; import org.apache.zest.api.type.HasTypes; import org.apache.zest.api.value.ValueDescriptor; -import org.apache.zest.spi.structure.ModelModule; -import org.apache.zest.spi.structure.TypeLookup; import static java.util.stream.Stream.concat; import static org.apache.zest.api.common.Visibility.application; import static org.apache.zest.api.common.Visibility.layer; -import static org.apache.zest.api.common.Visibility.module; -import static org.apache.zest.api.util.Classes.RAW_CLASS; import static org.apache.zest.api.util.Classes.interfacesOf; import static org.apache.zest.functional.Iterables.first; @@ -58,25 +52,26 @@ public class TypeLookupImpl { // Constructor parameters - private final ModuleInstance moduleInstance; + private final ModuleDescriptor moduleModel; + // Eager instance objects - private final Map<Class<?>, ModelModule<ObjectDescriptor>> objectModels; - private final Map<Class<?>, ModelModule<TransientDescriptor>> transientModels; - private final Map<Class<?>, ModelModule<ValueDescriptor>> valueModels; - private final Map<Class<?>, List<ModelModule<EntityDescriptor>>> allEntityModels; - private final Map<Class<?>, ModelModule<EntityDescriptor>> unambiguousEntityModels; - private final Map<Type, ServiceReference<?>> serviceReferences; - private final Map<Type, List<ServiceReference<?>>> servicesReferences; + private final ConcurrentHashMap<Class<?>, ObjectDescriptor> objectModels; + private final ConcurrentHashMap<Class<?>, TransientDescriptor> transientModels; + private final ConcurrentHashMap<Class<?>, ValueDescriptor> valueModels; + private final ConcurrentHashMap<Class<?>, List<? extends EntityDescriptor>> allEntityModels; + private final ConcurrentHashMap<Class<?>, EntityDescriptor> unambiguousEntityModels; + private final ConcurrentHashMap<Type, ModelDescriptor> serviceModels; + private final ConcurrentHashMap<Type, List<ModelDescriptor>> servicesReferences; /** - * Create a new TypeLookup bound to the given ModuleInstance. + * Create a new TypeLookup bound to the given moduleModel. * - * @param moduleInstance ModuleInstance bound to this TypeLookup + * @param module ModuleModel bound to this TypeLookup */ - TypeLookupImpl( ModuleInstance moduleInstance ) + TypeLookupImpl( ModuleModel module ) { // Constructor parameters - this.moduleInstance = moduleInstance; + this.moduleModel = module; // Eager instance objects objectModels = new ConcurrentHashMap<>(); @@ -84,7 +79,7 @@ public class TypeLookupImpl valueModels = new ConcurrentHashMap<>(); allEntityModels = new ConcurrentHashMap<>(); unambiguousEntityModels = new ConcurrentHashMap<>(); - serviceReferences = new ConcurrentHashMap<>(); + serviceModels = new ConcurrentHashMap<>(); servicesReferences = new ConcurrentHashMap<>(); } @@ -103,23 +98,19 @@ public class TypeLookupImpl * * @return First matching Object Model */ - ModelModule<ObjectDescriptor> lookupObjectModel( final Class type ) + @Override + public ObjectDescriptor lookupObjectModel( final Class<?> type ) { - ModelModule<ObjectDescriptor> model = objectModels.get( type ); - if( model == null ) + return objectModels.computeIfAbsent( type, key -> { - List<ModelModule<ObjectDescriptor>> allModels = allObjects().collect( Collectors.toList() ); - model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) ); + List<ObjectDescriptor> allModels = allObjects().collect( Collectors.toList() ); + ObjectDescriptor model = ambiguityMatching( key, allModels, new ExactTypeMatching<>( key ) ); if( model == null ) { - model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) ); - } - if( model != null ) - { - objectModels.put( type, model ); + model = ambiguityMatching( key, allModels, new AssignableFromTypeMatching<>( key ) ); } - } - return model; + return model; + } ); } /** @@ -137,23 +128,19 @@ public class TypeLookupImpl * * @return First matching Transient Model */ - ModelModule<TransientDescriptor> lookupTransientModel( final Class type ) + @Override + public TransientDescriptor lookupTransientModel( final Class<?> type ) { - ModelModule<TransientDescriptor> model = transientModels.get( type ); - if( model == null ) + return transientModels.computeIfAbsent( type, key -> { - List<ModelModule<TransientDescriptor>> allModels = allTransients().collect( Collectors.toList() ); - model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) ); + List<TransientDescriptor> allModels = allTransients().collect( Collectors.toList() ); + TransientDescriptor model = ambiguityMatching( key, allModels, new ExactTypeMatching<>( key ) ); if( model == null ) { - model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) ); - } - if( model != null ) - { - transientModels.put( type, model ); + model = ambiguityMatching( key, allModels, new AssignableFromTypeMatching<>( key ) ); } - } - return model; + return model; + } ); } /** @@ -171,23 +158,19 @@ public class TypeLookupImpl * * @return First matching Value Model */ - public ModelModule<ValueDescriptor> lookupValueModel( final Class type ) + @Override + public ValueDescriptor lookupValueModel( final Class<?> type ) { - ModelModule<ValueDescriptor> model = valueModels.get( type ); - if( model == null ) + return valueModels.computeIfAbsent( type, key -> { - List<ModelModule<ValueDescriptor>> allModels = allValues().collect( Collectors.toList() ); - model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) ); + List<ValueDescriptor> allModels = allValues().collect( Collectors.toList() ); + ValueDescriptor model = ambiguityMatching( key, allModels, new ExactTypeMatching<>( key ) ); if( model == null ) { - model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) ); - } - if( model != null ) - { - valueModels.put( type, model ); + model = ambiguityMatching( key, allModels, new AssignableFromTypeMatching<>( key ) ); } - } - return model; + return model; + } ); } /** @@ -209,24 +192,18 @@ public class TypeLookupImpl * @return First matching Entity Model */ @Override - public ModelModule<EntityDescriptor> lookupEntityModel( final Class type ) + public EntityDescriptor lookupEntityModel( final Class<?> type ) { - ModelModule<EntityDescriptor> model = unambiguousEntityModels.get( type ); - - if( model == null ) + return unambiguousEntityModels.computeIfAbsent( type, key -> { - List<ModelModule<EntityDescriptor>> allModels = allEntities().collect( Collectors.toList() ); - model = ambiguityMatching( type, allModels, new ExactTypeMatching<>( type ) ); + List<EntityDescriptor> allModels = allEntities().collect( Collectors.toList() ); + EntityDescriptor model = ambiguityMatching( key, allModels, new ExactTypeMatching<>( key ) ); if( model == null ) { - model = ambiguityMatching( type, allModels, new AssignableFromTypeMatching<>( type ) ); - } - if( model != null ) - { - unambiguousEntityModels.put( type, model ); + model = ambiguityMatching( key, allModels, new AssignableFromTypeMatching<>( key ) ); } - } - return model; + return model; + } ); } /** @@ -252,179 +229,161 @@ public class TypeLookupImpl * @return All matching Entity Models */ @Override - public Iterable<ModelModule<EntityDescriptor>> lookupEntityModels( final Class type ) + public Iterable<? extends EntityDescriptor> lookupEntityModels( final Class type ) { - List<ModelModule<EntityDescriptor>> result = allEntityModels.get( type ); - if( result == null ) - { - result = concat( - allEntities().filter( ref -> new ExactTypeMatching<>( type ).test( ref.model() ) ), - allEntities().filter( ref -> new AssignableFromTypeMatching<>( type ).test( ref.model() ) ) - ).distinct().collect( Collectors.toList() ); - allEntityModels.put( type, result ); - } - return result; + return allEntityModels.computeIfAbsent( type, key -> + concat( + allEntities().filter( ref -> new ExactTypeMatching<>( key ).test( ref ) ), + allEntities().filter( ref -> new AssignableFromTypeMatching<>( key ).test( ref ) ) + ).distinct().collect( Collectors.toList() ) + ); } - /** - * Lookup first ServiceReference matching the given Type. - * - * <p>Type lookup is done lazily and cached.</p> - * - * <p>See {@link #lookupServiceReferences(Type)}.</p> - * - * @param <T> Service Type - * @param serviceType Looked up Type - * - * @return First matching ServiceReference - */ @Override - public <T> ServiceReference<T> lookupServiceReference( Type serviceType ) + public ModelDescriptor lookupServiceModel( Type serviceType1 ) { - @SuppressWarnings( "unchecked" ) - ServiceReference<T> serviceReference = (ServiceReference<T>) serviceReferences.get( serviceType ); - if( serviceReference == null ) - { - // Lazily resolve ServiceReference - serviceReference = first( lookupServiceReferences( serviceType ) ); - if( serviceReference != null ) - { - serviceReferences.put( serviceType, serviceReference ); - } - } - - if( serviceReference == null ) - { - throw new NoSuchServiceException( RAW_CLASS.apply( serviceType ).getName(), moduleInstance.name() ); - } - return serviceReference; + return serviceModels.computeIfAbsent( serviceType1, key -> first( lookupServiceModels( key ) ) ); } - /** - * Lookup all ServiceReferences matching the given Type. - * - * <p>Returned Iterable contains, in order, ServiceReferences that: </p> - * - * <ul> - * <li>exactly match the given type, in Visibility then Assembly order ;</li> - * <li>match a type assignable to the given type, in Visibility then Assembly order.</li> - * </ul> - * - * <p>Multiple <b>exact</b> matches with the same Visibility are <b>allowed</b> to enable polymorphic lookup/injection.</p> - * <p>Multiple <b>assignable</b> matches with the same Visibility are <b>allowed</b> for the very same reason.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * @param <T> Service Type - * @param type Looked up Type - * - * @return All matching ServiceReferences - */ @Override - public <T> List<ServiceReference<T>> lookupServiceReferences( final Type type ) + public List<? extends ModelDescriptor> lookupServiceModels( Type type1 ) { - List<ServiceReference<?>> serviceRefs = servicesReferences.get( type ); - if( serviceRefs == null ) + return servicesReferences.computeIfAbsent( type1, type -> { - serviceRefs = concat( - allServices() - .filter( new ExactTypeMatching<>( type ) ), - allServices() - .filter( new AssignableFromTypeMatching<>( type ) - ) - ).distinct().collect( Collectors.toList() ); - servicesReferences.put( type, serviceRefs ); - } - List<ServiceReference<T>> result = new ArrayList<>(); - //noinspection unchecked - serviceRefs.forEach( ref -> result.add( (ServiceReference<T>) ref ) ); - return result; + List<ModelDescriptor> models = + allServices().filter( + new ExactTypeMatching<>( type ).or( new AssignableFromTypeMatching<>( type ) ) + ) + .distinct() + .collect( Collectors.toList() ); + + // TODO: Needed?? +// List<T> result = new ArrayList<>(); +// //noinspection unchecked +// serviceRefs.forEach( descriptor -> result.add( (T) descriptor ) ); + + return models; + } ); } @Override public Stream<Class<?>> allVisibleObjects() { - return allObjects().flatMap( model -> model.model().types() ); + return allObjects().flatMap( HasTypes::types ); } @Override - public Stream<ModelModule<ObjectDescriptor>> allObjects() + public Stream<? extends ObjectDescriptor> allObjects() { - return concat( moduleInstance.visibleObjects( module ), + return concat( moduleModel.objects(), concat( - moduleInstance.layerInstance().visibleObjects( layer ), concat( - moduleInstance.layerInstance().visibleObjects( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleObjects() - ) + moduleModel.layer().visibleObjects( layer ), + moduleModel.layer().visibleObjects( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleObjects( application ) ) ) ); } @Override - public Stream<ModelModule<TransientDescriptor>> allTransients() + public Stream<? extends TransientDescriptor> allTransients() { - return concat( moduleInstance.visibleTransients( module ), + return concat( moduleModel.transientComposites(), concat( - moduleInstance.layerInstance().visibleTransients( layer ), concat( - moduleInstance.layerInstance().visibleTransients( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleTransients() - ) + moduleModel.layer().visibleTransients( layer ), + moduleModel.layer().visibleTransients( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleTransients( application ) ) ) ); } @Override - public Stream<ModelModule<ValueDescriptor>> allValues() + public Stream<? extends ValueDescriptor> allValues() { - return concat( moduleInstance.visibleValues( module ), + + return concat( moduleModel.valueComposites(), concat( - moduleInstance.layerInstance().visibleValues( layer ), - concat( - moduleInstance.layerInstance().visibleValues( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleValues() - ) + concat( moduleModel.layer().visibleValues( layer ), + moduleModel.layer().visibleValues( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer1 -> layer1.visibleValues( application ) ) ) ); } @Override - public Stream<ModelModule<EntityDescriptor>> allEntities() + public Stream<? extends EntityDescriptor> allEntities() { - return concat( moduleInstance.visibleEntities( module ), + return concat( moduleModel.entityComposites(), concat( - moduleInstance.layerInstance().visibleEntities( layer ), concat( - moduleInstance.layerInstance().visibleEntities( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleEntities() - ) + moduleModel.layer().visibleEntities( layer ), + moduleModel.layer().visibleEntities( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleEntities( application ) ) ) ); } @Override - public Stream<ServiceReference<?>> allServices() + public Stream<? extends ModelDescriptor> allServices() { - return concat( moduleInstance.visibleServices( module ), - concat( - moduleInstance.layerInstance().visibleServices( layer ), - concat( - moduleInstance.layerInstance().visibleServices( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleServices() - ) - ) - ); + Stream<? extends ModelDescriptor> managedServices = + concat( moduleModel.serviceComposites(), + concat( + concat( + moduleModel.layer() + .visibleServices( layer ), + moduleModel.layer() + .visibleServices( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleServices( application ) ) + ) + ); + Stream<? extends ModelDescriptor> importedServices = + concat( moduleModel.serviceComposites(), + concat( + concat( + moduleModel.layer() + .visibleServices( layer ), + moduleModel.layer() + .visibleServices( application ) + ), + moduleModel.layer() + .usedLayers() + .layers() + .flatMap( layer -> layer.visibleServices( application ) ) + ) + ); + return concat( managedServices, importedServices ); } - private <T extends ModelDescriptor> ModelModule<T> ambiguityMatching( + private <T extends ModelDescriptor> T ambiguityMatching( Class type, - List<ModelModule<T>> modelModules, + List<T> modelModules, TypeMatching<T> matching ) { - List<ModelModule<T>> models = modelModules.stream() - .filter( ref -> matching.test( ref.model() ) ) + List<T> models = modelModules.stream() + .filter( matching ) .filter( new SameVisibility<>() ) .distinct() .collect( Collectors.toList() ); @@ -520,19 +479,19 @@ public class TypeLookupImpl * This Predicate will filter out all Models that doesn't have the same visisbility as the first one. */ private class SameVisibility<T extends ModelDescriptor> - implements Predicate<ModelModule<T>> + implements Predicate<T> { private Visibility current = null; @Override - public boolean test( ModelModule<T> model ) + public boolean test( T model ) { if( current == null ) { - current = model.model().visibility(); + current = model.visibility(); return true; } - return current == model.model().visibility(); + return current == model.visibility(); } } } http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java index ebf4b9c..7d1df94 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java @@ -17,50 +17,51 @@ package org.apache.zest.runtime.structure; import java.util.List; import java.util.stream.Stream; import org.apache.zest.api.common.Visibility; +import org.apache.zest.api.composite.ModelDescriptor; import org.apache.zest.api.composite.TransientDescriptor; import org.apache.zest.api.entity.EntityDescriptor; import org.apache.zest.api.object.ObjectDescriptor; import org.apache.zest.api.service.ServiceReference; +import org.apache.zest.api.structure.LayerDescriptor; import org.apache.zest.api.value.ValueDescriptor; -import org.apache.zest.spi.structure.ModelModule; /** * JAVADOC */ public final class UsedLayersInstance { - private final List<LayerInstance> usedLayerInstances; + private final List<LayerDescriptor> usedLayerInstances; - public UsedLayersInstance( List<LayerInstance> usedLayerInstances ) + public UsedLayersInstance( List<LayerDescriptor> usedLayerInstances ) { this.usedLayerInstances = usedLayerInstances; } - /* package */ Stream<ModelModule<ObjectDescriptor>> visibleObjects() + Stream<? extends ObjectDescriptor> visibleObjects() { return usedLayerInstances.stream() .flatMap( layerInstance -> layerInstance.visibleObjects( Visibility.application ) ); } - /* package */ Stream<ModelModule<TransientDescriptor>> visibleTransients() + Stream<? extends TransientDescriptor> visibleTransients() { return usedLayerInstances.stream() .flatMap( layerInstance -> layerInstance.visibleTransients( Visibility.application ) ); } - /* package */ Stream<ModelModule<EntityDescriptor>> visibleEntities() + Stream<? extends EntityDescriptor> visibleEntities() { return usedLayerInstances.stream() .flatMap( layerInstance -> layerInstance.visibleEntities( Visibility.application ) ); } - /* package */ Stream<ModelModule<ValueDescriptor>> visibleValues() + Stream<? extends ValueDescriptor> visibleValues() { return usedLayerInstances.stream() .flatMap( layerInstance -> layerInstance.visibleValues( Visibility.application ) ); } - /* package */ Stream<ServiceReference<?>> visibleServices() + Stream<? extends ModelDescriptor> visibleServices() { return usedLayerInstances.stream() .flatMap( layerInstance -> layerInstance.visibleServices( Visibility.application ) ); http://git-wip-us.apache.org/repos/asf/zest-java/blob/dedb068e/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java index 1f098a9..a00c53e 100644 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java +++ b/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java @@ -15,6 +15,8 @@ package org.apache.zest.runtime.structure; import java.util.List; +import java.util.stream.Stream; +import org.apache.zest.api.structure.LayerDescriptor; import org.apache.zest.api.structure.UsedLayersDescriptor; import org.apache.zest.functional.HierarchicalVisitor; import org.apache.zest.functional.VisitableHierarchy; @@ -33,9 +35,9 @@ public final class UsedLayersModel } @Override - public Iterable<LayerModel> layers() + public Stream<? extends LayerDescriptor> layers() { - return usedLayers; + return usedLayers.stream(); } @Override @@ -56,7 +58,7 @@ public final class UsedLayersModel return visitor.visitLeave( this ); } - public UsedLayersInstance newInstance( List<LayerInstance> usedLayerInstances ) + public UsedLayersInstance newInstance( List<LayerDescriptor> usedLayerInstances ) { return new UsedLayersInstance( usedLayerInstances ); }
