http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java deleted file mode 100644 index 0ebfbbb..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/TypeLookup.java +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 2008-2012, Rickard Ãberg. - * Copyright (c) 2008-2012, Niclas Hedhman. - * Copyright (c) 2012, Paul Merlin. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.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.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.zest.api.composite.AmbiguousTypeException; -import org.apache.zest.api.composite.ModelDescriptor; -import org.apache.zest.api.service.NoSuchServiceException; -import org.apache.zest.api.service.ServiceReference; -import org.apache.zest.functional.Function; -import org.apache.zest.functional.Specification; -import org.apache.zest.functional.Specifications; -import org.apache.zest.runtime.composite.TransientModel; -import org.apache.zest.runtime.entity.EntityModel; -import org.apache.zest.runtime.object.ObjectModel; -import org.apache.zest.runtime.value.ValueModel; -import org.apache.zest.spi.module.ModelModule; - -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.cast; -import static org.apache.zest.functional.Iterables.filter; -import static org.apache.zest.functional.Iterables.first; -import static org.apache.zest.functional.Iterables.flatten; -import static org.apache.zest.functional.Iterables.flattenIterables; -import static org.apache.zest.functional.Iterables.iterable; -import static org.apache.zest.functional.Iterables.toList; -import static org.apache.zest.functional.Iterables.unique; - -/** - * Central place for Composite Type lookups. - */ -public class TypeLookup -{ - - // Constructor parameters - private final ModuleInstance moduleInstance; - // Eager instance objects - private final Map<Class<?>, ModelModule<ObjectModel>> objectModels; - private final Map<Class<?>, ModelModule<TransientModel>> transientModels; - private final Map<Class<?>, ModelModule<ValueModel>> valueModels; - private final Map<Class<?>, Iterable<ModelModule<EntityModel>>> allEntityModels; - private final Map<Class<?>, ModelModule<EntityModel>> unambiguousEntityModels; - private final Map<Type, ServiceReference<?>> serviceReferences; - private final Map<Type, Iterable<ServiceReference<?>>> servicesReferences; - - /** - * Create a new TypeLookup bound to the given ModuleInstance. - * - * @param moduleInstance ModuleInstance bound to this TypeLookup - */ - /* package */ TypeLookup( ModuleInstance moduleInstance ) - { - // Constructor parameters - this.moduleInstance = moduleInstance; - - // Eager instance objects - objectModels = new ConcurrentHashMap<>(); - transientModels = new ConcurrentHashMap<>(); - valueModels = new ConcurrentHashMap<>(); - allEntityModels = new ConcurrentHashMap<>(); - unambiguousEntityModels = new ConcurrentHashMap<>(); - serviceReferences = new ConcurrentHashMap<>(); - servicesReferences = new ConcurrentHashMap<>(); - } - - /** - * Lookup first Object Model matching the given Type. - * - * <p>First, if Object Models exactly match the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Second, if Object Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * @param type Looked up Type - * - * @return First matching Object Model - */ - @SuppressWarnings( { "raw", "unchecked" } ) - /* package */ ModelModule<ObjectModel> lookupObjectModel( final Class type ) - { - ModelModule<ObjectModel> model = objectModels.get( type ); - - if( model == null ) - { - // Unambiguously and lazily resolve ObjectModel - Iterable<ModelModule<ObjectModel>> flatten = flatten( - ambiguousTypeCheck( type, - findModels( new ExactTypeLookupSpecification( type ), - moduleInstance.visibleObjects( module ), - moduleInstance.layerInstance().visibleObjects( layer ), - moduleInstance.layerInstance().visibleObjects( application ), - moduleInstance.layerInstance() - .usedLayersInstance() - .visibleObjects() ) ), - ambiguousTypeCheck( type, - findModels( new AssignableTypeLookupSpecification( type ), - moduleInstance.visibleObjects( module ), - moduleInstance.layerInstance().visibleObjects( layer ), - moduleInstance.layerInstance().visibleObjects( application ), - moduleInstance.layerInstance() - .usedLayersInstance() - .visibleObjects() ) ) ); - - model = first( flatten ); - - if( model != null ) - { - objectModels.put( type, model ); - } - } - - return model; - } - - /** - * Lookup first Transient Model matching the given Type. - * - * <p>First, if Transient Models exactly match the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Second, if Transient Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * @param type Looked up Type - * - * @return First matching Transient Model - */ - @SuppressWarnings( { "raw", "unchecked" } ) - /* package */ ModelModule<TransientModel> lookupTransientModel( final Class type ) - { - ModelModule<TransientModel> model = transientModels.get( type ); - - if( model == null ) - { - // Unambiguously and lazily resolve TransientModel - Iterable<ModelModule<TransientModel>> allModels = flatten( - ambiguousTypeCheck( type, - findModels( new ExactTypeLookupSpecification( type ), - moduleInstance.visibleTransients( module ), - moduleInstance.layerInstance().visibleTransients( layer ), - moduleInstance.layerInstance().visibleTransients( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleTransients() - ) - ), - - ambiguousTypeCheck( type, - findModels( new AssignableTypeLookupSpecification( type ), - moduleInstance.visibleTransients( module ), - moduleInstance.layerInstance().visibleTransients( layer ), - moduleInstance.layerInstance().visibleTransients( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleTransients() - ) - ) - ); - model = first( allModels ); - - if( model != null ) - { - transientModels.put( type, model ); - } - } - - return model; - } - - /** - * Lookup first Value Model matching the given Type. - * - * <p>First, if Value Models exactly match the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Second, if Value Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * @param type Looked up Type - * - * @return First matching Value Model - */ - @SuppressWarnings( { "raw", "unchecked" } ) - public ModelModule<ValueModel> lookupValueModel( final Class type ) - { - ModelModule<ValueModel> model = valueModels.get( type ); - - if( model == null ) - { - // Unambiguously and lazily resolve ValueModel - Iterable<ModelModule<ValueModel>> flatten = flatten( - ambiguousTypeCheck( type, - findModels( new ExactTypeLookupSpecification( type ), - moduleInstance.visibleValues( module ), - moduleInstance.layerInstance().visibleValues( layer ), - moduleInstance.layerInstance().visibleValues( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleValues() ) ), - ambiguousTypeCheck( type, - findModels( new AssignableTypeLookupSpecification( type ), - moduleInstance.visibleValues( module ), - moduleInstance.layerInstance().visibleValues( layer ), - moduleInstance.layerInstance().visibleValues( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleValues() - ) - ) - ); - - model = first( flatten ); - - if( model != null ) - { - valueModels.put( type, model ); - } - } - - return model; - } - - /** - * Lookup first Entity Model matching the given Type. - * - * <p>First, if Entity Models exactly match the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>exact</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Second, if Entity Models match a type assignable to the given type, the closest one (Visibility then Assembly order) is returned. - * Multiple <b>assignable</b> matches with the same Visibility are <b>forbidden</b> and result in an AmbiguousTypeException.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * <p><b>Should be used for creational use cases only.</b> For non-creational use cases see - * {@link #lookupEntityModels(java.lang.Class)}.</p> - * - * @param type Looked up Type - * - * @return First matching Entity Model - */ - @SuppressWarnings( { "raw", "unchecked" } ) - /* package */ ModelModule<EntityModel> lookupEntityModel( final Class type ) - { - ModelModule<EntityModel> model = unambiguousEntityModels.get( type ); - - if( model == null ) - { - // Unambiguously and lazily resolve EntityModels - Iterable<ModelModule<EntityModel>> allModels = flatten( - ambiguousTypeCheck( type, - findModels( new ExactTypeLookupSpecification( type ), - moduleInstance.visibleEntities( module ), - moduleInstance.layerInstance().visibleEntities( layer ), - moduleInstance.layerInstance().visibleEntities( application ), - moduleInstance.layerInstance() - .usedLayersInstance() - .visibleEntities() ) ), - ambiguousTypeCheck( type, - findModels( new AssignableTypeLookupSpecification( type ), - moduleInstance.visibleEntities( module ), - moduleInstance.layerInstance().visibleEntities( layer ), - moduleInstance.layerInstance().visibleEntities( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleEntities() - ) - ) - ); - - model = first( allModels ); - - if( model != null ) - { - unambiguousEntityModels.put( type, model ); - } - } - - return model; - } - - /** - * Lookup all Entity Models matching the given Type. - * - * <p>Returned Iterable contains, in order, Entity Models 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>forbidden</b> and result in an AmbiguousTypeException.</p> - * <p>Multiple <b>assignable</b> matches are <b>allowed</b> to enable polymorphic fetches and queries.</p> - * - * <p>Type lookup is done lazily and cached.</p> - * - * <p><b>Should be used for non-creational use cases only.</b> For creational use cases see - * {@link #lookupEntityModel(java.lang.Class)}.</p> - * - * @param type Looked up Type - * - * @return All matching Entity Models - */ - @SuppressWarnings( { "raw", "unchecked" } ) - /* package */ Iterable<ModelModule<EntityModel>> lookupEntityModels( final Class type ) - { - Iterable<ModelModule<EntityModel>> models = allEntityModels.get( type ); - if( models == null ) - { - // Ambiguously and lasily resolve EntityModels - Iterable<ModelModule<EntityModel>> matchingEntityModels = flatten( - ambiguousTypeCheck( type, - findModels( new ExactTypeLookupSpecification( type ), - moduleInstance.visibleEntities( module ), - moduleInstance.layerInstance().visibleEntities( layer ), - moduleInstance.layerInstance().visibleEntities( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleEntities() - ) - ), - findModels( new AssignableTypeLookupSpecification( type ), - moduleInstance.visibleEntities( module ), - moduleInstance.layerInstance().visibleEntities( layer ), - moduleInstance.layerInstance().visibleEntities( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleEntities() ) ); - - // Don't return the same EntityModel multiple times - matchingEntityModels = unique( matchingEntityModels ); - - models = toList( matchingEntityModels ); - allEntityModels.put( type, models ); - } - return models; - } - - /** - * Lookup first ServiceReference matching the given Type. - * - * <p>Type lookup is done lazily and cached.</p> - * - * <p>See {@link #lookupServiceReferences(java.lang.reflect.Type)}.</p> - * - * @param <T> Service Type - * @param serviceType Looked up Type - * - * @return First matching ServiceReference - */ - /* package */ - @SuppressWarnings( "unchecked" ) - <T> ServiceReference<T> lookupServiceReference( Type serviceType ) - { - ServiceReference<?> serviceReference = 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.map( serviceType ).getName(), moduleInstance.name() ); - } - - return (ServiceReference<T>) serviceReference; - } - - /** - * 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 serviceType Looked up Type - * - * @return All matching ServiceReferences - */ - @SuppressWarnings( "unchecked" ) - /* package */ <T> Iterable<ServiceReference<T>> lookupServiceReferences( final Type serviceType ) - { - Iterable<ServiceReference<?>> serviceRefs = servicesReferences.get( serviceType ); - if( serviceRefs == null ) - { - // Lazily resolve ServicesReferences - Iterable<ServiceReference<?>> matchingServices = flatten( - findServiceReferences( new ExactTypeLookupSpecification( serviceType ), - moduleInstance.visibleServices( module ), - moduleInstance.layerInstance().visibleServices( layer ), - moduleInstance.layerInstance().visibleServices( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleServices() ), - findServiceReferences( new AssignableTypeLookupSpecification( serviceType ), - moduleInstance.visibleServices( module ), - moduleInstance.layerInstance().visibleServices( layer ), - moduleInstance.layerInstance().visibleServices( application ), - moduleInstance.layerInstance().usedLayersInstance().visibleServices() ) ); - - // Don't return the same ServiceReference multiple times - matchingServices = unique( matchingServices ); - - serviceRefs = toList( matchingServices ); - servicesReferences.put( serviceType, serviceRefs ); - } - - return cast( serviceRefs ); - } - - @SuppressWarnings( { "raw", "unchecked" } ) - private static <T extends ModelDescriptor> Iterable<ModelModule<T>> findModels( Specification<Iterable<Class<?>>> specification, - Iterable<ModelModule<T>>... models - ) - { - Specification<ModelModule<T>> spec = Specifications.translate( new ModelModuleTypesFunction(), specification ); - Iterable<ModelModule<T>> flattened = flattenIterables( iterable( models ) ); - return filter( spec, flattened ); - } - - @SuppressWarnings( { "raw", "unchecked" } ) - private static Iterable<ServiceReference<?>> findServiceReferences( Specification<Iterable<Class<?>>> specification, - Iterable<ServiceReference<?>>... references - ) - { - Specification<ServiceReference<?>> spec = Specifications.translate( new ServiceReferenceTypesFunction(), specification ); - Iterable<ServiceReference<?>> flattened = flattenIterables( iterable( references ) ); - return filter( spec, flattened ); - } - - /** - * Check if the list of models contains several ones with the same visibility. If yes, then - * throw an AmbiguousTypeException - */ - @SuppressWarnings( "raw" ) - private static <T extends ModelDescriptor> Iterable<ModelModule<T>> ambiguousTypeCheck( final Class type, - final Iterable<ModelModule<T>> models - ) - { - return new Iterable<ModelModule<T>>() - { - - @Override - public Iterator<ModelModule<T>> iterator() - { - ModelModule<T> current = null; - List<ModelModule<T>> ambiguous = null; - List<ModelModule<T>> results = new ArrayList<>(); - for( ModelModule<T> model : models ) - { - if( current != null && !model.equals( current ) ) - { - if( model.model().visibility() == current.model().visibility() ) - { - if( ambiguous == null ) - { - ambiguous = new ArrayList<>(); - } - ambiguous.add( model ); - } - } - else - { - current = model; - } - results.add( model ); - } - if( ambiguous != null ) - { - // Check if we had any ambiguities - ambiguous.add( current ); - throw new AmbiguousTypeException( "More than one type matches " + type.getName() + ":" + ambiguous ); - } - // Ambiguity check done, and no ambiguities found. Return results - return results.iterator(); - } - }; - } - - private static class ModelModuleTypesFunction<T extends ModelDescriptor> - implements Function<ModelModule<T>, Iterable<Class<?>>> - { - - @Override - public Iterable<Class<?>> map( ModelModule<T> modelModule ) - { - return modelModule.model().types(); - } - } - - private static class ServiceReferenceTypesFunction - implements Function<ServiceReference<?>, Iterable<Class<?>>> - { - - @Override - public Iterable<Class<?>> map( ServiceReference<?> serviceReference ) - { - return serviceReference.types(); - } - } - - private static abstract class AbstractTypeLookupSpecification - implements Specification<Iterable<Class<?>>> - { - - protected final Type lookedUpType; - - private AbstractTypeLookupSpecification( Type lookedUpType ) - { - this.lookedUpType = lookedUpType; - } - - @Override - public final boolean satisfiedBy( Iterable<Class<?>> types ) - { - if( lookedUpType instanceof Class ) - { - // Straight class assignability check - return checkClassMatch( types, (Class) lookedUpType ); - } - else - { - if( lookedUpType instanceof ParameterizedType ) - { - // Foo<Bar> check - // First check Foo - ParameterizedType parameterizedType = (ParameterizedType) lookedUpType; - if( !checkClassMatch( types, (Class) parameterizedType.getRawType() ) ) - { - return false; - } - // Then check Bar - for( Type intf : interfacesOf( types ) ) - { - if( intf.equals( lookedUpType ) ) - { - // All parameters are the same - ok! - return true; - } - } - return false; - } - else if( lookedUpType instanceof WildcardType ) - { - return true; - } - return false; - } - } - - private boolean checkClassMatch( Iterable<Class<?>> candidates, Class<?> lookedUpType ) - { - for( Class<?> candidate : candidates ) - { - if( checkClassMatch( candidate, lookedUpType ) ) - { - return true; - } - } - return false; - } - - protected abstract boolean checkClassMatch( Class<?> candidate, Class<?> lookedUpType ); - } - - private static final class ExactTypeLookupSpecification - extends AbstractTypeLookupSpecification - { - - private ExactTypeLookupSpecification( Type lookedupType ) - { - super( lookedupType ); - } - - @Override - protected boolean checkClassMatch( Class<?> candidate, Class<?> lookedUpType ) - { - return candidate.equals( lookedUpType ); - } - } - - private static final class AssignableTypeLookupSpecification - extends AbstractTypeLookupSpecification - { - - private AssignableTypeLookupSpecification( Type lookedupType ) - { - super( lookedupType ); - } - - @Override - protected boolean checkClassMatch( Class<?> candidate, Class<?> lookedUpType ) - { - return !candidate.equals( lookedUpType ) && lookedUpType.isAssignableFrom( candidate ); - } - } -}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/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 deleted file mode 100644 index 12893cf..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersInstance.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.zest.runtime.structure; - -import java.util.List; -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.value.ValueDescriptor; -import org.apache.zest.functional.Function; -import org.apache.zest.spi.module.ModelModule; - -import static org.apache.zest.functional.Iterables.*; - -/** - * JAVADOC - */ -public final class UsedLayersInstance -{ - private final List<LayerInstance> usedLayerInstances; - - public UsedLayersInstance( List<LayerInstance> usedLayerInstances ) - { - this.usedLayerInstances = usedLayerInstances; - } - - /* package */ Iterable<ModelModule<ObjectDescriptor>> visibleObjects() - { - return flattenIterables( map( new Function<LayerInstance, Iterable<ModelModule<ObjectDescriptor>>>() - { - @Override - public Iterable<ModelModule<ObjectDescriptor>> map( LayerInstance layerInstance ) - { - return layerInstance.visibleObjects( Visibility.application ); - } - }, usedLayerInstances ) ); - } - - /* package */ Iterable<ModelModule<TransientDescriptor>> visibleTransients() - { - return flattenIterables( map( new Function<LayerInstance, Iterable<ModelModule<TransientDescriptor>>>() - { - @Override - public Iterable<ModelModule<TransientDescriptor>> map( LayerInstance layerInstance ) - { - return layerInstance.visibleTransients( Visibility.application ); - } - }, usedLayerInstances ) ); - } - - /* package */ Iterable<ModelModule<EntityDescriptor>> visibleEntities() - { - return flattenIterables( map( new Function<LayerInstance, Iterable<ModelModule<EntityDescriptor>>>() - { - @Override - public Iterable<ModelModule<EntityDescriptor>> map( LayerInstance layerInstance ) - { - return layerInstance.visibleEntities( Visibility.application ); - } - }, usedLayerInstances ) ); - } - - /* package */ Iterable<ModelModule<ValueDescriptor>> visibleValues() - { - return flattenIterables( map( new Function<LayerInstance, Iterable<ModelModule<ValueDescriptor>>>() - { - @Override - public Iterable<ModelModule<ValueDescriptor>> map( LayerInstance layerInstance ) - { - return layerInstance.visibleValues( Visibility.application ); - } - }, usedLayerInstances ) ); - } - - /* package */ Iterable<ServiceReference<?>> visibleServices() - { - return flattenIterables( map( new Function<LayerInstance, Iterable<ServiceReference<?>>>() - { - @Override - public Iterable<ServiceReference<?>> map( LayerInstance layerInstance ) - { - return layerInstance.visibleServices( Visibility.application ); - } - }, usedLayerInstances ) ); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/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 deleted file mode 100644 index 1f098a9..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/UsedLayersModel.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.zest.runtime.structure; - -import java.util.List; -import org.apache.zest.api.structure.UsedLayersDescriptor; -import org.apache.zest.functional.HierarchicalVisitor; -import org.apache.zest.functional.VisitableHierarchy; - -/** - * JAVADOC - */ -public final class UsedLayersModel - implements UsedLayersDescriptor, VisitableHierarchy<Object, Object> -{ - private final List<LayerModel> usedLayers; - - public UsedLayersModel( List<LayerModel> usedLayers ) - { - this.usedLayers = usedLayers; - } - - @Override - public Iterable<LayerModel> layers() - { - return usedLayers; - } - - @Override - public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor ) - throws ThrowableType - { - if( visitor.visitEnter( this ) ) - { - for( LayerModel usedLayer : usedLayers ) - { - if( !usedLayer.accept( visitor ) ) - { - break; - } - } - } - - return visitor.visitLeave( this ); - } - - public UsedLayersInstance newInstance( List<LayerInstance> usedLayerInstances ) - { - return new UsedLayersInstance( usedLayerInstances ); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/structure/VisibilitySpecification.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/structure/VisibilitySpecification.java b/core/runtime/src/main/java/org/apache/zest/runtime/structure/VisibilitySpecification.java deleted file mode 100644 index bb646eb..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/structure/VisibilitySpecification.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 org.apache.zest.api.common.Visibility; -import org.apache.zest.api.composite.ModelDescriptor; -import org.apache.zest.functional.Specification; - -/** - * TODO - */ -public class VisibilitySpecification - implements Specification<ModelDescriptor> -{ - public static final Specification<ModelDescriptor> MODULE = new VisibilitySpecification( Visibility.module ); - public static final Specification<ModelDescriptor> LAYER = new VisibilitySpecification( Visibility.layer ); - public static final Specification<ModelDescriptor> APPLICATION = new VisibilitySpecification( Visibility.application ); - - private final Visibility visibility; - - public VisibilitySpecification( Visibility visibility ) - { - this.visibility = visibility; - } - - @Override - public boolean satisfiedBy( ModelDescriptor item ) - { - return item.visibility().ordinal() >= visibility.ordinal(); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/types/ValueTypeFactory.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/types/ValueTypeFactory.java b/core/runtime/src/main/java/org/apache/zest/runtime/types/ValueTypeFactory.java deleted file mode 100644 index 2c7951c..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/types/ValueTypeFactory.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2009 Niclas Hedhman. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.zest.runtime.types; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import org.apache.zest.api.common.InvalidApplicationException; -import org.apache.zest.api.common.MetaInfo; -import org.apache.zest.api.common.Visibility; -import org.apache.zest.api.type.CollectionType; -import org.apache.zest.api.type.EnumType; -import org.apache.zest.api.type.MapType; -import org.apache.zest.api.type.Serialization; -import org.apache.zest.api.type.ValueCompositeType; -import org.apache.zest.api.type.ValueType; -import org.apache.zest.api.util.Classes; -import org.apache.zest.api.value.ValueComposite; -import org.apache.zest.functional.HierarchicalVisitorAdapter; -import org.apache.zest.functional.Iterables; -import org.apache.zest.functional.Specifications; -import org.apache.zest.runtime.association.AssociationsModel; -import org.apache.zest.runtime.association.ManyAssociationsModel; -import org.apache.zest.runtime.association.NamedAssociationsModel; -import org.apache.zest.runtime.composite.CompositeMethodsModel; -import org.apache.zest.runtime.composite.MixinsModel; -import org.apache.zest.runtime.property.PropertiesModel; -import org.apache.zest.runtime.structure.LayerModel; -import org.apache.zest.runtime.structure.ModuleModel; -import org.apache.zest.runtime.structure.UsedLayersModel; -import org.apache.zest.runtime.value.ValueModel; -import org.apache.zest.runtime.value.ValueStateModel; -import org.apache.zest.runtime.value.ValuesModel; - -public class ValueTypeFactory -{ - private static final ValueTypeFactory instance = new ValueTypeFactory(); - - public static ValueTypeFactory instance() - { - return instance; - } - - @SuppressWarnings( {"raw", "unchecked"} ) - public ValueType newValueType( Type type, - Class declaringClass, - Class compositeType, - LayerModel layer, - ModuleModel module, - Serialization.Variant variant - ) - { - ValueType valueType = null; - if( CollectionType.isCollection( type ) ) - { - if( type instanceof ParameterizedType ) - { - ParameterizedType pt = (ParameterizedType) type; - Type collectionType = pt.getActualTypeArguments()[ 0 ]; - if( collectionType instanceof TypeVariable ) - { - TypeVariable collectionTypeVariable = (TypeVariable) collectionType; - collectionType = Classes.resolveTypeVariable( collectionTypeVariable, declaringClass, compositeType ); - } - ValueType collectedType = newValueType( collectionType, declaringClass, compositeType, layer, module, variant ); - valueType = new CollectionType( Classes.RAW_CLASS.map( type ), collectedType ); - } - else - { - ValueType collectedType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); - valueType = new CollectionType( Classes.RAW_CLASS.map( type ), collectedType ); - } - } - else if( MapType.isMap( type ) ) - { - if( type instanceof ParameterizedType ) - { - ParameterizedType pt = (ParameterizedType) type; - Type keyType = pt.getActualTypeArguments()[ 0 ]; - if( keyType instanceof TypeVariable ) - { - TypeVariable keyTypeVariable = (TypeVariable) keyType; - keyType = Classes.resolveTypeVariable( keyTypeVariable, declaringClass, compositeType ); - } - ValueType keyedType = newValueType( keyType, declaringClass, compositeType, layer, module, variant ); - Type valType = pt.getActualTypeArguments()[ 1 ]; - if( valType instanceof TypeVariable ) - { - TypeVariable valueTypeVariable = (TypeVariable) valType; - valType = Classes.resolveTypeVariable( valueTypeVariable, declaringClass, compositeType ); - } - ValueType valuedType = newValueType( valType, declaringClass, compositeType, layer, module, variant ); - valueType = new MapType( Classes.RAW_CLASS.map( type ), keyedType, valuedType, variant ); - } - else - { - ValueType keyType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); - ValueType valuesType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); - valueType = new MapType( Classes.RAW_CLASS.map( type ), keyType, valuesType, variant ); - } - } - else if( ValueCompositeType.isValueComposite( type ) ) - { - // Find ValueModel in module/layer/used layers - ValueModel model = new ValueFinder( layer, module, Classes.RAW_CLASS.map( type ) ).getFoundModel(); - - if( model == null ) - { - if( type.equals( ValueComposite.class ) ) - { - // Create default model - MixinsModel mixinsModel = new MixinsModel(); - Iterable valueComposite = (Iterable) Iterables.iterable( ValueComposite.class ); - ValueStateModel valueStateModel = new ValueStateModel( new PropertiesModel(), - new AssociationsModel(), - new ManyAssociationsModel(), - new NamedAssociationsModel() ); - model = new ValueModel( valueComposite, Visibility.application, new MetaInfo(), - mixinsModel, valueStateModel, new CompositeMethodsModel( mixinsModel ) ); - } - else - { - throw new InvalidApplicationException( "[" + module.name() + "] Could not find ValueComposite of type " + type ); - } - } - - return model.valueType(); - } - else if( EnumType.isEnum( type ) ) - { - valueType = new EnumType( Classes.RAW_CLASS.map( type ) ); - } - else - { - valueType = new ValueType( Classes.RAW_CLASS.map( type ) ); - } - - return valueType; - } - - @SuppressWarnings( "raw" ) - private static class ValueFinder - extends HierarchicalVisitorAdapter<Object, Object, RuntimeException> - { - private Class type; - private ValueModel foundModel; - private Visibility visibility; - - private ValueFinder( LayerModel layer, ModuleModel module, Class type ) - { - this.type = type; - - visibility = Visibility.module; - module.accept( this ); - - if( foundModel == null ) - { - visibility = Visibility.layer; - layer.accept( this ); - - if( foundModel == null ) - { - visibility = Visibility.application; - layer.usedLayers().accept( this ); - } - } - } - - public ValueModel getFoundModel() - { - return foundModel; - } - - @Override - public boolean visitEnter( Object visited ) - throws RuntimeException - { - if( visited instanceof ValuesModel ) - { - return true; - } - else if( visited instanceof ModuleModel ) - { - return true; - } - else if (visited instanceof LayerModel ) - { - return true; - } - else if (visited instanceof UsedLayersModel ) - { - return true; - } - else if( visited instanceof ValueModel ) - { - ValueModel valueModel = (ValueModel) visited; - boolean typeEquality = Specifications.in( valueModel.types() ).satisfiedBy( type ); - if( typeEquality && valueModel.visibility().ordinal() >= visibility.ordinal() ) - { - foundModel = valueModel; - } - } - - return false; - } - - @Override - public boolean visitLeave( Object visited ) - throws RuntimeException - { - return foundModel == null; - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderEntityState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderEntityState.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderEntityState.java deleted file mode 100644 index a390874..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderEntityState.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2009-2011, Rickard Ãberg. All Rights Reserved. - * Copyright (c) 2009-2013, Niclas Hedhman. All Rights Reserved. - * Copyright (c) 2014, Paul Merlin. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.zest.runtime.unitofwork; - -import java.util.HashMap; -import java.util.Map; -import org.apache.zest.api.common.QualifiedName; -import org.apache.zest.api.entity.EntityDescriptor; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.util.Classes; -import org.apache.zest.spi.entity.EntityState; -import org.apache.zest.spi.entity.EntityStatus; -import org.apache.zest.spi.entity.ManyAssociationState; -import org.apache.zest.spi.entity.NamedAssociationState; - -/** - * Implementation of EntityState for use through EntityBuilder. - */ -public final class BuilderEntityState - implements EntityState -{ - private final EntityDescriptor entityType; - private final EntityReference reference; - private final Map<QualifiedName, Object> properties = new HashMap<>(); - private final Map<QualifiedName, EntityReference> associations = new HashMap<>(); - private final Map<QualifiedName, ManyAssociationState> manyAssociations = new HashMap<>(); - private final Map<QualifiedName, NamedAssociationState> namedAssociations = new HashMap<>(); - - public BuilderEntityState( EntityDescriptor type, EntityReference reference ) - { - this.entityType = type; - this.reference = reference; - } - - @Override - public EntityReference identity() - { - return reference; - } - - @Override - public String version() - { - return ""; - } - - @Override - public long lastModified() - { - return 0; - } - - @Override - public void remove() - { - } - - @Override - public EntityStatus status() - { - return EntityStatus.NEW; - } - - @Override - public boolean isAssignableTo( Class<?> type ) - { - return Classes.exactTypeSpecification( type ).satisfiedBy( entityType ); - } - - @Override - public EntityDescriptor entityDescriptor() - { - return entityType; - } - - @Override - public Object propertyValueOf( QualifiedName stateName ) - { - return properties.get( stateName ); - } - - @Override - public EntityReference associationValueOf( QualifiedName stateName ) - { - return associations.get( stateName ); - } - - @Override - public void setPropertyValue( QualifiedName stateName, Object newValue ) - { - properties.put( stateName, newValue ); - } - - @Override - public void setAssociationValue( QualifiedName stateName, EntityReference newEntity ) - { - associations.put( stateName, newEntity ); - } - - @Override - public ManyAssociationState manyAssociationValueOf( QualifiedName stateName ) - { - ManyAssociationState state = manyAssociations.get( stateName ); - if( state == null ) - { - state = new BuilderManyAssociationState(); - manyAssociations.put( stateName, state ); - } - return state; - } - - @Override - public NamedAssociationState namedAssociationValueOf( QualifiedName stateName ) - { - NamedAssociationState state = namedAssociations.get( stateName ); - if( state == null ) - { - state = new BuilderNamedAssociationState(); - namedAssociations.put( stateName, state ); - } - return state; - } - - public void copyTo( EntityState newEntityState ) - { - for( Map.Entry<QualifiedName, Object> fromPropertyEntry : properties.entrySet() ) - { - newEntityState.setPropertyValue( fromPropertyEntry.getKey(), fromPropertyEntry.getValue() ); - } - for( Map.Entry<QualifiedName, EntityReference> fromAssociationEntry : associations.entrySet() ) - { - newEntityState.setAssociationValue( fromAssociationEntry.getKey(), fromAssociationEntry.getValue() ); - } - for( Map.Entry<QualifiedName, ManyAssociationState> fromManyAssociationEntry : manyAssociations.entrySet() ) - { - QualifiedName qName = fromManyAssociationEntry.getKey(); - ManyAssociationState fromManyAssoc = fromManyAssociationEntry.getValue(); - ManyAssociationState toManyAssoc = newEntityState.manyAssociationValueOf( qName ); - for( EntityReference entityReference : fromManyAssoc ) - { - toManyAssoc.add( 0, entityReference ); - } - } - for( Map.Entry<QualifiedName, NamedAssociationState> fromNamedAssociationEntry : namedAssociations.entrySet() ) - { - QualifiedName qName = fromNamedAssociationEntry.getKey(); - NamedAssociationState fromNamedAssoc = fromNamedAssociationEntry.getValue(); - NamedAssociationState toNamedAssoc = newEntityState.namedAssociationValueOf( qName ); - for( String name : fromNamedAssoc ) - { - toNamedAssoc.put( name, fromNamedAssoc.get( name ) ); - } - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderManyAssociationState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderManyAssociationState.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderManyAssociationState.java deleted file mode 100644 index d549c2a..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderManyAssociationState.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.zest.runtime.unitofwork; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.spi.entity.ManyAssociationState; - -/** - * Default implementation of ManyAssociationState that also - * keeps a list of changes that can be extracted at any time. - */ -public final class BuilderManyAssociationState - implements ManyAssociationState -{ - private List<EntityReference> references; - - public BuilderManyAssociationState() - { - references = new ArrayList<EntityReference>(); - } - - @Override - public int count() - { - return references.size(); - } - - @Override - public boolean contains( EntityReference entityReference ) - { - return references.contains( entityReference ); - } - - @Override - public boolean add( int i, EntityReference entityReference ) - { - if( references.contains( entityReference ) ) - { - return false; - } - - references.add( i, entityReference ); - return true; - } - - @Override - public boolean remove( EntityReference entityReference ) - { - return references.remove( entityReference ); - } - - @Override - public EntityReference get( int i ) - { - return references.get( i ); - } - - @Override - public Iterator<EntityReference> iterator() - { - return references.iterator(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java deleted file mode 100644 index 8ec7a4b..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/BuilderNamedAssociationState.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2011-2013, Niclas Hedhman. All Rights Reserved. - * Copyright (c) 2014, Paul Merlin. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.zest.runtime.unitofwork; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.spi.entity.NamedAssociationState; - -/** - * Default implementation of NamedAssociationState that also - * keeps a list of changes that can be extracted at any time. - */ -public final class BuilderNamedAssociationState - implements NamedAssociationState -{ - private final Map<String, EntityReference> references; - - public BuilderNamedAssociationState() - { - references = new HashMap<>(); - } - - @Override - public int count() - { - return references.size(); - } - - @Override - public boolean containsName( String name ) - { - return references.containsKey( name ); - } - - @Override - public boolean put( String name, EntityReference entityReference ) - { - return references.put( name, entityReference ) != null; - } - - @Override - public boolean remove( String name ) - { - return references.remove( name ) != null; - } - - @Override - public EntityReference get( String name ) - { - return references.get( name ); - } - - @Override - public String nameOf( EntityReference entityReference ) - { - for( Map.Entry<String, EntityReference> entry : references.entrySet() ) - { - if( entry.getValue().equals( entityReference ) ) - { - return entry.getKey(); - } - } - return null; - } - - @Override - public Iterator<String> iterator() - { - return references.keySet().iterator(); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java deleted file mode 100644 index 014c28c..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityBuilderInstance.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2007-2009, Rickard Ãberg. All Rights Reserved. - * Copyright (c) 2008, Alin Dreghiciu. All Rights Reserved. - * Copyright (c) 2008, Edward Yakop. All Rights Reserved. - * Copyright (c) 2014-2015, Paul Merlin. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.zest.runtime.unitofwork; - -import org.apache.zest.api.common.QualifiedName; -import org.apache.zest.api.entity.EntityBuilder; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.entity.Identity; -import org.apache.zest.api.entity.LifecycleException; -import org.apache.zest.runtime.composite.FunctionStateResolver; -import org.apache.zest.runtime.entity.EntityInstance; -import org.apache.zest.runtime.entity.EntityModel; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.runtime.structure.ModuleUnitOfWork; -import org.apache.zest.spi.entity.EntityState; -import org.apache.zest.spi.entitystore.EntityStoreUnitOfWork; - -/** - * Implementation of EntityBuilder. Maintains an instance of the entity which - * will not have its state validated until it is created by calling newInstance(). - */ -public final class EntityBuilderInstance<T> - implements EntityBuilder<T> -{ - private static final QualifiedName IDENTITY_STATE_NAME; - - private final ModelModule<EntityModel> model; - private final ModuleUnitOfWork uow; - private final EntityStoreUnitOfWork store; - private String identity; - - private final BuilderEntityState entityState; - private final EntityInstance prototypeInstance; - - static - { - try - { - IDENTITY_STATE_NAME = QualifiedName.fromAccessor( Identity.class.getMethod( "identity" ) ); - } - catch( NoSuchMethodException e ) - { - throw new InternalError( "Zest Core Runtime codebase is corrupted. Contact Zest team: EntityBuilderInstance" ); - } - } - - public EntityBuilderInstance( - ModelModule<EntityModel> model, - ModuleUnitOfWork uow, - EntityStoreUnitOfWork store, - String identity - ) - { - this( model, uow, store, identity, null ); - } - - public EntityBuilderInstance( - ModelModule<EntityModel> model, - ModuleUnitOfWork uow, - EntityStoreUnitOfWork store, - String identity, - FunctionStateResolver stateResolver - ) - { - this.model = model; - this.uow = uow; - this.store = store; - this.identity = identity; - EntityReference reference = new EntityReference( identity ); - entityState = new BuilderEntityState( model.model(), reference ); - model.model().initState( model.module(), entityState ); - if( stateResolver != null ) - { - stateResolver.populateState( model.model(), entityState ); - } - entityState.setPropertyValue( IDENTITY_STATE_NAME, identity ); - prototypeInstance = model.model().newInstance( uow, model.module(), entityState ); - } - - @SuppressWarnings( "unchecked" ) - @Override - public T instance() - { - checkValid(); - return prototypeInstance.<T>proxy(); - } - - @Override - public <K> K instanceFor( Class<K> mixinType ) - { - checkValid(); - return prototypeInstance.newProxy( mixinType ); - } - - @Override - @SuppressWarnings( "unchecked" ) - public T newInstance() - throws LifecycleException - { - checkValid(); - - String identity; - - // Figure out whether to use given or generated identity - identity = (String) entityState.propertyValueOf( IDENTITY_STATE_NAME ); - EntityState newEntityState = model.model().newEntityState( store, uow.module(), - EntityReference.parseEntityReference( identity ) ); - - prototypeInstance.invokeCreate(); - - // Check constraints - prototypeInstance.checkConstraints(); - - entityState.copyTo( newEntityState ); - - EntityInstance instance = model.model().newInstance( uow, model.module(), newEntityState ); - - Object proxy = instance.proxy(); - - // Add entity in UOW - uow.addEntity( instance ); - - // Invalidate builder - this.identity = null; - - return (T) proxy; - } - - private void checkValid() - throws IllegalStateException - { - if( identity == null ) - { - throw new IllegalStateException( "EntityBuilder is not valid after call to newInstance()" ); - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityStateStore.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityStateStore.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityStateStore.java deleted file mode 100644 index 6afe68e..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/EntityStateStore.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.zest.runtime.unitofwork; - -import org.apache.zest.api.association.AssociationStateHolder; -import org.apache.zest.spi.entity.EntityState; - -/** - * JAVADOC - */ -final class EntityStateStore -{ - AssociationStateHolder stateHolder; - EntityState state; - - @Override - public String toString() - { - return state.identity().toString(); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/UnitOfWorkInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/UnitOfWorkInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/UnitOfWorkInstance.java deleted file mode 100644 index 2136528..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/unitofwork/UnitOfWorkInstance.java +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright (c) 2007-2013, Niclas Hedhman. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - * implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.zest.runtime.unitofwork; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Stack; -import java.util.concurrent.TimeUnit; -import org.apache.zest.api.common.MetaInfo; -import org.apache.zest.api.entity.EntityComposite; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.metrics.MetricsCounter; -import org.apache.zest.api.metrics.MetricsCounterFactory; -import org.apache.zest.api.metrics.MetricsProvider; -import org.apache.zest.api.metrics.MetricsTimer; -import org.apache.zest.api.metrics.MetricsTimerFactory; -import org.apache.zest.api.unitofwork.ConcurrentEntityModificationException; -import org.apache.zest.api.unitofwork.EntityTypeNotFoundException; -import org.apache.zest.api.unitofwork.NoSuchEntityException; -import org.apache.zest.api.unitofwork.UnitOfWorkCallback; -import org.apache.zest.api.unitofwork.UnitOfWorkCompletionException; -import org.apache.zest.api.unitofwork.UnitOfWorkException; -import org.apache.zest.api.unitofwork.UnitOfWorkOptions; -import org.apache.zest.api.usecase.Usecase; -import org.apache.zest.runtime.entity.EntityInstance; -import org.apache.zest.runtime.entity.EntityModel; -import org.apache.zest.runtime.structure.ModuleUnitOfWork; -import org.apache.zest.spi.entity.EntityState; -import org.apache.zest.spi.entity.EntityStatus; -import org.apache.zest.spi.entitystore.ConcurrentEntityStateModificationException; -import org.apache.zest.spi.entitystore.EntityNotFoundException; -import org.apache.zest.spi.entitystore.EntityStore; -import org.apache.zest.spi.entitystore.EntityStoreUnitOfWork; -import org.apache.zest.spi.entitystore.StateCommitter; -import org.apache.zest.spi.metrics.DefaultMetric; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.spi.module.ModuleSpi; - -import static org.apache.zest.api.unitofwork.UnitOfWorkCallback.UnitOfWorkStatus.COMPLETED; -import static org.apache.zest.api.unitofwork.UnitOfWorkCallback.UnitOfWorkStatus.DISCARDED; -import static org.apache.zest.functional.Iterables.map; - -public final class UnitOfWorkInstance -{ - private static final ThreadLocal<Stack<UnitOfWorkInstance>> current = new ThreadLocal<Stack<UnitOfWorkInstance>>() - { - @Override - protected Stack<UnitOfWorkInstance> initialValue() - { - return new Stack<>(); - } - }; - private MetricsTimer.Context metricsTimer; - - public static Stack<UnitOfWorkInstance> getCurrent() - { - return current.get(); - } - - private long currentTime; - private MetricsProvider metrics; - final HashMap<EntityReference, EntityInstance> instanceCache; - final HashMap<EntityStore, EntityStoreUnitOfWork> storeUnitOfWork; - - private boolean open; - - private boolean paused; - - /** - * Lazy query builder factory. - */ - private Usecase usecase; - - private MetaInfo metaInfo; - - private List<UnitOfWorkCallback> callbacks; - - public UnitOfWorkInstance( Usecase usecase, long currentTime, MetricsProvider metrics ) - { - this.currentTime = currentTime; - this.open = true; - instanceCache = new HashMap<>(); - storeUnitOfWork = new HashMap<>(); - getCurrent().push( this ); - paused = false; - this.usecase = usecase; - startCapture( metrics ); - } - - public long currentTime() - { - return currentTime; - } - - public EntityStoreUnitOfWork getEntityStoreUnitOfWork( EntityStore store, ModuleSpi module ) - { - EntityStoreUnitOfWork uow = storeUnitOfWork.get( store ); - if( uow == null ) - { - uow = store.newUnitOfWork( usecase, module, currentTime ); - storeUnitOfWork.put( store, uow ); - } - return uow; - } - - public <T> T get( EntityReference identity, - ModuleUnitOfWork uow, - Iterable<ModelModule<EntityModel>> potentialModels, - Class<T> mixinType - ) - throws EntityTypeNotFoundException, NoSuchEntityException - { - checkOpen(); - - EntityInstance entityInstance = instanceCache.get( identity ); - if( entityInstance == null ) - { // Not yet in cache - - // Check if this is a root UoW, or if no parent UoW knows about this entity - EntityState entityState = null; - EntityModel model = null; - ModuleSpi module = null; - // Figure out what EntityStore to use - for( ModelModule<EntityModel> potentialModel : potentialModels ) - { - EntityStore store = potentialModel.module().entityStore(); - EntityStoreUnitOfWork storeUow = getEntityStoreUnitOfWork( store, potentialModel.module() ); - try - { - entityState = storeUow.entityStateOf( potentialModel.module(), identity ); - } - catch( EntityNotFoundException e ) - { - continue; - } - - // Get the selected model - model = (EntityModel) entityState.entityDescriptor(); - module = potentialModel.module(); - } - - // Check if model was found - if( model == null ) - { - // Check if state was found - if( entityState == null ) - { - throw new NoSuchEntityException( identity, mixinType, usecase ); - } - else - { - throw new EntityTypeNotFoundException( mixinType.getName(), - module.name(), - map( ModelModule.toStringFunction, - module.findVisibleEntityTypes() - ) ); - } - } - - // Create instance - entityInstance = new EntityInstance( uow, module, model, entityState ); - - instanceCache.put( identity, entityInstance ); - } - else - { - // Check if it has been removed - if( entityInstance.status() == EntityStatus.REMOVED ) - { - throw new NoSuchEntityException( identity, mixinType, usecase ); - } - } - - return entityInstance.proxy(); - } - - public Usecase usecase() - { - return usecase; - } - - public MetaInfo metaInfo() - { - if( metaInfo == null ) - { - metaInfo = new MetaInfo(); - } - - return metaInfo; - } - - public void pause() - { - if( !paused ) - { - paused = true; - getCurrent().pop(); - - UnitOfWorkOptions unitOfWorkOptions = metaInfo().get( UnitOfWorkOptions.class ); - if( unitOfWorkOptions == null ) - { - unitOfWorkOptions = usecase().metaInfo( UnitOfWorkOptions.class ); - } - - if( unitOfWorkOptions != null ) - { - if( unitOfWorkOptions.isPruneOnPause() ) - { - List<EntityReference> prunedInstances = null; - for( EntityInstance entityInstance : instanceCache.values() ) - { - if( entityInstance.status() == EntityStatus.LOADED ) - { - if( prunedInstances == null ) - { - prunedInstances = new ArrayList<>(); - } - prunedInstances.add( entityInstance.identity() ); - } - } - if( prunedInstances != null ) - { - for( EntityReference prunedInstance : prunedInstances ) - { - instanceCache.remove( prunedInstance ); - } - } - } - } - } - else - { - throw new UnitOfWorkException( "Unit of work is not active" ); - } - } - - public void resume() - { - if( paused ) - { - paused = false; - getCurrent().push( this ); - } - else - { - throw new UnitOfWorkException( "Unit of work has not been paused" ); - } - } - - public void complete() - throws UnitOfWorkCompletionException - { - checkOpen(); - - // Copy list so that it cannot be modified during completion - List<UnitOfWorkCallback> currentCallbacks = callbacks == null ? null : new ArrayList<>( callbacks ); - - // Commit state to EntityStores - List<StateCommitter> committers = applyChanges(); - - // Check callbacks - notifyBeforeCompletion( currentCallbacks ); - - // Commit all changes - for( StateCommitter committer : committers ) - { - committer.commit(); - } - - close(); - - // Call callbacks - notifyAfterCompletion( currentCallbacks, COMPLETED ); - - callbacks = currentCallbacks; - } - - public void discard() - { - if( !isOpen() ) - { - return; - } - close(); - - // Copy list so that it cannot be modified during completion - List<UnitOfWorkCallback> currentCallbacks = callbacks == null ? null : new ArrayList<>( callbacks ); - - // Call callbacks - notifyAfterCompletion( currentCallbacks, DISCARDED ); - - for( EntityStoreUnitOfWork entityStoreUnitOfWork : storeUnitOfWork.values() ) - { - entityStoreUnitOfWork.discard(); - } - - callbacks = currentCallbacks; - } - - private void close() - { - checkOpen(); - - if( !isPaused() ) - { - getCurrent().pop(); - } - endCapture(); - open = false; - } - - public boolean isOpen() - { - return open; - } - - public void addUnitOfWorkCallback( UnitOfWorkCallback callback ) - { - if( callbacks == null ) - { - callbacks = new ArrayList<>(); - } - - callbacks.add( callback ); - } - - public void removeUnitOfWorkCallback( UnitOfWorkCallback callback ) - { - if( callbacks != null ) - { - callbacks.remove( callback ); - } - } - - public void addEntity( EntityInstance instance ) - { - instanceCache.put( instance.identity(), instance ); - } - - private List<StateCommitter> applyChanges() - throws UnitOfWorkCompletionException - { - List<StateCommitter> committers = new ArrayList<>(); - for( EntityStoreUnitOfWork entityStoreUnitOfWork : storeUnitOfWork.values() ) - { - try - { - StateCommitter committer = entityStoreUnitOfWork.applyChanges(); - committers.add( committer ); - } - catch( Exception e ) - { - // Cancel all previously prepared stores - for( StateCommitter committer : committers ) - { - committer.cancel(); - } - - if( e instanceof ConcurrentEntityStateModificationException ) - { - // If we cancelled due to concurrent modification, then create the proper exception for it! - ConcurrentEntityStateModificationException mee = (ConcurrentEntityStateModificationException) e; - Collection<EntityReference> modifiedEntityIdentities = mee.modifiedEntities(); - Collection<EntityComposite> modifiedEntities = new ArrayList<>(); - for( EntityReference modifiedEntityIdentity : modifiedEntityIdentities ) - { - Collection<EntityInstance> instances = instanceCache.values(); - for( EntityInstance instance : instances ) - { - if( instance.identity().equals( modifiedEntityIdentity ) ) - { - modifiedEntities.add( instance.<EntityComposite>proxy() ); - } - } - } - throw new ConcurrentEntityModificationException( modifiedEntities ); - } - else - { - throw new UnitOfWorkCompletionException( e ); - } - } - } - return committers; - } - - private void notifyBeforeCompletion( List<UnitOfWorkCallback> callbacks ) - throws UnitOfWorkCompletionException - { - // Notify explicitly registered callbacks - if( callbacks != null ) - { - for( UnitOfWorkCallback callback : callbacks ) - { - callback.beforeCompletion(); - } - } - - // Notify entities - try - { - for( EntityInstance instance : instanceCache.values() ) - { - boolean isCallback = instance.proxy() instanceof UnitOfWorkCallback; - boolean isNotRemoved = !instance.status().equals( EntityStatus.REMOVED ); - if( isCallback && isNotRemoved ) - { - UnitOfWorkCallback callback = UnitOfWorkCallback.class.cast( instance.proxy() ); - callback.beforeCompletion(); - } - } - } - catch( UnitOfWorkCompletionException e ) - { - throw e; - } - catch( Exception e ) - { - throw new UnitOfWorkCompletionException( e ); - } - } - - private void notifyAfterCompletion( List<UnitOfWorkCallback> callbacks, - final UnitOfWorkCallback.UnitOfWorkStatus status - ) - { - if( callbacks != null ) - { - for( UnitOfWorkCallback callback : callbacks ) - { - try - { - callback.afterCompletion( status ); - } - catch( Exception e ) - { - // Ignore - } - } - } - - // Notify entities - try - { - for( EntityInstance instance : instanceCache.values() ) - { - boolean isCallback = instance.proxy() instanceof UnitOfWorkCallback; - boolean isNotRemoved = !instance.status().equals( EntityStatus.REMOVED ); - if( isCallback && isNotRemoved ) - { - UnitOfWorkCallback callback = UnitOfWorkCallback.class.cast( instance.proxy() ); - callback.afterCompletion( status ); - } - } - } - catch( Exception e ) - { - // Ignore - } - } - - public void checkOpen() - { - if( !isOpen() ) - { - throw new UnitOfWorkException( "Unit of work has been closed" ); - } - } - - public boolean isPaused() - { - return paused; - } - - @Override - public String toString() - { - return "UnitOfWork " + hashCode() + "(" + usecase + "): entities:" + instanceCache.size(); - } - - public void remove( EntityReference entityReference ) - { - instanceCache.remove( entityReference ); - } - - private void incrementCount() - { - MetricsCounter counter = getCounter(); - counter.increment(); - } - - private void decrementCount() - { - MetricsCounter counter = getCounter(); - counter.decrement(); - } - - private MetricsCounter getCounter() - { - if( metrics != null ) - { - MetricsCounterFactory metricsFactory = metrics.createFactory( MetricsCounterFactory.class ); - return metricsFactory.createCounter( getClass(), "UnitOfWork Counter" ); - } - return new DefaultMetric(); - } - - private void endCapture() - { - decrementCount(); - metricsTimer.stop(); - } - - private void startCapture( MetricsProvider metrics ) - { - this.metrics = metrics; - incrementCount(); - startTimer( metrics ); - } - - private void startTimer( MetricsProvider metrics ) - { - MetricsTimerFactory metricsFactory = metrics.createFactory( MetricsTimerFactory.class ); - String name = "UnitOfWork Timer"; - MetricsTimer timer = metricsFactory.createTimer( getClass(), name, TimeUnit.MILLISECONDS, TimeUnit.SECONDS ); - metricsTimer = timer.start(); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ManyAssociationValueState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ManyAssociationValueState.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ManyAssociationValueState.java deleted file mode 100644 index 6056d9b..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ManyAssociationValueState.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.value; - -import java.util.Iterator; -import java.util.List; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.spi.entity.ManyAssociationState; - -/** - * ManyAssociationState implementation for Value composites. - */ -public class ManyAssociationValueState - implements ManyAssociationState -{ - private List<EntityReference> references; - - public ManyAssociationValueState( List<EntityReference> references ) - { - this.references = references; - } - - @Override - public int count() - { - return references.size(); - } - - @Override - public boolean contains( EntityReference entityReference ) - { - return references.contains( entityReference ); - } - - @Override - public boolean add( int i, EntityReference entityReference ) - { - if( references.contains( entityReference ) ) - { - return false; - } - - references.add( i, entityReference ); - return true; - } - - @Override - public boolean remove( EntityReference entity ) - { - boolean removed = references.remove( entity ); - return removed; - } - - @Override - public EntityReference get( int i ) - { - return references.get( i ); - } - - @Override - public Iterator<EntityReference> iterator() - { - final Iterator<EntityReference> iter = references.iterator(); - - return new Iterator<EntityReference>() - { - EntityReference current; - - @Override - public boolean hasNext() - { - return iter.hasNext(); - } - - @Override - public EntityReference next() - { - current = iter.next(); - return current; - } - - @Override - public void remove() - { - iter.remove(); - } - }; - } -}
