| /* |
| * 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.polygene.runtime; |
| |
| import java.lang.reflect.InvocationHandler; |
| import java.lang.reflect.Proxy; |
| import java.util.Arrays; |
| import java.util.Map; |
| import java.util.stream.Stream; |
| import org.apache.polygene.api.PolygeneAPI; |
| import org.apache.polygene.api.association.AbstractAssociation; |
| import org.apache.polygene.api.association.Association; |
| import org.apache.polygene.api.association.AssociationDescriptor; |
| import org.apache.polygene.api.association.AssociationStateHolder; |
| import org.apache.polygene.api.association.AssociationWrapper; |
| import org.apache.polygene.api.association.ManyAssociation; |
| import org.apache.polygene.api.association.ManyAssociationWrapper; |
| import org.apache.polygene.api.association.NamedAssociation; |
| import org.apache.polygene.api.association.NamedAssociationWrapper; |
| import org.apache.polygene.api.composite.Composite; |
| import org.apache.polygene.api.composite.CompositeDescriptor; |
| import org.apache.polygene.api.composite.CompositeInstance; |
| import org.apache.polygene.api.composite.ModelDescriptor; |
| import org.apache.polygene.api.composite.TransientComposite; |
| import org.apache.polygene.api.composite.TransientDescriptor; |
| import org.apache.polygene.api.entity.EntityComposite; |
| import org.apache.polygene.api.entity.EntityDescriptor; |
| import org.apache.polygene.api.entity.EntityReference; |
| import org.apache.polygene.api.property.Property; |
| import org.apache.polygene.api.property.PropertyDescriptor; |
| import org.apache.polygene.api.property.PropertyWrapper; |
| import org.apache.polygene.api.property.StateHolder; |
| import org.apache.polygene.api.service.ServiceComposite; |
| import org.apache.polygene.api.service.ServiceDescriptor; |
| import org.apache.polygene.api.service.ServiceReference; |
| import org.apache.polygene.api.structure.ModuleDescriptor; |
| import org.apache.polygene.api.unitofwork.UnitOfWork; |
| import org.apache.polygene.api.value.ValueComposite; |
| import org.apache.polygene.api.value.ValueDescriptor; |
| import org.apache.polygene.bootstrap.ApplicationAssemblyFactory; |
| import org.apache.polygene.bootstrap.ApplicationModelFactory; |
| import org.apache.polygene.bootstrap.PolygeneRuntime; |
| import org.apache.polygene.runtime.association.AbstractAssociationInstance; |
| import org.apache.polygene.runtime.bootstrap.ApplicationAssemblyFactoryImpl; |
| import org.apache.polygene.runtime.bootstrap.ApplicationModelFactoryImpl; |
| import org.apache.polygene.runtime.composite.ProxyReferenceInvocationHandler; |
| import org.apache.polygene.runtime.composite.TransientInstance; |
| import org.apache.polygene.runtime.entity.EntityInstance; |
| import org.apache.polygene.runtime.property.PropertyInstance; |
| import org.apache.polygene.runtime.service.ImportedServiceReferenceInstance; |
| import org.apache.polygene.runtime.service.ServiceReferenceInstance; |
| import org.apache.polygene.runtime.unitofwork.ModuleUnitOfWork; |
| import org.apache.polygene.runtime.value.ValueInstance; |
| import org.apache.polygene.spi.PolygeneSPI; |
| import org.apache.polygene.spi.entity.EntityState; |
| |
| import static java.lang.reflect.Proxy.getInvocationHandler; |
| import static org.apache.polygene.api.composite.CompositeInstance.compositeInstanceOf; |
| |
| /** |
| * Incarnation of Polygene. |
| */ |
| public final class PolygeneRuntimeImpl |
| implements PolygeneSPI, PolygeneRuntime |
| { |
| private final ApplicationAssemblyFactory applicationAssemblyFactory; |
| private final ApplicationModelFactory applicationModelFactory; |
| |
| public PolygeneRuntimeImpl() |
| { |
| applicationAssemblyFactory = new ApplicationAssemblyFactoryImpl(); |
| applicationModelFactory = new ApplicationModelFactoryImpl(); |
| } |
| |
| @Override |
| public ApplicationAssemblyFactory applicationAssemblyFactory() |
| { |
| return applicationAssemblyFactory; |
| } |
| |
| @Override |
| public ApplicationModelFactory applicationModelFactory() |
| { |
| return applicationModelFactory; |
| } |
| |
| @Override |
| public PolygeneAPI api() |
| { |
| return this; |
| } |
| |
| @Override |
| public PolygeneSPI 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 ModuleDescriptor moduleOf( Object compositeOrServiceReferenceOrUow ) |
| { |
| if( compositeOrServiceReferenceOrUow instanceof Composite ) |
| { |
| return compositeInstanceOf( (Composite) compositeOrServiceReferenceOrUow ).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, |
| EntityComposite.class, |
| ServiceComposite.class, ServiceReference.class, |
| UnitOfWork.class ) ); |
| } |
| |
| @Override |
| public ModelDescriptor modelDescriptorFor( Object compositeOrServiceReference ) |
| { |
| if( compositeOrServiceReference instanceof Composite ) |
| { |
| return compositeInstanceOf( (Composite) compositeOrServiceReference ).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, EntityComposite.class, |
| ServiceComposite.class, ServiceReference.class, |
| ImportedServiceReferenceInstance.class ) ); |
| } |
| |
| @Override |
| public CompositeDescriptor compositeDescriptorFor( Object compositeOrServiceReference ) |
| { |
| return (CompositeDescriptor) modelDescriptorFor( compositeOrServiceReference ); |
| } |
| |
| // Descriptors |
| |
| @Override |
| public TransientDescriptor transientDescriptorFor( Object transsient ) |
| { |
| if( transsient instanceof TransientComposite ) |
| { |
| TransientInstance 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 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) compositeInstanceOf( composite ) ).state(); |
| } |
| |
| @Override |
| public ValueDescriptor valueDescriptorFor( Object value ) |
| { |
| if( value instanceof ValueComposite ) |
| { |
| ValueInstance valueInstance = (ValueInstance) compositeInstanceOf( (Composite) value ); |
| return valueInstance.descriptor(); |
| } |
| throw new IllegalArgumentException( "Wrong type. {" + value + "} must be subtype of " + ValueComposite.class ); |
| } |
| |
| @Override |
| public AssociationStateHolder stateOf( ValueComposite composite ) |
| { |
| return ( (ValueInstance) compositeInstanceOf( 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) compositeInstanceOf( 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(); |
| } |
| |
| @Override |
| public boolean isComposite( Object object ) |
| { |
| return isCompositeType( object ); |
| } |
| |
| public static boolean isCompositeType( Object object ) |
| { |
| return Proxy.isProxyClass( object.getClass() ) |
| && Proxy.getInvocationHandler( object ) instanceof CompositeInstance; |
| } |
| |
| // SPI |
| @Override |
| public EntityState entityStateOf( EntityComposite composite ) |
| { |
| return ( (EntityInstance) compositeInstanceOf( composite ) ).entityState(); |
| } |
| |
| @Override |
| public EntityReference entityReferenceOf( Association<?> assoc ) |
| { |
| return assoc.reference(); |
| } |
| |
| @Override |
| public Stream<EntityReference> entityReferencesOf( ManyAssociation<?> assoc ) |
| { |
| return assoc.references(); |
| } |
| |
| @Override |
| public Stream<Map.Entry<String, EntityReference>> entityReferencesOf( NamedAssociation<?> assoc ) |
| { |
| return assoc.references(); |
| } |
| } |