diff options
Diffstat (limited to 'sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework')
24 files changed, 1692 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java new file mode 100644 index 0000000000..e2071e27c3 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/DefaultScaAdapter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 11-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +/** + * @author Adrian Colyer + * @since 2.0 + */ +public class DefaultScaAdapter implements ScaAdapter { + + public Object getServiceReference(String referenceName, + Class referenceType, + String moduleName, + String defaultServiceName) { + // TODO + return new Object(); + } + + public Object getPropertyReference(String propertyName, Class propertyType, String moduleName) { + // TODO + return new Object(); + } + + public void publishAsService(Object serviceImplementation, + Class serviceInterface, + String serviceName, + String moduleName) { + // TODO + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java new file mode 100644 index 0000000000..e5aae6f0a2 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapter.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 11-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +/** + * Encapsulates interaction with an SCA runtime + * + * @author Adrian Colyer + * @since 2.0 + */ +public interface ScaAdapter { + + Object getServiceReference( + String referenceName, + Class referenceType, + String moduleName, + String defaultServiceName); + + Object getPropertyReference( + String propertyName, + Class propertyType, + String moduleName); + + void publishAsService( + Object serviceImplementation, + Class serviceInterface, + String serviceName, + String moduleName); + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.java new file mode 100644 index 0000000000..abe975c936 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterAware.java @@ -0,0 +1,31 @@ +/* + * 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.springframework.sca; + +/** + * /** Interface that enables beans to find the ScaAdapter they are defined with. + * <p/> + * Note that in most circumstances there is no need for a bean to implement this interface. + * + * @author Andy Piper + * @since 2.1 + */ +public interface ScaAdapterAware { + void setScaAdapter(ScaAdapter adapter); +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java new file mode 100644 index 0000000000..b07be8f452 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaAdapterPostProcessor.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * @author Andy Piper + * @since 2.1 + */ +public class ScaAdapterPostProcessor implements BeanPostProcessor { + private ScaAdapter scaAdapter; + + public ScaAdapterPostProcessor(ScaAdapter adapter) { + this.scaAdapter = adapter; + } + + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof ScaAdapterAware) { + if (this.scaAdapter == null) { + throw new IllegalStateException("Cannot satisfy ScaAdapterAware for bean '" + + beanName + "' without ScaAdapater"); + } + ((ScaAdapterAware) bean).setScaAdapter(scaAdapter); + } + return bean; + } + + public Object postProcessAfterInitialization(Object object, String string) throws BeansException { + return object; + } + + public ScaAdapter getScaAdapter() { + return scaAdapter; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java new file mode 100644 index 0000000000..e12e763d9f --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaComposite.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.factory.InitializingBean; + +/** + * Bean that represents an Sca composite component. An instance of this bean is created when the <sca:composite + * module-id="xxx"/> element is declared. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaComposite implements InitializingBean { + + private String component; + private ScaAdapter scaAdapter = new DefaultScaAdapter(); + + public String getComponent() { + return this.component; + } + + public void setComponent(String component) { + this.component = component; + } + + public void setScaAdapter(ScaAdapter scaAdapter) { + this.scaAdapter = scaAdapter; + } + + public void setScaAdapterClass(Class adapterClass) { + if (!ScaAdapter.class.isAssignableFrom(adapterClass)) { + throw new IllegalArgumentException( + "Adapter class '" + adapterClass + "' specified for ScaComposite bean " + + "does not implement the ScaApapter interface" + ); + } + try { + this.scaAdapter = (ScaAdapter) adapterClass.newInstance(); + } catch (Exception ex) { + // many exceptions may be thrown by the above, we treat them all + // the same + throw new IllegalStateException("Unable to create instance of ScaAdapter class '" + + adapterClass.getName() + "'", ex); + } + } + + public ScaAdapter getScaAdapter() { + return this.scaAdapter; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.component == null) { + throw new IllegalArgumentException("Required property moduleId was not set"); + } + } + + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java new file mode 100644 index 0000000000..f96af00584 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPostProcessor.java @@ -0,0 +1,147 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca; + +import java.beans.PropertyDescriptor; + +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValues; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.task.TaskExecutor; +import org.springframework.sca.intercept.OneWayAdvisor; +import org.springframework.sca.metadata.DeploymentMetadata; +import org.springframework.sca.metadata.Injection; +import org.springframework.sca.metadata.NoSuchServiceException; +import org.springframework.sca.metadata.ServiceMetadata; + +/** + * Spring bean post processor that looks up service metadata by name for each bean definition and performs SCA + * injection. + * <p/> + * Also performs proxying for OneWay. + * + * @author Rod Johnson + */ +public class ScaPostProcessor implements InstantiationAwareBeanPostProcessor, ApplicationContextAware { + + private DeploymentMetadata deploymentMetadata; + + private ApplicationContext applicationContext; + + private TaskExecutor taskExecutor; + + //private ScaAdapter scaAdapter; + + + /** + * @param taskExecutor The taskExecutor to set. + */ + public void setTaskExecutor(TaskExecutor taskExecutor) { + this.taskExecutor = taskExecutor; + } + + // TODO would process side files when container starts up + + public void setDeploymentMetadata(DeploymentMetadata deploymentMetadata) { + this.deploymentMetadata = deploymentMetadata; + } + + /** + * @param scaAdapter the ScaAdapter for use to export services if necessary + */ + public void setScaAdapter(ScaAdapter scaAdapter) { + //this.scaAdapter = scaAdapter; + } + + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + public Object postProcessBeforeInstantiation(Class beanClass, + String beanName) throws BeansException { + return null; + } + + public boolean postProcessAfterInstantiation(Object bean, String beanName) + throws BeansException { + try { + ServiceMetadata smd = deploymentMetadata.getServiceMetadata(beanName); + doScaInjection(bean, smd); + } catch (NoSuchServiceException ex) { + // + } + return true; + } + + public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, + String beanName) throws BeansException { + return pvs; + } + + public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, Object object, String string) + throws BeansException { + return propertyValues; + } + + protected void doScaInjection(Object bean, ServiceMetadata smd) { + for (Injection injection : smd.getInjections()) { + injection.apply(applicationContext, bean); + } + } + + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + try { + ServiceMetadata smd = deploymentMetadata.getServiceMetadata(beanName); + return createScaProxy(bean, smd); + } catch (NoSuchServiceException ex) { + return bean; + } + + // TODO validate required injections here or earlier + + // TODO publish if necessary, using adapter + } + + protected Object createScaProxy(Object bean, ServiceMetadata smd) { + ProxyFactory pf = new ProxyFactory(bean); + for (Class intf : smd.getServiceInterfaces()) { + pf.addInterface(intf); + } + +//pf.addAdvisor(ExposeInvocationInterceptor.ADVISOR); +//pf.addAdvisor(new ExposeBeanNameAdvisor(smd.getServiceName())); + // TODO enforce call by value + + if (!smd.getOneWayMethods().isEmpty()) { + pf.addAdvisor(new OneWayAdvisor(smd, this.taskExecutor)); + } + + return pf.getProxy(); + } + + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java new file mode 100644 index 0000000000..e89072466a --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaPropertyProxyFactoryBean.java @@ -0,0 +1,123 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; + +/** + * Factory bean that returns a reference to an SCA property obtained by asking the SCA runtime for the property with the + * given name for the given component. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaPropertyProxyFactoryBean implements InitializingBean, FactoryBean { + + /** + * the type of the property + */ + private Class propertyType; + + /** + * the name of the property to look up + */ + private String propertyName; + + /** + * the SCA component we should present ourselves as when asking for a service reference + */ + private ScaComposite scaComposite; + + private Object resolvedPropertyVal; + + public void setPropertyType(Class serviceType) { + this.propertyType = serviceType; + } + + public Class getPropertyType() { + return this.propertyType; + } + + public void setPropertyName(String name) { + this.propertyName = name; + } + + public String getPropertyName() { + return this.propertyName; + } + + public void setScaComposite(ScaComposite scaComposite) { + this.scaComposite = scaComposite; + } + + public ScaComposite getScaComposite() { + return this.scaComposite; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.propertyType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.scaComposite == null) { + throw new IllegalArgumentException("Required property scaComposite was not set"); + } + if (this.propertyName == null) { + throw new IllegalArgumentException("Required property referenceName was not set"); + } + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + public Object getObject() throws Exception { + if (this.resolvedPropertyVal != null) { + return this.resolvedPropertyVal; + } + + String moduleName = this.scaComposite.getComponent(); + // TODO: AMC is there any merit in proxying this with a lazy target source? + Object propertyVal = + this.scaComposite.getScaAdapter().getPropertyReference(this.propertyName, this.propertyType, moduleName); + if (!this.propertyType.isAssignableFrom(propertyVal.getClass())) { + throw new IllegalStateException("Property value '" + propertyVal.toString() + "'" + + " of type '" + propertyVal.getClass().getName() + "' " + + " is not of expected type '" + this.propertyType.getName() + "'"); + } + this.resolvedPropertyVal = propertyVal; + return this.resolvedPropertyVal; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + public Class getObjectType() { + return this.propertyType; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + public boolean isSingleton() { + return true; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java new file mode 100644 index 0000000000..0155dd9646 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceExporter.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.InitializingBean; + +/** + * Exposes a bean instance to SCA to using the given service name. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceExporter implements InitializingBean, BeanFactoryAware, ScaAdapterAware { + + /** + * the name of the service we want to advertise + */ + private String serviceName; + + /** + * the type the service should be published with + */ + private Class serviceType; + + /** + * the bean to be published + */ + private Object target; + + /** + * for resolving the bean name + */ + private BeanFactory beanFactory; + private ScaAdapter scaAdapter; + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getServiceName() { + return this.serviceName; + } + + public void setServiceType(Class serviceType) { + this.serviceType = serviceType; + } + + public Class getServiceType() { + return this.serviceType; + } + + public void setTarget(Object targetBean) { + this.target = targetBean; + } + + public Object getTarget() { + return this.target; + } + + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + public void afterPropertiesSet() throws Exception { + if (this.serviceType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.target == null) { + throw new IllegalArgumentException("Required property target was not set"); + } + if (this.beanFactory == null) { + throw new IllegalArgumentException("Required property beanFactory was not set"); + } + if (this.serviceName == null) { + throw new IllegalArgumentException("Required property serviceName was not set"); + } + publishScaService(); + } + + private void publishScaService() { + scaAdapter.publishAsService(target, serviceType, serviceName, null); + } + + public void setScaAdapter(ScaAdapter adapter) { + this.scaAdapter = adapter; + } +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java new file mode 100644 index 0000000000..01ca5671d4 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/ScaServiceProxyFactoryBean.java @@ -0,0 +1,144 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * Factory bean that returns a reference to an SCA service obtained by asking the SCA runtime for the service with the + * given name for the given component. + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceProxyFactoryBean + implements InitializingBean, FactoryBean, ApplicationContextAware, ScaAdapterAware { + + /** + * the public interface type of the service (may be a class...) + */ + private Class serviceType; + + /** + * the name of the reference to look up + */ + private String referenceName; + + /** + * the default service name to resolve the reference too + */ + private String defaultServiceName; + + private Object resolvedServiceReference; + private ApplicationContext applicationContext; + //private ScaAdapter scaAdapter; + + public void setServiceType(Class serviceType) { + this.serviceType = serviceType; + } + + public Class getServiceType() { + return this.serviceType; + } + + public void setReferenceName(String name) { + this.referenceName = name; + } + + public String getReferenceName() { + return this.referenceName; + } + + public void setDefaultServiceName(String defaultService) { + this.defaultServiceName = defaultService; + } + + public String getDefaultServiceName() { + return this.defaultServiceName; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + public void afterPropertiesSet() throws Exception { + if (this.serviceType == null) { + throw new IllegalArgumentException("Required property serviceType was not set"); + } + if (this.referenceName == null) { + throw new IllegalArgumentException("Required property referenceName was not set"); + } + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + public Object getObject() throws Exception { + if (this.resolvedServiceReference != null) { + return this.resolvedServiceReference; + } + + // TODO: AMC is there any merit in proxying this with a lazy target source? + // should the returned service ref be proxied? Only seems to add value + // if SCA gives us any lifecycle events we can subscribe to and take + // meaningful action on... + // See OsgiServiceProxyFactoryBean for an example of how to do the + // proxying if needed. + Object scaServiceRef; + if (this.applicationContext.getParent() == null) { + return null; + } + + if (!this.applicationContext.getParent().containsBean(this.referenceName)) { + return new Object(); + //scaServiceRef = this.applicationContext.getParent().getBean(this.defaultServiceName); + } else { + scaServiceRef = this.applicationContext.getParent().getBean(this.referenceName); + } + if (!this.serviceType.isAssignableFrom(scaServiceRef.getClass())) { + throw new IllegalStateException("..."); + } + this.resolvedServiceReference = scaServiceRef; + return this.resolvedServiceReference; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + public Class getObjectType() { + return this.serviceType; + } + + /* (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + public boolean isSingleton() { + return false; + } + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + public void setScaAdapter(ScaAdapter adapter) { + // this.scaAdapter = adapter; + } +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java new file mode 100644 index 0000000000..9c6ac633f7 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaCompositeBeanDefinitionParser.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaComposite; + +/** + * Parser for <sca:composite> elements + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaCompositeBeanDefinitionParser implements BeanDefinitionParser { + + static final String SCA_COMPOSITE_BEAN_NAME = "scaComposite"; + private static final String MODULE_ATTRIBUTE_NAME = "component"; + private static final String MODULE_ID = "component"; + private static final String ADAPTER_ATTRIBUTE = "sca-adapter-class"; + private static final String ADAPTER_CLASS_PROPERTY = "scaAdapterClass"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionRegistry registry = parserContext.getRegistry(); + if (registry.containsBeanDefinition(SCA_COMPOSITE_BEAN_NAME)) { + throw new IllegalArgumentException( + "At most one <sca:composite> element can be declared in a bean factory"); + } + BeanDefinition beanDef = createScaCompositeBeanDefinition(element); + registry.registerBeanDefinition(SCA_COMPOSITE_BEAN_NAME, beanDef); + return beanDef; + } + + private BeanDefinition createScaCompositeBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaComposite.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(MODULE_ID, element.getAttribute(MODULE_ATTRIBUTE_NAME)); + if (element.hasAttribute(ADAPTER_ATTRIBUTE)) { + props.addPropertyValue(ADAPTER_CLASS_PROPERTY, element.getAttribute(ADAPTER_ATTRIBUTE)); + } + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java new file mode 100644 index 0000000000..3446aaf462 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaContextBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.sca.ScaAdapter; +import org.springframework.sca.ScaComposite; + +/** + * @author Hal Hildebrand Date: Apr 11, 2006 Time: 4:33:33 PM + */ +public class ScaContextBuilder { + private static final String MODULE_ID = "moduleId"; + + private static final String SCA_ADAPTER = "scaAdapter"; + + private static final String SCA_COMPOSITE_BEAN_NAME = "scaComposite"; + + private String moduleId; + + private ScaAdapter scaAdapter; + + public String getModuleId() { + return this.moduleId; + } + + public void setModuleId(String moduleId) { + this.moduleId = moduleId; + } + + public void setScaAdapter(ScaAdapter scaAdapter) { + this.scaAdapter = scaAdapter; + } + + public ScaAdapter getScaAdapter() { + return this.scaAdapter; + } + + public ApplicationContext construct() { + GenericApplicationContext parent = new GenericApplicationContext(); + BeanDefinition bd = new RootBeanDefinition(ScaComposite.class, true); + + bd.getPropertyValues().addPropertyValue(new PropertyValue(MODULE_ID, moduleId)); + bd.getPropertyValues().addPropertyValue(new PropertyValue(SCA_ADAPTER, scaAdapter)); + parent.registerBeanDefinition(SCA_COMPOSITE_BEAN_NAME, bd); + parent.refresh(); + return parent; + } +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java new file mode 100644 index 0000000000..878267813a --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaNamespaceHandler.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +/** + * Handler for the <sca:> namespace. Handles: <ul> <li><sca:composite module="xxxxx"/></li> + * <li><sca:reference name="xxx" type="yyy" default-service="zzz"/></li> <li><sca:property name="xxx" + * type="yyy"/></li> <li><sca:service name="xxx" type="yyyy" target="zzz"/> </ul> + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaNamespaceHandler extends NamespaceHandlerSupport { + + public ScaNamespaceHandler() { + // FIXME JFM + init(); + } + + public final void init() { + registerBeanDefinitionParser("composite", new ScaCompositeBeanDefinitionParser()); + registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser()); + registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser()); + registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser()); + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java new file mode 100644 index 0000000000..55413b69da --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaPropertyBeanDefinitionParser.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaPropertyProxyFactoryBean; + +/** + * Parser for the <sca:property/> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser { + + private static final String PROPERTY_NAME_ATTRIBUTE = "name"; + private static final String PROPERTY_NAME_PROPERTY = "propertyName"; + private static final String PROPERTY_TYPE_PROPERTY = "propertyType"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String ID_ATTRIBUTE = "id"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // needs service type, reference name, sca component, and optionally default service name + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String beanName = element.getAttribute(ID_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(beanName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaPropertyProxyFactoryBean.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(PROPERTY_NAME_PROPERTY, element.getAttribute(PROPERTY_NAME_ATTRIBUTE)); + props.addPropertyValue(PROPERTY_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java new file mode 100644 index 0000000000..4f4d196571 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaReferenceBeanDefinitionParser.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaServiceProxyFactoryBean; + +/** + * Parser for the <sca:reference> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser { + + private static final String REFERENCE_NAME_ATTRIBUTE = "name"; + private static final String REFERENCE_NAME_PROPERTY = "referenceName"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String SERVICE_TYPE_PROPERTY = "serviceType"; + private static final String DEFAULT_SERVICE_ATTRIBUTE = "default"; + private static final String DEFAULT_SERVICE_PROPERTY = "defaultServiceName"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // needs service type, reference name, sca component, and optionally default service name + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String referenceName = element.getAttribute(REFERENCE_NAME_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(referenceName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaServiceProxyFactoryBean.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(REFERENCE_NAME_PROPERTY, element.getAttribute(REFERENCE_NAME_ATTRIBUTE)); + props.addPropertyValue(SERVICE_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + if (element.hasAttribute(DEFAULT_SERVICE_ATTRIBUTE)) { + props.addPropertyValue(DEFAULT_SERVICE_PROPERTY, element.getAttribute(DEFAULT_SERVICE_ATTRIBUTE)); + } + beanDefinition.setPropertyValues(props); + return beanDefinition; + } +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java new file mode 100644 index 0000000000..5867236faa --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/config/ScaServiceBeanDefinitionParser.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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. + * + * Created on 10-Apr-2006 by Adrian Colyer + */ +package org.springframework.sca.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.sca.ScaServiceExporter; + +/** + * Parser for the <sca:service/> element + * + * @author Adrian Colyer + * @since 2.0 + */ +public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser { + + private static final String SERVICE_NAME_ATTRIBUTE = "name"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String TARGET_ATTRIBUTE = "target"; + private static final String SERVICE_NAME_PROPERTY = "serviceName"; + private static final String SERVICE_TYPE_PROPERTY = "serviceType"; + private static final String TARGET_PROPERTY = "target"; + + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionRegistry registry = parserContext.getRegistry(); + String serviceName = element.getAttribute(SERVICE_NAME_ATTRIBUTE); + BeanDefinition beanDef = createBeanDefinition(element); + registry.registerBeanDefinition(serviceName, beanDef); + return beanDef; + } + + private BeanDefinition createBeanDefinition(Element element) { + RootBeanDefinition beanDefinition = new RootBeanDefinition(); + beanDefinition.setBeanClass(ScaServiceExporter.class); + MutablePropertyValues props = new MutablePropertyValues(); + props.addPropertyValue(SERVICE_TYPE_PROPERTY, element.getAttribute(TYPE_ATTRIBUTE)); + props.addPropertyValue(TARGET_PROPERTY, new RuntimeBeanReference(element.getAttribute(TARGET_ATTRIBUTE))); + props.addPropertyValue(SERVICE_NAME_PROPERTY, element.getAttribute(SERVICE_NAME_ATTRIBUTE)); + beanDefinition.setPropertyValues(props); + return beanDefinition; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java new file mode 100644 index 0000000000..60bf2a344d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/intercept/OneWayAdvisor.java @@ -0,0 +1,82 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.intercept; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.aop.framework.ReflectiveMethodInvocation; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.StaticMethodMatcherPointcut; +import org.springframework.core.task.TaskExecutor; +import org.springframework.sca.metadata.ServiceMetadata; + +/** + * An AOP Alliance MethodInterceptor, rather than AspectJ aspect, as there's no value in typed pointcuts. Oh, if it were + * only annotations... + * + * @author Rod Johnson + */ + +public class OneWayAdvisor extends DefaultPointcutAdvisor { + + private TaskExecutor taskExecutor; + + private final ServiceMetadata smd; + + public OneWayAdvisor(final ServiceMetadata aSmd, TaskExecutor taskExecutor) { + this.smd = aSmd; + setPointcut(new StaticMethodMatcherPointcut() { + public boolean matches(Method method, Class targetClass) { + for (Method m : smd.getOneWayMethods()) { + if (m.getName().equals(method.getName())) { + return true; + } + } + return false; + } + }); + setAdvice(new OneWayInterceptor()); + this.taskExecutor = taskExecutor; + } + + + private class OneWayInterceptor implements MethodInterceptor { + public Object invoke(MethodInvocation mi) throws Throwable { + try { + // TODO this is not right + ReflectiveMethodInvocation rmi = (ReflectiveMethodInvocation) mi; + final MethodInvocation clone = rmi.invocableClone(); + System.out.println("EXECUTE DEFERRED"); + taskExecutor.execute(new Runnable() { + public void run() { + try { + clone.proceed(); + } catch (Throwable ex) { + // TODO + throw new UnsupportedOperationException(); + } + } + }); + } catch (Throwable t) { + t.printStackTrace(); + } + return null; + } + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java new file mode 100644 index 0000000000..9a04831ab8 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/AnnotationServiceMetadata.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.List; + +import org.osoa.sca.annotations.ComponentName; +import org.osoa.sca.annotations.OneWay; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Service; + +import org.springframework.util.ReflectionUtils; + +/** + * TODO not the way to get this + * + * @author Rod Johnson + */ +public class AnnotationServiceMetadata implements ServiceMetadata { + + private final String name; + + private final Class<?> serviceClass; + + public AnnotationServiceMetadata(String name, Class<?> serviceClass) throws NoSuchServiceException { + if (!serviceClass.isAnnotationPresent(Service.class)) { + throw new NoSuchServiceException(); + } + this.name = name; + this.serviceClass = serviceClass; + } + + public String getServiceName() { + return name; + } + + public Class<?>[] getServiceInterfaces() { + return serviceClass.getAnnotation(Service.class).interfaces(); + } + + public List<Method> getOneWayMethods() { + List<Method> oneWayMethods = new LinkedList<Method>(); + for (Method m : serviceClass.getMethods()) { + if (m.isAnnotationPresent(OneWay.class)) { + oneWayMethods.add(m); + } + } + + // TODO fields + + return oneWayMethods; + } + + public List<Injection> getInjections() { + final List<Injection> injections = new LinkedList<Injection>(); + for (Method m : serviceClass.getMethods()) { + if (m.isAnnotationPresent(Property.class)) { + injections.add(new MethodInjection(m)); + } + } + + // TODO fields propertly + + ReflectionUtils.doWithFields(serviceClass, new ReflectionUtils.FieldCallback() { + public void doWith(Field f) throws IllegalArgumentException { + if (f.isAnnotationPresent(ComponentName.class)) { + Injection componentNameInjection = new FieldInjection(f); + componentNameInjection.setLiteralValue(name); + injections.add(componentNameInjection); + } + } + }); + + return injections; + } + + // TODO reference + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java new file mode 100644 index 0000000000..b819ad8f8d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/BeanFactoryDeploymentMetadata.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; + +/** + * DeploymentMetadata implementation backed by Spring BeanFactory metadata + * + * @author Rod Johnson + */ +public class BeanFactoryDeploymentMetadata implements BeanFactoryAware, DeploymentMetadata { + + private BeanFactory beanFactory; + + private Map<String, ServiceMetadata> serviceNameToMetadataMap = new HashMap<String, ServiceMetadata>(); + + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + + /* (non-Javadoc) + * @see org.springframework.sca.metadata.DeploymentMetadata#getServiceMetadata(java.lang.String) + */ + public synchronized ServiceMetadata getServiceMetadata(String serviceName) throws NoSuchServiceException { + ServiceMetadata sm = serviceNameToMetadataMap.get(serviceName); + if (sm == null) { + Class clazz = beanFactory.getType(serviceName); + sm = new AnnotationServiceMetadata(serviceName, clazz); + serviceNameToMetadataMap.put(serviceName, sm); + } + return sm; + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java new file mode 100644 index 0000000000..950e5e3786 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/DeploymentMetadata.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +/** + * Source of ServiceMetadata by name + * + * @author Rod Johnson + */ +public interface DeploymentMetadata { + + ServiceMetadata getServiceMetadata(String serviceName) throws NoSuchServiceException; + +}
\ No newline at end of file diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java new file mode 100644 index 0000000000..3d9f1b6e79 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/FieldInjection.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import java.lang.reflect.Field; + +import org.osoa.sca.annotations.Reference; + +/** + * @author Rod Johnson + */ +public class FieldInjection extends Injection { + + private final Field field; + + public FieldInjection(Field field, String lookupName) { + super(lookupName); + this.field = field; + } + + public FieldInjection(Field field) { + Reference annotation = field.getAnnotation(Reference.class); + + this.field = field; + + if (annotation == null) { + //throw new IllegalArgumentException("Field " + field + " not annotated"); + return; + } + + if ("".equals(annotation.name())) { + setLookupName(field.getName()); + } else { + setLookupName(annotation.name()); + } + } + + @Override + protected void injectValue(Object target, Object value) { + try { + if (!field.isAccessible()) { + field.setAccessible(true); + } + field.set(target, value); + } catch (IllegalArgumentException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (IllegalAccessException ex) { + // TODO + ex.printStackTrace(); + throw new UnsupportedOperationException(); + } + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java new file mode 100644 index 0000000000..2e81516d56 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/Injection.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import org.springframework.beans.factory.BeanFactory; + +/** + * @author Rod Johnson + */ +public abstract class Injection { + + private String lookupName; + + /** + * Is it a literal value? + */ + private boolean literal; + + /** + * Literal value if it's a literal + */ + private Object literalValue; + + protected Injection() { + + } + + protected Injection(String lookupName) { + this.lookupName = lookupName; + } + + public Object getLiteralValue() { + return literalValue; + } + + public void setLiteralValue(Object literalValue) { + this.literal = true; + this.literalValue = literalValue; + } + + public boolean isLiteral() { + return literal; + } + + protected void setLookupName(String lookupName) { + this.lookupName = lookupName; + } + + public String getLookupName() { + return lookupName; + } + + public void apply(BeanFactory owner, Object target) { + Object value = literalValue; + if (!isLiteral()) { + value = owner.getBean(lookupName); + } + injectValue(target, value); + } + + protected abstract void injectValue(Object target, Object value); + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java new file mode 100644 index 0000000000..df01d1428d --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/MethodInjection.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.osoa.sca.annotations.Property; + +/** + * @author Rod Johnson + */ +public class MethodInjection extends Injection { + + private final Method method; + + public MethodInjection(Method method, String lookupName) { + super(lookupName); + this.method = method; + } + + public MethodInjection(Method method) { + // TODO reference also + Property annotation = method.getAnnotation(Property.class); + if (annotation == null) { + throw new IllegalArgumentException("Method " + method + " not annotated"); + } + this.method = method; + if ("".equals(annotation.name())) { + setLookupName(method.getName()); + } else { + setLookupName(annotation.name()); + } + } + + @Override + protected void injectValue(Object target, Object value) { + try { + method.invoke(target, value); + } catch (IllegalArgumentException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (IllegalAccessException ex) { + // TODO + throw new UnsupportedOperationException(); + } catch (InvocationTargetException ex) { + // TODO + throw new UnsupportedOperationException(); + } + } + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java new file mode 100644 index 0000000000..b7ffdfeee6 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/NoSuchServiceException.java @@ -0,0 +1,24 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +/** + * @author Rod Johnson + */ +public class NoSuchServiceException extends Exception { + +} diff --git a/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java new file mode 100644 index 0000000000..5d23c499e4 --- /dev/null +++ b/sca-java-1.x/branches/sca-java-M2/sca/services/containers/container.spring/src/main/java/org/springframework/sca/metadata/ServiceMetadata.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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.springframework.sca.metadata; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * Metadata for an SCA component. + * + * @author Rod Johnson + */ +public interface ServiceMetadata { + + /** + * Return the service name + * + * @return the service name of the component + */ + String getServiceName(); + + /** + * Return the service interfaces implemented by the component + * + * @return interfaces implemented by the component + */ + Class<?>[] getServiceInterfaces(); + + /** + * Return a list of OneWay methods + * + * @return never returns null + */ + List<Method> getOneWayMethods(); + + /** + * Return a list of SCA injections + * @return a list of SCA injections. Never returns null. + */ + List<Injection> getInjections(); + +} |