| /* |
| * 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.apache.zest.runtime; |
| |
| import java.lang.reflect.InvocationHandler; |
| import java.util.Arrays; |
| import java.util.Map; |
| import org.apache.zest.api.Qi4j; |
| import org.apache.zest.api.association.AbstractAssociation; |
| import org.apache.zest.api.association.Association; |
| import org.apache.zest.api.association.AssociationDescriptor; |
| import org.apache.zest.api.association.AssociationStateHolder; |
| import org.apache.zest.api.association.AssociationWrapper; |
| import org.apache.zest.api.association.ManyAssociation; |
| import org.apache.zest.api.association.ManyAssociationWrapper; |
| import org.apache.zest.api.association.NamedAssociation; |
| import org.apache.zest.api.association.NamedAssociationWrapper; |
| import org.apache.zest.api.composite.Composite; |
| import org.apache.zest.api.composite.CompositeDescriptor; |
| import org.apache.zest.api.composite.CompositeInstance; |
| import org.apache.zest.api.composite.ModelDescriptor; |
| import org.apache.zest.api.composite.TransientComposite; |
| import org.apache.zest.api.composite.TransientDescriptor; |
| import org.apache.zest.api.entity.EntityComposite; |
| import org.apache.zest.api.entity.EntityDescriptor; |
| import org.apache.zest.api.entity.EntityReference; |
| import org.apache.zest.api.property.Property; |
| import org.apache.zest.api.property.PropertyDescriptor; |
| import org.apache.zest.api.property.PropertyWrapper; |
| import org.apache.zest.api.property.StateHolder; |
| import org.apache.zest.api.service.ServiceComposite; |
| import org.apache.zest.api.service.ServiceDescriptor; |
| import org.apache.zest.api.service.ServiceReference; |
| import org.apache.zest.api.structure.Module; |
| import org.apache.zest.api.unitofwork.UnitOfWork; |
| import org.apache.zest.api.value.ValueComposite; |
| import org.apache.zest.api.value.ValueDescriptor; |
| import org.apache.zest.bootstrap.ApplicationAssemblyFactory; |
| import org.apache.zest.bootstrap.ApplicationModelFactory; |
| import org.apache.zest.bootstrap.Qi4jRuntime; |
| import org.apache.zest.runtime.association.AbstractAssociationInstance; |
| import org.apache.zest.runtime.association.AssociationInstance; |
| import org.apache.zest.runtime.association.ManyAssociationInstance; |
| import org.apache.zest.runtime.association.NamedAssociationInstance; |
| import org.apache.zest.runtime.bootstrap.ApplicationAssemblyFactoryImpl; |
| import org.apache.zest.runtime.bootstrap.ApplicationModelFactoryImpl; |
| import org.apache.zest.runtime.composite.ProxyReferenceInvocationHandler; |
| import org.apache.zest.runtime.composite.TransientInstance; |
| import org.apache.zest.runtime.entity.EntityInstance; |
| import org.apache.zest.runtime.property.PropertyInstance; |
| import org.apache.zest.runtime.service.ImportedServiceReferenceInstance; |
| import org.apache.zest.runtime.service.ServiceInstance; |
| import org.apache.zest.runtime.service.ServiceReferenceInstance; |
| import org.apache.zest.runtime.structure.ModuleUnitOfWork; |
| import org.apache.zest.runtime.value.ValueInstance; |
| import org.apache.zest.spi.Qi4jSPI; |
| import org.apache.zest.spi.entity.EntityState; |
| |
| import static java.lang.reflect.Proxy.getInvocationHandler; |
| import static org.apache.zest.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(); |
| } |
| } |