http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/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 new file mode 100644 index 0000000..b252d33 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/NamedAssociationValueState.java @@ -0,0 +1,84 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..1bda2e9 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ReferenceProperty.java @@ -0,0 +1,53 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..ceeeb10 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderInstance.java @@ -0,0 +1,79 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..f6a40ae --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithPrototype.java @@ -0,0 +1,228 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..57413b5 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueBuilderWithState.java @@ -0,0 +1,91 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..3141ac1 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueInstance.java @@ -0,0 +1,182 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..aa8c9b4 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueModel.java @@ -0,0 +1,112 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..84a2719 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateInstance.java @@ -0,0 +1,233 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..e34398f --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValueStateModel.java @@ -0,0 +1,132 @@ +/* + * 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/061ddaa0/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 new file mode 100644 index 0000000..08f91e1 --- /dev/null +++ b/core/runtime/src/main/java/org/apache/zest/runtime/value/ValuesModel.java @@ -0,0 +1,55 @@ +/* + * 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/061ddaa0/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 deleted file mode 100644 index 232ad6f..0000000 --- a/core/runtime/src/main/java/org/qi4j/runtime/Qi4jRuntimeImpl.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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/061ddaa0/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 deleted file mode 100644 index 86b1d2c..0000000 --- a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationDelegate.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * 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/061ddaa0/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 deleted file mode 100644 index 41c883d..0000000 --- a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivationEventListenerSupport.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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/061ddaa0/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 deleted file mode 100644 index 823aace..0000000 --- a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorModel.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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/061ddaa0/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 deleted file mode 100644 index 2059e1e..0000000 --- a/core/runtime/src/main/java/org/qi4j/runtime/activation/ActivatorsInstance.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 ); - } - } - -}
