http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/NamedAssociationValueState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/NamedAssociationValueState.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/NamedAssociationValueState.java deleted file mode 100644 index b252d33..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/NamedAssociationValueState.java +++ /dev/null @@ -1,84 +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.value; - -import java.util.Iterator; -import java.util.Map; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.spi.entity.NamedAssociationState; - -public class NamedAssociationValueState - implements NamedAssociationState -{ - private final Map<String, EntityReference> references; - - public NamedAssociationValueState( Map<String, EntityReference> references ) - { - this.references = references; - } - - @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/value/ReferenceProperty.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ReferenceProperty.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ReferenceProperty.java deleted file mode 100644 index 1bda2e9..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ReferenceProperty.java +++ /dev/null @@ -1,53 +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 org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.property.Property; - -/** - * The reference for an Association - */ -public class ReferenceProperty - implements Property<EntityReference> -{ - EntityReference reference; - - public ReferenceProperty() - { - } - - public ReferenceProperty( EntityReference reference ) - { - this.reference = reference; - } - - @Override - public EntityReference get() - { - return reference; - } - - @Override - public void set( EntityReference newValue ) - throws IllegalArgumentException, IllegalStateException - { - reference = newValue; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderInstance.java deleted file mode 100644 index ceeeb10..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderInstance.java +++ /dev/null @@ -1,79 +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.value; - -import org.apache.zest.api.association.AssociationStateHolder; -import org.apache.zest.api.common.ConstructionException; -import org.apache.zest.api.composite.Composite; -import org.apache.zest.api.value.NoSuchValueException; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.runtime.composite.StateResolver; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.runtime.structure.ModuleInstance; - -import static org.apache.zest.functional.Iterables.first; - -/** - * Implementation of ValueBuilder - */ -public final class ValueBuilderInstance<T> - implements ValueBuilder<T> -{ - - private final ModuleInstance currentModule; - private final ValueInstance prototypeInstance; - - public ValueBuilderInstance( ModelModule<ValueModel> compositeModelModule, ModuleInstance currentModule, StateResolver stateResolver ) - { - ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, stateResolver ); - prototypeInstance = compositeModelModule.model().newValueInstance( compositeModelModule.module(), state ); - prototypeInstance.prepareToBuild(); - this.currentModule = currentModule; - } - - @Override - public T prototype() - { - return prototypeInstance.<T>proxy(); - } - - @Override - public AssociationStateHolder state() - { - return prototypeInstance.state(); - } - - @Override - public <K> K prototypeFor( Class<K> mixinType ) - { - return prototypeInstance.newProxy( mixinType ); - } - - @Override - @SuppressWarnings( "unchecked" ) - public T newInstance() - throws ConstructionException - { - Class<Composite> valueType = (Class<Composite>) first( prototypeInstance.types() ); - - ModelModule<ValueModel> valueModel = currentModule.typeLookup().lookupValueModel( valueType ); - - if( valueModel == null ) - { - throw new NoSuchValueException( valueType.getName(), currentModule.name() ); - } - return new ValueBuilderWithPrototype<>( valueModel, currentModule, prototype() ).newInstance(); - } - -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java deleted file mode 100644 index f6a40ae..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2007, Rickard Ãberg. - * Copyright 2009, Niclas Hedhman. - * Copyright 2012, Kent Sølvsten. - * Copyright 2013, 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.value; - -import java.util.HashMap; -import java.util.Map; -import org.apache.zest.api.association.AssociationDescriptor; -import org.apache.zest.api.association.AssociationStateHolder; -import org.apache.zest.api.association.NamedAssociation; -import org.apache.zest.api.common.ConstructionException; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.property.PropertyDescriptor; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.api.value.ValueComposite; -import org.apache.zest.functional.Function; -import org.apache.zest.runtime.composite.FunctionStateResolver; -import org.apache.zest.runtime.composite.MixinModel; -import org.apache.zest.runtime.composite.MixinsModel; -import org.apache.zest.runtime.composite.StateResolver; -import org.apache.zest.runtime.composite.UsesInstance; -import org.apache.zest.runtime.injection.InjectionContext; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.runtime.structure.ModuleInstance; - -/** - * Implementation of ValueBuilder with a prototype supplied - */ -public class ValueBuilderWithPrototype<T> - implements ValueBuilder<T> -{ - private ValueInstance prototypeInstance; - private final ValueModel valueModel; - - public ValueBuilderWithPrototype( ModelModule<ValueModel> compositeModelModule, - ModuleInstance currentModule, - T prototype - ) - { - valueModel = compositeModelModule.model(); - // Only shallow clone, as all generic types of the ValueComposites are expected to be Immutable. - - MixinsModel mixinsModel = valueModel.mixinsModel(); - Object[] mixins = mixinsModel.newMixinHolder(); - final ValueStateInstance prototypeState = ValueInstance.valueInstanceOf( (ValueComposite) prototype ).state(); - StateResolver resolver = new FunctionStateResolver( - new PropertyDescriptorFunction( prototypeState ), - new AssociationDescriptorEntityReferenceFunction( prototypeState ), - new AssociationDescriptorIterableFunction( prototypeState ), - new AssociationDescriptorMapFunction( prototypeState ) - ); - ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, resolver ); - ValueInstance valueInstance = new ValueInstance( - valueModel, - currentModule, - mixins, - state - ); - - int i = 0; - InjectionContext injectionContext = new InjectionContext( valueInstance, UsesInstance.EMPTY_USES, state ); - for( MixinModel mixinModel : mixinsModel.mixinModels() ) - { - mixins[ i++ ] = mixinModel.newInstance( injectionContext ); - } - -// // Use serialization-deserialization to make a copy of the prototype -// final Object value; -// try -// { -// // @TODO there is probably a more efficient way to do this -// ValueSerialization valueSerialization = currentModule.valueSerialization(); -// String serialized = valueSerialization.serialize( prototype ); -// value = valueSerialization.deserialize( valueModel.valueType(), serialized); -// } -// catch( ValueSerializationException e ) -// { -// throw new IllegalStateException( "Could not serialize-copy Value", e ); -// } - -// ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value ); - valueInstance.prepareToBuild(); - this.prototypeInstance = valueInstance; - } - - @Override - public T prototype() - { - verifyUnderConstruction(); - return prototypeInstance.<T>proxy(); - } - - @Override - public AssociationStateHolder state() - { - verifyUnderConstruction(); - return prototypeInstance.state(); - } - - @Override - public <K> K prototypeFor( Class<K> mixinType ) - { - verifyUnderConstruction(); - return prototypeInstance.newProxy( mixinType ); - } - - @Override - public T newInstance() - throws ConstructionException - { - verifyUnderConstruction(); - - // Set correct info's (immutable) on the state - prototypeInstance.prepareBuilderState(); - - // Check that it is valid - valueModel.checkConstraints( prototypeInstance.state() ); - - try - { - return prototypeInstance.<T>proxy(); - } - finally - { - // Invalidate builder - prototypeInstance = null; - } - } - - private void verifyUnderConstruction() - { - if( prototypeInstance == null ) - { - throw new IllegalStateException( "ValueBuilder instances cannot be reused" ); - } - } - - private static class PropertyDescriptorFunction - implements Function<PropertyDescriptor, Object> - { - private final ValueStateInstance prototypeState; - - public PropertyDescriptorFunction( ValueStateInstance prototypeState ) - { - this.prototypeState = prototypeState; - } - - @Override - public Object map( PropertyDescriptor descriptor ) - { - return prototypeState.propertyFor( descriptor.accessor() ).get(); - } - } - - private static class AssociationDescriptorEntityReferenceFunction - implements Function<AssociationDescriptor, EntityReference> - { - private final ValueStateInstance prototypeState; - - public AssociationDescriptorEntityReferenceFunction( ValueStateInstance prototypeState ) - { - this.prototypeState = prototypeState; - } - - @Override - public EntityReference map( AssociationDescriptor descriptor ) - { - return prototypeState.associationFor( descriptor.accessor() ).reference(); - } - } - - private static class AssociationDescriptorIterableFunction - implements Function<AssociationDescriptor, Iterable<EntityReference>> - { - private final ValueStateInstance prototypeState; - - public AssociationDescriptorIterableFunction( ValueStateInstance prototypeState ) - { - this.prototypeState = prototypeState; - } - - @Override - public Iterable<EntityReference> map( AssociationDescriptor descriptor ) - { - return prototypeState.manyAssociationFor( descriptor.accessor() ).references(); - } - } - - private static class AssociationDescriptorMapFunction - implements Function<AssociationDescriptor, Map<String, EntityReference>> - { - private final ValueStateInstance prototypeState; - - public AssociationDescriptorMapFunction( ValueStateInstance prototypeState ) - { - this.prototypeState = prototypeState; - } - - @Override - public Map<String, EntityReference> map( AssociationDescriptor descriptor ) - { - Map<String, EntityReference> result = new HashMap<>(); - NamedAssociation<?> namedAssociation = prototypeState.namedAssociationFor( descriptor.accessor() ); - for( String name : namedAssociation ) - { - result.put( name, namedAssociation.referenceOf( name ) ); - } - return result; - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithState.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithState.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithState.java deleted file mode 100644 index 57413b5..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithState.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2012, Kent Sølvsten. 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.value; - -import org.apache.zest.api.association.AssociationStateHolder; -import org.apache.zest.api.common.ConstructionException; -import org.apache.zest.api.value.ValueBuilder; -import org.apache.zest.runtime.composite.StateResolver; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.runtime.structure.ModuleInstance; - -public class ValueBuilderWithState<T> implements ValueBuilder<T> -{ - private final ModelModule<ValueModel> model; - private ValueInstance prototypeInstance; - - public ValueBuilderWithState( ModelModule<ValueModel> compositeModelModule, - ModuleInstance currentModule, - StateResolver stateResolver ) - { - ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, stateResolver ); - ValueInstance instance = compositeModelModule.model().newValueInstance( compositeModelModule.module(), state ); - instance.prepareToBuild(); - this.model = compositeModelModule; - this.prototypeInstance = instance; - } - - @Override - public T prototype() - { - verifyUnderConstruction(); - return prototypeInstance.<T>proxy(); - } - - @Override - public AssociationStateHolder state() - { - verifyUnderConstruction(); - return prototypeInstance.state(); - } - - @Override - public <K> K prototypeFor( Class<K> mixinType ) - { - verifyUnderConstruction(); - - return prototypeInstance.newProxy( mixinType ); - } - - @Override - public T newInstance() - throws ConstructionException - { - verifyUnderConstruction(); - - // Set correct info's (immutable) on the state - prototypeInstance.prepareBuilderState(); - - // Check that it is valid - model.model().checkConstraints( prototypeInstance.state() ); - - try - { - return prototypeInstance.<T>proxy(); - } - finally - { - // Invalidate builder - prototypeInstance = null; - } - } - - private void verifyUnderConstruction() - { - if( prototypeInstance == null ) - { - throw new IllegalStateException( "ValueBuilder instances cannot be reused" ); - } - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueInstance.java deleted file mode 100644 index 3141ac1..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueInstance.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. - * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. - * Copyright (c) 2007, Alin Dreghiciu. All Rights Reserved. - * Copyright (c) 2012, 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.value; - -import java.lang.reflect.Proxy; -import org.apache.zest.api.composite.CompositeInstance; -import org.apache.zest.api.value.ValueComposite; -import org.apache.zest.runtime.association.AssociationModel; -import org.apache.zest.runtime.association.ManyAssociationModel; -import org.apache.zest.runtime.association.NamedAssociationModel; -import org.apache.zest.runtime.composite.MixinsInstance; -import org.apache.zest.runtime.composite.TransientInstance; -import org.apache.zest.runtime.property.PropertyInstance; -import org.apache.zest.runtime.property.PropertyModel; -import org.apache.zest.spi.module.ModuleSpi; - -/** - * ValueComposite instance - */ -public final class ValueInstance - extends TransientInstance - implements CompositeInstance, MixinsInstance -{ - public static ValueInstance valueInstanceOf( ValueComposite composite ) - { - return (ValueInstance) Proxy.getInvocationHandler( composite ); - } - - public ValueInstance( ValueModel compositeModel, - ModuleSpi moduleInstance, - Object[] mixins, - ValueStateInstance state - ) - { - super( compositeModel, moduleInstance, mixins, state ); - } - - /** - * Perform equals with {@code o} argument. - * <p> - * The definition of equals() for the Value is that if both the state and descriptor are equal, - * then the values are equal. - * </p> - * - * @param o The other object to compare. - * - * @return Returns a {@code boolean} indicator whether this object is equals the other. - */ - @Override - public boolean equals( Object o ) - { - if( this == o ) - { - return true; - } - if( o == null || !Proxy.isProxyClass( o.getClass() ) ) - { - return false; - } - - try - { - ValueInstance that = (ValueInstance) Proxy.getInvocationHandler( o ); - // Descriptor equality - if( !descriptor().equals( that.descriptor() ) ) - { - return false; - } - // State equality - return state.equals( that.state ); - } - catch( ClassCastException e ) - { - return false; - } - } - - @Override - public ValueStateInstance state() - { - return (ValueStateInstance) state; - } - - @Override - public ValueModel descriptor() - { - return (ValueModel) compositeModel; - } - - /** - * When a ValueBuilder is about to start, ensure that all state has builder infos, i.e. they are mutable. - */ - public void prepareToBuild() - { - for( PropertyModel propertyDescriptor : descriptor().state().properties() ) - { - PropertyInstance<Object> propertyInstance = - (PropertyInstance<Object>) state.propertyFor( propertyDescriptor.accessor() ); - - propertyInstance.prepareToBuild( propertyDescriptor ); - } - - for( AssociationModel associationDescriptor : descriptor().state().associations() ) - { - state().associationFor( associationDescriptor.accessor() ) - .setAssociationInfo( associationDescriptor.getBuilderInfo() ); - } - - for( ManyAssociationModel associationDescriptor : descriptor().state().manyAssociations() ) - { - state().manyAssociationFor( associationDescriptor.accessor() ) - .setAssociationInfo( associationDescriptor.getBuilderInfo() ); - } - - for( NamedAssociationModel associationDescriptor : descriptor().state().namedAssociations() ) - { - state().namedAssociationFor( associationDescriptor.accessor() ) - .setAssociationInfo( associationDescriptor.getBuilderInfo() ); - } - } - - /** - * When a ValueBuilder is finished and is about to instantiate a Value, call this to ensure that the state has correct - * settings, i.e. is immutable. - */ - public void prepareBuilderState() - { - for( PropertyModel propertyDescriptor : descriptor().state().properties() ) - { - PropertyInstance<Object> propertyInstance = - (PropertyInstance<Object>) state.propertyFor( propertyDescriptor.accessor() ); - propertyInstance.prepareBuilderState( propertyDescriptor ); - } - - for( AssociationModel associationDescriptor : descriptor().state().associations() ) - { - state().associationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor ); - } - - for( ManyAssociationModel associationDescriptor : descriptor().state().manyAssociations() ) - { - state().manyAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor ); - } - - for( NamedAssociationModel associationDescriptor : descriptor().state().namedAssociations() ) - { - state().namedAssociationFor( associationDescriptor.accessor() ).setAssociationInfo( associationDescriptor ); - } - } - - /** - * Calculate hash code. - * - * @return the hashcode of this instance. - */ - @Override - public int hashCode() - { - int hash = compositeModel.hashCode() * 23; // Descriptor - return hash + state.hashCode() * 5; // State - } - - @Override - public String toString() - { - return ( (ModuleSpi) module() ).valueSerialization().serialize( this.<ValueComposite>proxy() ); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueModel.java deleted file mode 100644 index aa8c9b4..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueModel.java +++ /dev/null @@ -1,112 +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.value; - -import org.apache.zest.api.common.MetaInfo; -import org.apache.zest.api.common.Visibility; -import org.apache.zest.api.constraint.ConstraintViolationException; -import org.apache.zest.api.type.ValueCompositeType; -import org.apache.zest.api.value.ValueDescriptor; -import org.apache.zest.runtime.association.AssociationModel; -import org.apache.zest.runtime.association.ManyAssociationModel; -import org.apache.zest.runtime.composite.CompositeMethodsModel; -import org.apache.zest.runtime.composite.CompositeModel; -import org.apache.zest.runtime.composite.MixinModel; -import org.apache.zest.runtime.composite.MixinsModel; -import org.apache.zest.runtime.composite.UsesInstance; -import org.apache.zest.runtime.injection.InjectionContext; -import org.apache.zest.runtime.property.PropertyModel; -import org.apache.zest.runtime.unitofwork.UnitOfWorkInstance; -import org.apache.zest.spi.module.ModuleSpi; - -/** - * Model for ValueComposites - */ -public final class ValueModel - extends CompositeModel - implements ValueDescriptor -{ - private ValueCompositeType valueType; - - public ValueModel( final Iterable<Class<?>> types, - final Visibility visibility, - final MetaInfo metaInfo, - final MixinsModel mixinsModel, - final ValueStateModel stateModel, - final CompositeMethodsModel compositeMethodsModel - ) - { - super( types, visibility, metaInfo, mixinsModel, stateModel, compositeMethodsModel ); - - valueType = new ValueCompositeType( this ); - } - - @Override - public ValueCompositeType valueType() - { - return valueType; - } - - @Override - public ValueStateModel state() - { - return (ValueStateModel) super.state(); - } - - // This method is ONLY called by ValueBuilders - void checkConstraints( ValueStateInstance state ) - throws ConstraintViolationException - { - for( PropertyModel propertyModel : stateModel.properties() ) - { - propertyModel.checkConstraints( state.propertyFor( propertyModel.accessor() ).get() ); - } - - // IF no UnitOfWork is active, then the Association checks shouldn't be done. - if( UnitOfWorkInstance.getCurrent().empty() ) - { - return; - } - for( AssociationModel associationModel : ( (ValueStateModel) stateModel ).associations() ) - { - associationModel.checkConstraints( state.associationFor( associationModel.accessor() ).get() ); - } - - for( ManyAssociationModel associationModel : ( (ValueStateModel) stateModel ).manyAssociations() ) - { - associationModel.checkAssociationConstraints( state.manyAssociationFor( associationModel.accessor() ) ); - } - } - - public ValueInstance newValueInstance( ModuleSpi moduleInstance, - ValueStateInstance state - ) - { - Object[] mixins = mixinsModel.newMixinHolder(); - - ValueInstance instance = new ValueInstance( this, moduleInstance, mixins, state ); - - // Instantiate all mixins - int i = 0; - InjectionContext injectionContext = new InjectionContext( instance, UsesInstance.EMPTY_USES, state ); - for( MixinModel mixinModel : mixinsModel.mixinModels() ) - { - mixins[ i++ ] = mixinModel.newInstance( injectionContext ); - } - - // Return - return instance; - } -} \ 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/value/ValueStateInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java deleted file mode 100644 index 84a2719..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2008-2011, Rickard Ãberg. All Rights Reserved. - * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved. - * Copyright (c) 2012, Kent Sølvsten. 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.value; - -import java.lang.reflect.AccessibleObject; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import org.apache.zest.api.association.AssociationDescriptor; -import org.apache.zest.api.association.AssociationStateHolder; -import org.apache.zest.api.entity.EntityReference; -import org.apache.zest.api.property.PropertyDescriptor; -import org.apache.zest.runtime.association.AssociationInfo; -import org.apache.zest.runtime.association.AssociationInstance; -import org.apache.zest.runtime.association.AssociationModel; -import org.apache.zest.runtime.association.ManyAssociationInstance; -import org.apache.zest.runtime.association.ManyAssociationModel; -import org.apache.zest.runtime.association.NamedAssociationInstance; -import org.apache.zest.runtime.association.NamedAssociationModel; -import org.apache.zest.runtime.composite.StateResolver; -import org.apache.zest.runtime.property.PropertyInfo; -import org.apache.zest.runtime.property.PropertyInstance; -import org.apache.zest.runtime.property.PropertyModel; -import org.apache.zest.spi.module.ModelModule; -import org.apache.zest.runtime.structure.ModuleInstance; - -/** - * TODO - */ -public final class ValueStateInstance - implements AssociationStateHolder -{ - private final Map<AccessibleObject, PropertyInstance<?>> properties; - private final Map<AccessibleObject, AssociationInstance<?>> associations; - private final Map<AccessibleObject, ManyAssociationInstance<?>> manyAssociations; - private final Map<AccessibleObject, NamedAssociationInstance<?>> namedAssociations; - - public ValueStateInstance( Map<AccessibleObject, PropertyInstance<?>> properties, - Map<AccessibleObject, AssociationInstance<?>> associations, - Map<AccessibleObject, ManyAssociationInstance<?>> manyAssociations, - Map<AccessibleObject, NamedAssociationInstance<?>> namedAssociations - ) - { - this.properties = properties; - this.associations = associations; - this.manyAssociations = manyAssociations; - this.namedAssociations = namedAssociations; - } - - public ValueStateInstance( ModelModule<ValueModel> compositeModelModule, - ModuleInstance currentModule, - StateResolver stateResolver ) - { - ValueModel valueModel = compositeModelModule.model(); - this.properties = new LinkedHashMap<>(); - for( PropertyDescriptor propertyDescriptor : valueModel.state().properties() ) - { - PropertyInfo builderInfo = ( (PropertyModel) propertyDescriptor ).getBuilderInfo(); - Object value = stateResolver.getPropertyState( propertyDescriptor ); - PropertyInstance<Object> propertyInstance = new PropertyInstance<>( builderInfo, value ); - properties.put( propertyDescriptor.accessor(), propertyInstance ); - } - - this.associations = new LinkedHashMap<>(); - for( AssociationDescriptor associationDescriptor : valueModel.state().associations() ) - { - AssociationInfo builderInfo = ( (AssociationModel) associationDescriptor ).getBuilderInfo(); - EntityReference value = stateResolver.getAssociationState( associationDescriptor ); - AssociationInstance<Object> associationInstance1 = new AssociationInstance<>( - builderInfo, - currentModule.getEntityFunction(), - new ReferenceProperty( value ) ); - associations.put( associationDescriptor.accessor(), associationInstance1 ); - } - - this.manyAssociations = new LinkedHashMap<>(); - for( AssociationDescriptor associationDescriptor : valueModel.state().manyAssociations() ) - { - AssociationInfo builderInfo = ( (ManyAssociationModel) associationDescriptor ).getBuilderInfo(); - List<EntityReference> value = stateResolver.getManyAssociationState( associationDescriptor ); - ManyAssociationValueState manyAssociationState = new ManyAssociationValueState( value ); - ManyAssociationInstance<Object> associationInstance = new ManyAssociationInstance<>( - builderInfo, - currentModule.getEntityFunction(), - manyAssociationState ); - manyAssociations.put( associationDescriptor.accessor(), associationInstance ); - } - - this.namedAssociations = new LinkedHashMap<>(); - for( AssociationDescriptor associationDescriptor : valueModel.state().namedAssociations() ) - { - AssociationInfo builderInfo = ( (NamedAssociationModel) associationDescriptor ).getBuilderInfo(); - Map<String, EntityReference> value = stateResolver.getNamedAssociationState( associationDescriptor ); - NamedAssociationValueState namedAssociationState = new NamedAssociationValueState( value ); - NamedAssociationInstance<Object> associationInstance = new NamedAssociationInstance<>( - builderInfo, - currentModule.getEntityFunction(), - namedAssociationState ); - namedAssociations.put( associationDescriptor.accessor(), associationInstance ); - } - } - - @Override - @SuppressWarnings( "unchecked" ) - public <T> PropertyInstance<T> propertyFor( AccessibleObject accessor ) - throws IllegalArgumentException - { - PropertyInstance<T> property = (PropertyInstance<T>) properties.get( accessor ); - - if( property == null ) - { - throw new IllegalArgumentException( "No such property:" + accessor ); - } - - return property; - } - - @Override - public Iterable<PropertyInstance<?>> properties() - { - return properties.values(); - } - - @Override - @SuppressWarnings( "unchecked" ) - public <T> AssociationInstance<T> associationFor( AccessibleObject accessor ) - { - AssociationInstance<T> association = (AssociationInstance<T>) associations.get( accessor ); - - if( association == null ) - { - throw new IllegalArgumentException( "No such association:" + accessor ); - } - - return association; - } - - @Override - public Iterable<AssociationInstance<?>> allAssociations() - { - return associations.values(); - } - - @Override - @SuppressWarnings( "unchecked" ) - public <T> ManyAssociationInstance<T> manyAssociationFor( AccessibleObject accessor ) - { - ManyAssociationInstance<T> manyAssociation = (ManyAssociationInstance<T>) manyAssociations.get( accessor ); - - if( manyAssociation == null ) - { - throw new IllegalArgumentException( "No such many-association:" + accessor ); - } - - return manyAssociation; - } - - @Override - public Iterable<ManyAssociationInstance<?>> allManyAssociations() - { - return manyAssociations.values(); - } - - @Override - @SuppressWarnings( "unchecked" ) - public <T> NamedAssociationInstance<T> namedAssociationFor( AccessibleObject accessor ) - { - NamedAssociationInstance<T> namedAssociation = (NamedAssociationInstance<T>) namedAssociations.get( accessor ); - - if( namedAssociation == null ) - { - throw new IllegalArgumentException( "No such named-association:" + accessor ); - } - - return namedAssociation; - } - - @Override - public Iterable<? extends NamedAssociationInstance<?>> allNamedAssociations() - { - return namedAssociations.values(); - } - - @Override - public boolean equals( Object obj ) - { - if( !( obj instanceof ValueStateInstance ) ) - { - return false; - } - ValueStateInstance state = (ValueStateInstance) obj; - if( !properties.equals( state.properties ) ) - { - return false; - } - if( !associations.equals( state.associations ) ) - { - return false; - } - if( !manyAssociations.equals( state.manyAssociations ) ) - { - return false; - } - return namedAssociations.equals( state.namedAssociations ); - } - - @Override - public int hashCode() - { - int result = properties.hashCode(); - result = 31 * result + associations.hashCode(); - result = 31 * result + manyAssociations.hashCode(); - result = 31 * result + namedAssociations.hashCode(); - return result; - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateModel.java deleted file mode 100644 index e34398f..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateModel.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2008-2011, Rickard Ãberg. - * Copyright (c) 2012, Kent Sølvsten. - * Copyright (c) 2014-2015, 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.value; - -import org.apache.zest.api.association.AssociationDescriptor; -import org.apache.zest.api.association.AssociationStateDescriptor; -import org.apache.zest.api.common.QualifiedName; -import org.apache.zest.functional.HierarchicalVisitor; -import org.apache.zest.functional.VisitableHierarchy; -import org.apache.zest.runtime.association.AssociationModel; -import org.apache.zest.runtime.association.AssociationsModel; -import org.apache.zest.runtime.association.ManyAssociationModel; -import org.apache.zest.runtime.association.ManyAssociationsModel; -import org.apache.zest.runtime.association.NamedAssociationModel; -import org.apache.zest.runtime.association.NamedAssociationsModel; -import org.apache.zest.runtime.composite.StateModel; -import org.apache.zest.runtime.property.PropertiesModel; - -/** - * Model for ValueComposite state. - */ -public final class ValueStateModel - extends StateModel - implements AssociationStateDescriptor -{ - private final AssociationsModel associationsModel; - private final ManyAssociationsModel manyAssociationsModel; - private final NamedAssociationsModel namedAssociationsModel; - - public ValueStateModel( PropertiesModel propertiesModel, - AssociationsModel associationsModel, - ManyAssociationsModel manyAssociationsModel, - NamedAssociationsModel namedAssociationsModel - ) - { - super( propertiesModel ); - this.associationsModel = associationsModel; - this.manyAssociationsModel = manyAssociationsModel; - this.namedAssociationsModel = namedAssociationsModel; - } - - @Override - public AssociationDescriptor getAssociationByName( String name ) - { - return associationsModel.getAssociationByName( name ); - } - - @Override - public AssociationDescriptor getAssociationByQualifiedName( QualifiedName name ) - { - return associationsModel.getAssociationByQualifiedName( name ); - } - - @Override - public AssociationDescriptor getManyAssociationByName( String name ) - { - return manyAssociationsModel.getManyAssociationByName( name ); - } - - @Override - public AssociationDescriptor getManyAssociationByQualifiedName( QualifiedName name ) - { - return manyAssociationsModel.getManyAssociationByQualifiedName( name ); - } - - @Override - public AssociationDescriptor getNamedAssociationByName( String name ) - { - return namedAssociationsModel.getNamedAssociationByName( name ); - } - - @Override - public AssociationDescriptor getNamedAssociationByQualifiedName( QualifiedName name ) - { - return namedAssociationsModel.getNamedAssociationByQualifiedName( name ); - } - - @Override - public Iterable<AssociationModel> associations() - { - return associationsModel.associations(); - } - - @Override - public Iterable<ManyAssociationModel> manyAssociations() - { - return manyAssociationsModel.manyAssociations(); - } - - @Override - public Iterable<NamedAssociationModel> namedAssociations() - { - return namedAssociationsModel.namedAssociations(); - } - - @Override - public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor ) - throws ThrowableType - { - if( visitor.visitEnter( this ) ) - { - if( ( (VisitableHierarchy<Object, Object>) propertiesModel ).accept( visitor ) ) - { - if( ( (VisitableHierarchy<AssociationsModel, AssociationModel>) associationsModel ).accept( visitor ) ) - { - if( ( (VisitableHierarchy<ManyAssociationsModel, ManyAssociationModel>) manyAssociationsModel ).accept( visitor ) ) - { - ( (VisitableHierarchy<NamedAssociationsModel, NamedAssociationModel>) namedAssociationsModel ).accept( visitor ); - } - } - } - } - return visitor.visitLeave( this ); - } -} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/apache/zest/runtime/value/ValuesModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValuesModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValuesModel.java deleted file mode 100644 index 08f91e1..0000000 --- a/core/runtime/src/main/java/org/apache/zest/runtime/value/ValuesModel.java +++ /dev/null @@ -1,55 +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.value; - -import java.util.List; -import org.apache.zest.functional.HierarchicalVisitor; -import org.apache.zest.functional.VisitableHierarchy; - -/** - * JAVADOC - */ -public final class ValuesModel - implements VisitableHierarchy<Object, Object> -{ - private final List<ValueModel> valueModels; - - public ValuesModel( List<ValueModel> valueModels ) - { - this.valueModels = valueModels; - } - - public Iterable<ValueModel> models() - { - return valueModels; - } - - @Override - public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor ) - throws ThrowableType - { - if( visitor.visitEnter( this ) ) - { - for( ValueModel valueModel : valueModels ) - { - if( !valueModel.accept( visitor ) ) - { - break; - } - } - } - return visitor.visitLeave( this ); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java b/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java new file mode 100644 index 0000000..232ad6f --- /dev/null +++ b/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2007, 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.qi4j.runtime; + +import java.lang.reflect.InvocationHandler; +import java.util.Arrays; +import java.util.Map; +import org.qi4j.api.Qi4j; +import org.qi4j.api.association.AbstractAssociation; +import org.qi4j.api.association.Association; +import org.qi4j.api.association.AssociationDescriptor; +import org.qi4j.api.association.AssociationStateHolder; +import org.qi4j.api.association.AssociationWrapper; +import org.qi4j.api.association.ManyAssociation; +import org.qi4j.api.association.ManyAssociationWrapper; +import org.qi4j.api.association.NamedAssociation; +import org.qi4j.api.association.NamedAssociationWrapper; +import org.qi4j.api.composite.Composite; +import org.qi4j.api.composite.CompositeDescriptor; +import org.qi4j.api.composite.CompositeInstance; +import org.qi4j.api.composite.ModelDescriptor; +import org.qi4j.api.composite.TransientComposite; +import org.qi4j.api.composite.TransientDescriptor; +import org.qi4j.api.entity.EntityComposite; +import org.qi4j.api.entity.EntityDescriptor; +import org.qi4j.api.entity.EntityReference; +import org.qi4j.api.property.Property; +import org.qi4j.api.property.PropertyDescriptor; +import org.qi4j.api.property.PropertyWrapper; +import org.qi4j.api.property.StateHolder; +import org.qi4j.api.service.ServiceComposite; +import org.qi4j.api.service.ServiceDescriptor; +import org.qi4j.api.service.ServiceReference; +import org.qi4j.api.structure.Module; +import org.qi4j.api.unitofwork.UnitOfWork; +import org.qi4j.api.value.ValueComposite; +import org.qi4j.api.value.ValueDescriptor; +import org.qi4j.bootstrap.ApplicationAssemblyFactory; +import org.qi4j.bootstrap.ApplicationModelFactory; +import org.qi4j.bootstrap.Qi4jRuntime; +import org.qi4j.runtime.association.AbstractAssociationInstance; +import org.qi4j.runtime.association.AssociationInstance; +import org.qi4j.runtime.association.ManyAssociationInstance; +import org.qi4j.runtime.association.NamedAssociationInstance; +import org.qi4j.runtime.bootstrap.ApplicationAssemblyFactoryImpl; +import org.qi4j.runtime.bootstrap.ApplicationModelFactoryImpl; +import org.qi4j.runtime.composite.ProxyReferenceInvocationHandler; +import org.qi4j.runtime.composite.TransientInstance; +import org.qi4j.runtime.entity.EntityInstance; +import org.qi4j.runtime.property.PropertyInstance; +import org.qi4j.runtime.service.ImportedServiceReferenceInstance; +import org.qi4j.runtime.service.ServiceInstance; +import org.qi4j.runtime.service.ServiceReferenceInstance; +import org.qi4j.runtime.structure.ModuleUnitOfWork; +import org.qi4j.runtime.value.ValueInstance; +import org.qi4j.spi.Qi4jSPI; +import org.qi4j.spi.entity.EntityState; + +import static java.lang.reflect.Proxy.getInvocationHandler; +import static org.qi4j.runtime.composite.TransientInstance.compositeInstanceOf; + +/** + * Incarnation of Zest. + */ +public final class Qi4jRuntimeImpl + implements Qi4jSPI, Qi4jRuntime +{ + private final ApplicationAssemblyFactory applicationAssemblyFactory; + private final ApplicationModelFactory applicationModelFactory; + + public Qi4jRuntimeImpl() + { + applicationAssemblyFactory = new ApplicationAssemblyFactoryImpl(); + applicationModelFactory = new ApplicationModelFactoryImpl(); + } + + @Override + public ApplicationAssemblyFactory applicationAssemblyFactory() + { + return applicationAssemblyFactory; + } + + @Override + public ApplicationModelFactory applicationModelFactory() + { + return applicationModelFactory; + } + + @Override + public Qi4j api() + { + return this; + } + + @Override + public Qi4jSPI spi() + { + return this; + } + + // API + + @Override + @SuppressWarnings( "unchecked" ) + public <T> T dereference( T composite ) + { + InvocationHandler handler = getInvocationHandler( composite ); + if( handler instanceof ProxyReferenceInvocationHandler ) + { + return (T) ( (ProxyReferenceInvocationHandler) handler ).proxy(); + } + if( handler instanceof CompositeInstance ) + { + return composite; + } + return null; + } + + @Override + public Module moduleOf( Object compositeOrServiceReferenceOrUow ) + { + if( compositeOrServiceReferenceOrUow instanceof TransientComposite ) + { + TransientComposite composite = (TransientComposite) compositeOrServiceReferenceOrUow; + return TransientInstance.compositeInstanceOf( composite ).module(); + } + else if( compositeOrServiceReferenceOrUow instanceof EntityComposite ) + { + EntityComposite composite = (EntityComposite) compositeOrServiceReferenceOrUow; + return EntityInstance.entityInstanceOf( composite ).module(); + } + else if( compositeOrServiceReferenceOrUow instanceof ValueComposite ) + { + ValueComposite composite = (ValueComposite) compositeOrServiceReferenceOrUow; + return ValueInstance.valueInstanceOf( composite ).module(); + } + else if( compositeOrServiceReferenceOrUow instanceof ServiceComposite ) + { + ServiceComposite composite = (ServiceComposite) compositeOrServiceReferenceOrUow; + InvocationHandler handler = getInvocationHandler( composite ); + if( handler instanceof ServiceInstance ) + { + return ( (ServiceInstance) handler ).module(); + } + return ( (ServiceReferenceInstance.ServiceInvocationHandler) handler ).module(); + } + else if( compositeOrServiceReferenceOrUow instanceof UnitOfWork ) + { + ModuleUnitOfWork unitOfWork = (ModuleUnitOfWork) compositeOrServiceReferenceOrUow; + return unitOfWork.module(); + } + else if( compositeOrServiceReferenceOrUow instanceof ServiceReferenceInstance ) + { + ServiceReferenceInstance<?> reference = (ServiceReferenceInstance<?>) compositeOrServiceReferenceOrUow; + return reference.module(); + } + else if( compositeOrServiceReferenceOrUow instanceof ImportedServiceReferenceInstance ) + { + ImportedServiceReferenceInstance<?> importedServiceReference + = (ImportedServiceReferenceInstance<?>) compositeOrServiceReferenceOrUow; + return importedServiceReference.module(); + } + throw new IllegalArgumentException( "Wrong type. Must be one of " + + Arrays.asList( TransientComposite.class, ValueComposite.class, + ServiceComposite.class, ServiceReference.class, + UnitOfWork.class ) ); + } + + @Override + public ModelDescriptor modelDescriptorFor( Object compositeOrServiceReference ) + { + if( compositeOrServiceReference instanceof TransientComposite ) + { + TransientComposite composite = (TransientComposite) compositeOrServiceReference; + return TransientInstance.compositeInstanceOf( composite ).descriptor(); + } + else if( compositeOrServiceReference instanceof EntityComposite ) + { + EntityComposite composite = (EntityComposite) compositeOrServiceReference; + return EntityInstance.entityInstanceOf( composite ).descriptor(); + } + else if( compositeOrServiceReference instanceof ValueComposite ) + { + ValueComposite composite = (ValueComposite) compositeOrServiceReference; + return ValueInstance.valueInstanceOf( composite ).descriptor(); + } + else if( compositeOrServiceReference instanceof ServiceComposite ) + { + ServiceComposite composite = (ServiceComposite) compositeOrServiceReference; + InvocationHandler handler = getInvocationHandler( composite ); + if( handler instanceof ServiceInstance ) + { + return ( (ServiceInstance) handler ).descriptor(); + } + return ( (ServiceReferenceInstance.ServiceInvocationHandler) handler ).descriptor(); + } + else if( compositeOrServiceReference instanceof ServiceReferenceInstance ) + { + ServiceReferenceInstance<?> reference = (ServiceReferenceInstance<?>) compositeOrServiceReference; + return reference.serviceDescriptor(); + } + else if( compositeOrServiceReference instanceof ImportedServiceReferenceInstance ) + { + ImportedServiceReferenceInstance<?> importedServiceReference + = (ImportedServiceReferenceInstance<?>) compositeOrServiceReference; + return importedServiceReference.serviceDescriptor(); + } + throw new IllegalArgumentException( "Wrong type. Must be one of " + + Arrays.asList( TransientComposite.class, ValueComposite.class, + ServiceComposite.class, ServiceReference.class ) ); + } + + @Override + public CompositeDescriptor compositeDescriptorFor( Object compositeOrServiceReference ) + { + return (CompositeDescriptor) modelDescriptorFor( compositeOrServiceReference ); + } + + // Descriptors + + @Override + public TransientDescriptor transientDescriptorFor( Object transsient ) + { + if( transsient instanceof TransientComposite ) + { + TransientInstance transientInstance = compositeInstanceOf( (Composite) transsient ); + return (TransientDescriptor) transientInstance.descriptor(); + } + throw new IllegalArgumentException( "Wrong type. Must be subtype of " + TransientComposite.class ); + } + + @Override + public StateHolder stateOf( TransientComposite composite ) + { + return TransientInstance.compositeInstanceOf( composite ).state(); + } + + @Override + public EntityDescriptor entityDescriptorFor( Object entity ) + { + if( entity instanceof EntityComposite ) + { + EntityInstance entityInstance = (EntityInstance) getInvocationHandler( entity ); + return entityInstance.entityModel(); + } + throw new IllegalArgumentException( "Wrong type. Must be subtype of " + EntityComposite.class ); + } + + @Override + public AssociationStateHolder stateOf( EntityComposite composite ) + { + return EntityInstance.entityInstanceOf( composite ).state(); + } + + @Override + public ValueDescriptor valueDescriptorFor( Object value ) + { + if( value instanceof ValueComposite ) + { + ValueInstance valueInstance = ValueInstance.valueInstanceOf( (ValueComposite) value ); + return valueInstance.descriptor(); + } + throw new IllegalArgumentException( "Wrong type. Must be subtype of " + ValueComposite.class ); + } + + @Override + public AssociationStateHolder stateOf( ValueComposite composite ) + { + return ValueInstance.valueInstanceOf( composite ).state(); + } + + @Override + public ServiceDescriptor serviceDescriptorFor( Object service ) + { + if( service instanceof ServiceReferenceInstance ) + { + ServiceReferenceInstance<?> ref = (ServiceReferenceInstance<?>) service; + return ref.serviceDescriptor(); + } + if( service instanceof ServiceComposite ) + { + ServiceComposite composite = (ServiceComposite) service; + return (ServiceDescriptor) ServiceInstance.serviceInstanceOf( composite ).descriptor(); + } + throw new IllegalArgumentException( "Wrong type. Must be subtype of " + + ServiceComposite.class + " or " + ServiceReference.class ); + } + + @Override + public PropertyDescriptor propertyDescriptorFor( Property<?> property ) + { + while( property instanceof PropertyWrapper ) + { + property = ( (PropertyWrapper) property ).next(); + } + + return (PropertyDescriptor) ( (PropertyInstance<?>) property ).propertyInfo(); + } + + @Override + public AssociationDescriptor associationDescriptorFor( AbstractAssociation association ) + { + while( association instanceof AssociationWrapper ) + { + association = ( (AssociationWrapper) association ).next(); + } + + while( association instanceof ManyAssociationWrapper ) + { + association = ( (ManyAssociationWrapper) association ).next(); + } + + while( association instanceof NamedAssociationWrapper ) + { + association = ( (NamedAssociationWrapper) association ).next(); + } + + return (AssociationDescriptor) ( (AbstractAssociationInstance) association ).associationInfo(); + } + + // SPI + @Override + public EntityState entityStateOf( EntityComposite composite ) + { + return EntityInstance.entityInstanceOf( composite ).entityState(); + } + + @Override + public EntityReference entityReferenceOf( Association assoc ) + { + @SuppressWarnings( "unchecked" ) + Property<EntityReference> associationState = ( (AssociationInstance) assoc ).getAssociationState(); + return associationState.get(); + } + + @Override + public Iterable<EntityReference> entityReferenceOf( ManyAssociation assoc ) + { + return ( (ManyAssociationInstance) assoc ).getManyAssociationState(); + } + + @Override + public Iterable<Map.Entry<String, EntityReference>> entityReferenceOf( NamedAssociation assoc ) + { + return ( (NamedAssociationInstance) assoc ).getEntityReferences(); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationDelegate.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationDelegate.java b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationDelegate.java new file mode 100644 index 0000000..86b1d2c --- /dev/null +++ b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationDelegate.java @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * Copyright (c) 2012, Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.qi4j.runtime.activation; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; +import org.qi4j.api.activation.Activation; +import org.qi4j.api.activation.ActivationEvent; +import org.qi4j.api.activation.ActivationEventListener; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.activation.PassivationException; +import org.qi4j.api.service.ServiceReference; + +import static org.qi4j.api.activation.ActivationEvent.EventType.ACTIVATED; +import static org.qi4j.api.activation.ActivationEvent.EventType.ACTIVATING; +import static org.qi4j.api.activation.ActivationEvent.EventType.PASSIVATED; +import static org.qi4j.api.activation.ActivationEvent.EventType.PASSIVATING; + +/** + * This class manage Activation of a target and propagates to children. + */ +@SuppressWarnings( "raw" ) +public final class ActivationDelegate + extends ActivationEventListenerSupport +{ + private final Object target; + private final boolean fireEvents; + private ActivatorsInstance targetActivators = null; + private final LinkedList<Activation> activeChildren = new LinkedList<>(); + + /** + * Create a new ActivationDelegate that will fire events. + * @param target target of Activation + */ + public ActivationDelegate( Object target ) + { + this( target, true ); + } + + /** + * Create a new ActivationDelegate. + * @param target target of Activation + * @param fireEvents if {@link ActivationEvent}s should be fired + */ + public ActivationDelegate( Object target, boolean fireEvents ) + { + super(); + this.target = target; + this.fireEvents = fireEvents; + } + + public void activate( ActivatorsInstance targetActivators, Activation child ) + throws Exception + { + activate( targetActivators, Collections.singleton( child ), null ); + } + + public void activate( ActivatorsInstance targetActivators, Activation child, Runnable callback ) + throws Exception + { + activate( targetActivators, Collections.singleton( child ), callback ); + } + + public void activate( ActivatorsInstance targetActivators, Iterable<? extends Activation> children ) + throws ActivationException + { + activate( targetActivators, children, null ); + } + + @SuppressWarnings( "unchecked" ) + public void activate( ActivatorsInstance targetActivators, Iterable<? extends Activation> children, Runnable callback ) + throws ActivationException + { + if( this.targetActivators != null ) + { + throw new IllegalStateException( "Activation.activate() called multiple times " + + "or without calling passivate() first!" ); + } + + try + { + // Before Activation Events + if( fireEvents ) + { + fireEvent( new ActivationEvent( target, ACTIVATING ) ); + } + + // Before Activation for Activators + targetActivators.beforeActivation( target instanceof ServiceReference + ? new PassiveServiceReference( (ServiceReference) target ) + : target ); + + // Activation + for( Activation child : children ) + { + if( !activeChildren.contains( child ) ) + { + child.activate(); + } + activeChildren.addFirst( child ); + } + + // Internal Activation Callback + if( callback != null ) + { + callback.run(); + } + + // After Activation + targetActivators.afterActivation( target ); + + // After Activation Events + if( fireEvents ) + { + fireEvent( new ActivationEvent( target, ACTIVATED ) ); + } + + // Activated + this.targetActivators = targetActivators; + } + catch( Exception e ) + { + // Passivate actives + try + { + passivate(); + } + catch( PassivationException e1 ) + { + ActivationException activationEx = new ActivationException( "Unable to Activate application.", e ); + activationEx.addSuppressed( e1 ); + throw activationEx; + } + if( e instanceof ActivationException ) + { + throw ( (ActivationException) e ); + } + throw new ActivationException( "Unable to Activate application.", e ); + } + } + + public void passivate() + throws PassivationException + { + passivate( (Runnable) null ); + } + + @SuppressWarnings( "unchecked" ) + public void passivate( Runnable callback ) + throws PassivationException + { + Set<Exception> exceptions = new LinkedHashSet<>(); + + // Before Passivation Events + if( fireEvents ) + { + ActivationEvent event = new ActivationEvent( target, PASSIVATING ); + for( ActivationEventListener listener : listeners ) + { + try + { + listener.onEvent( event ); + } + catch( Exception ex ) + { + if( ex instanceof PassivationException ) + { + exceptions.addAll( ( (PassivationException) ex ).causes() ); + } + else + { + exceptions.add( ex ); + } + } + } + } + + // Before Passivation for Activators + if( targetActivators != null ) + { + try + { + targetActivators.beforePassivation( target ); + } + catch( PassivationException ex ) + { + exceptions.addAll( ex.causes() ); + } + catch( Exception ex ) + { + exceptions.add( ex ); + } + } + + // Passivation + while( !activeChildren.isEmpty() ) + { + passivateOneChild( exceptions ); + } + + // Internal Passivation Callback + if( callback != null ) + { + try + { + callback.run(); + } + catch( Exception ex ) + { + if( ex instanceof PassivationException ) + { + exceptions.addAll( ( (PassivationException) ex ).causes() ); + } + else + { + exceptions.add( ex ); + } + } + } + + // After Passivation for Activators + if( targetActivators != null ) + { + try + { + targetActivators.afterPassivation( target instanceof ServiceReference + ? new PassiveServiceReference( (ServiceReference) target ) + : target ); + } + catch( PassivationException ex ) + { + exceptions.addAll( ex.causes() ); + } + catch( Exception ex ) + { + exceptions.add( ex ); + } + } + targetActivators = null; + + // After Passivation Events + if( fireEvents ) + { + ActivationEvent event = new ActivationEvent( target, PASSIVATED ); + for( ActivationEventListener listener : listeners ) + { + try + { + listener.onEvent( event ); + } + catch( Exception ex ) + { + if( ex instanceof PassivationException ) + { + exceptions.addAll( ( (PassivationException) ex ).causes() ); + } + else + { + exceptions.add( ex ); + } + } + } + } + + // Error handling + if( exceptions.isEmpty() ) + { + return; + } + throw new PassivationException( exceptions ); + } + + @SuppressWarnings( "TooBroadCatch" ) + private void passivateOneChild( Set<Exception> exceptions ) + { + Activation activeChild = activeChildren.removeFirst(); + try + { + activeChild.passivate(); + } + catch( PassivationException ex ) + { + exceptions.addAll( ex.causes() ); + } + catch( Exception ex ) + { + exceptions.add( ex ); + } + } + + @SuppressWarnings( "raw" ) + private static class PassiveServiceReference + implements ServiceReference + { + + private final ServiceReference reference; + + private PassiveServiceReference( ServiceReference reference ) + { + this.reference = reference; + } + + @Override + public String identity() + { + return reference.identity(); + } + + @Override + public Object get() + { + throw new IllegalStateException( "Service is passive, either activating and" + + " cannot be used yet or passivating and cannot be used anymore." ); + } + + @Override + public boolean isActive() + { + return false; + } + + @Override + public boolean isAvailable() + { + return false; + } + + @Override + public Iterable<Class<?>> types() + { + return reference.types(); + } + + @Override + public <T> T metaInfo( Class<T> infoType ) + { + return reference.metaInfo( infoType ); + } + + @Override + public void registerActivationEventListener( ActivationEventListener listener ) + { + reference.registerActivationEventListener( listener ); + } + + @Override + public void deregisterActivationEventListener( ActivationEventListener listener ) + { + reference.deregisterActivationEventListener( listener ); + } + + @Override + public int hashCode() + { + return identity().hashCode(); + } + + @Override + public boolean equals( Object obj ) + { + if( obj == null ) + { + return false; + } + if( getClass() != obj.getClass() ) + { + return false; + } + final ServiceReference other = (ServiceReference) obj; + return identity().equals( other.identity() ); + } + + @Override + public String toString() + { + return reference.toString(); + } + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationEventListenerSupport.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationEventListenerSupport.java b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationEventListenerSupport.java new file mode 100644 index 0000000..41c883d --- /dev/null +++ b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationEventListenerSupport.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, Rickard Ãberg. + * Copyright (c) 2012, 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.qi4j.runtime.activation; + +import java.util.ArrayList; +import java.util.List; +import org.qi4j.api.activation.ActivationEvent; +import org.qi4j.api.activation.ActivationEventListener; +import org.qi4j.api.activation.ActivationEventListenerRegistration; + +/** + * Internal helper for managing registrations and firing events + */ +/* package */ class ActivationEventListenerSupport + implements ActivationEventListenerRegistration, ActivationEventListener +{ + protected List<ActivationEventListener> listeners = new ArrayList<>(); + + @Override + public void registerActivationEventListener( ActivationEventListener listener ) + { + List<ActivationEventListener> newListeners = new ArrayList<>(); + newListeners.addAll( listeners ); + newListeners.add( listener ); + listeners = newListeners; + } + + @Override + public void deregisterActivationEventListener( ActivationEventListener listener ) + { + List<ActivationEventListener> newListeners = new ArrayList<>(); + newListeners.addAll( listeners ); + newListeners.remove( listener ); + listeners = newListeners; + } + + /* package */ void fireEvent( ActivationEvent event ) + throws Exception + { + for( ActivationEventListener listener : listeners ) + { + listener.onEvent( event ); + } + } + + @Override + public void onEvent( ActivationEvent event ) + throws Exception + { + fireEvent( event ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorModel.java b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorModel.java new file mode 100644 index 0000000..823aace --- /dev/null +++ b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorModel.java @@ -0,0 +1,108 @@ +/* + * 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.qi4j.runtime.activation; + +import org.qi4j.api.activation.Activator; +import org.qi4j.api.activation.ActivatorDescriptor; +import org.qi4j.api.common.ConstructionException; +import org.qi4j.functional.HierarchicalVisitor; +import org.qi4j.functional.VisitableHierarchy; +import org.qi4j.runtime.composite.ConstructorsModel; +import org.qi4j.runtime.injection.InjectedFieldsModel; +import org.qi4j.runtime.injection.InjectedMethodsModel; +import org.qi4j.runtime.injection.InjectionContext; + +/** + * Model for a single Activator. + * + * @param <ActivateeType> Type of the activation target + */ +public class ActivatorModel<ActivateeType> + implements ActivatorDescriptor, VisitableHierarchy<Object, Object> +{ + private final Class<? extends Activator<ActivateeType>> activatorType; + private final ConstructorsModel constructorsModel; + private final InjectedFieldsModel injectedFieldsModel; + private final InjectedMethodsModel injectedMethodsModel; + + public ActivatorModel( Class<? extends Activator<ActivateeType>> activatorType ) + { + this.activatorType = activatorType; + this.constructorsModel = new ConstructorsModel( activatorType ); + this.injectedFieldsModel = new InjectedFieldsModel( activatorType ); + this.injectedMethodsModel = new InjectedMethodsModel( activatorType ); + } + + @Override + public <ThrowableType extends Throwable> boolean accept( HierarchicalVisitor<? super Object, ? super Object, ThrowableType> visitor ) + throws ThrowableType + { + if( visitor.visitEnter( this ) ) + { + if( constructorsModel.accept( visitor ) ) + { + if( injectedFieldsModel.accept( visitor ) ) + { + injectedMethodsModel.accept( visitor ); + } + } + } + return visitor.visitLeave( this ); + } + + public Activator<ActivateeType> newInstance() + { + try + { + return activatorType.newInstance(); + } + catch( InstantiationException | IllegalAccessException ex ) + { + throw new ConstructionException( "Could not instantiate " + activatorType.getName(), ex ); + } + } + + @SuppressWarnings( "unchecked" ) + public Activator<ActivateeType> newInstance( InjectionContext injectionContext ) + { + try + { + Activator<ActivateeType> instance = (Activator<ActivateeType>) constructorsModel.newInstance( injectionContext ); + injectionContext = new InjectionContext( injectionContext.module(), injectionContext.uses(), instance ); + inject( injectionContext, instance ); + return instance; + } + catch( Exception ex ) + { + throw new ConstructionException( "Could not instantiate " + activatorType.getName(), ex ); + } + } + + public void inject( InjectionContext injectionContext, Activator<ActivateeType> instance ) + { + injectedFieldsModel.inject( injectionContext, instance ); + injectedMethodsModel.inject( injectionContext, instance ); + } + + @Override + public String toString() + { + return activatorType.getName(); + } + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorsInstance.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorsInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorsInstance.java new file mode 100644 index 0000000..2059e1e --- /dev/null +++ b/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorsInstance.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012, Paul Merlin. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.qi4j.runtime.activation; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import org.qi4j.api.activation.Activator; +import org.qi4j.api.activation.PassivationException; +import org.qi4j.functional.Iterables; + +/** + * Instance of a Zest Activators of one Activation target. Contains ordered + * Activators and roll the Activation on the target. + * + * @param <ActivateeType> Type of the activation target + */ +public class ActivatorsInstance<ActivateeType> + implements Activator<ActivateeType> +{ + @SuppressWarnings( {"raw", "unchecked"} ) + public static final ActivatorsInstance EMPTY = new ActivatorsInstance( Collections.emptyList() ); + + private final Iterable<Activator<ActivateeType>> activators; + + public ActivatorsInstance( Iterable<Activator<ActivateeType>> activators ) + { + this.activators = activators; + } + + @Override + public void beforeActivation( ActivateeType activating ) + throws Exception + { + for( Activator<ActivateeType> activator : activators ) + { + activator.beforeActivation( activating ); + } + } + + @Override + public void afterActivation( ActivateeType activated ) + throws Exception + { + for( Activator<ActivateeType> activator : activators ) + { + activator.afterActivation( activated ); + } + } + + @Override + public void beforePassivation( ActivateeType passivating ) + throws Exception + { + Set<Exception> exceptions = new LinkedHashSet<>(); + for( Activator<ActivateeType> activator : Iterables.reverse( activators ) ) + { + try + { + activator.beforePassivation( passivating ); + } + catch( Exception ex ) + { + exceptions.add( ex ); + } + } + if( !exceptions.isEmpty() ) + { + throw new PassivationException( exceptions ); + } + } + + @Override + public void afterPassivation( ActivateeType passivated ) + throws Exception + { + Set<Exception> exceptions = new LinkedHashSet<>(); + for( Activator<ActivateeType> activator : Iterables.reverse( activators ) ) + { + try + { + activator.afterPassivation( passivated ); + } + catch( Exception ex ) + { + exceptions.add( ex ); + } + } + if( !exceptions.isEmpty() ) + { + throw new PassivationException( exceptions ); + } + } + +}
