diff options
Diffstat (limited to 'sca-java-2.x/trunk/modules/implementation-spring-sca')
24 files changed, 1870 insertions, 0 deletions
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/LICENSE b/sca-java-2.x/trunk/modules/implementation-spring-sca/LICENSE new file mode 100644 index 0000000000..6e529a25c4 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/LICENSE @@ -0,0 +1,205 @@ +
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/implementation-spring-sca/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..543353e3b3 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/META-INF/MANIFEST.MF @@ -0,0 +1,24 @@ +Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Spring Implementation Runtime Model
+Bundle-SymbolicName: org.apache.tuscany.sca.implementation.spring.runtime
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 +Import-Package: org.oasisopen.sca;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0",
+ org.springframework.beans;version="2.5.5",
+ org.springframework.beans.factory;version="2.5.5",
+ org.springframework.beans.factory.annotation;version="2.5.5",
+ org.springframework.beans.factory.config;version="2.5.5",
+ org.springframework.beans.factory.support;version="2.5.5",
+ org.springframework.beans.factory.xml;version="2.5.5",
+ org.springframework.context;version="2.5.5",
+ org.springframework.context.support;version="2.5.5",
+ org.springframework.core.io;version="2.5.5",
+ org.springframework.util;version="2.5.5"
+
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/NOTICE b/sca-java-2.x/trunk/modules/implementation-spring-sca/NOTICE new file mode 100644 index 0000000000..1325efd8bf --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/NOTICE @@ -0,0 +1,6 @@ +${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/README b/sca-java-2.x/trunk/modules/implementation-spring-sca/README new file mode 100644 index 0000000000..e1b1f98fe0 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/README @@ -0,0 +1,9 @@ +Note that the implementation spring modules have a different structure from other extensions.
+
+The aim is to have the Tuscany runtime embedded in a container with the Tuscany classes hidden
+from user applications and the Spring jar's packaged with the application. That means that the
+Tuscany code has no visibilty of the Spring classes and visa-versa. To implement that the
+implementation-spring module has no dependencies on Spring and the implementation-spring-runtime
+module has no dependencies on Tuscany (other than the sca-api), and reflection is used to call
+methods between the modules.
+
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/pom.xml b/sca-java-2.x/trunk/modules/implementation-spring-sca/pom.xml new file mode 100644 index 0000000000..abb60e0c68 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/pom.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-modules</artifactId> + <version>2.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-implementation-spring-sca</artifactId> + <name>Apache Tuscany SCA Spring Implementation Runtime Model</name> + + <dependencies> + + <!-- **************************************** --> + <!-- * * --> + <!-- * DONT ADD ANY TUSCANY DEPENDENCIES!!! * --> + <!-- * * --> + <!-- * See the README for details why not * --> + <!-- * * --> + <!-- * * --> + <!-- **************************************** --> + + <!-- SCA API dependency --> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-sca-api</artifactId> + <version>2.0-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- Spring dependencies... --> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>2.5.5</version> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>2.5.5</version> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>2.5.5</version> + </dependency> + + </dependencies> +</project> diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java new file mode 100644 index 0000000000..75e00007f6 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/SCANamespaceHandlerResolver.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.implementation.spring.namespace; + +import org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver; +import org.springframework.beans.factory.xml.NamespaceHandler; + +/** + * Overrides the default Spring namespace resolver to automatically register + * {@link ScaNamespaceHandler} instead of requiring a value to be supplied in a + * Spring configuration + * + * @version $Rev$ $Date$ + */ +public class SCANamespaceHandlerResolver extends DefaultNamespaceHandlerResolver { + private static final String SCA_NAMESPACE = "http://www.springframework.org/schema/sca"; + + private ScaNamespaceHandler handler; + + public SCANamespaceHandlerResolver(ClassLoader classLoader) { + super(classLoader); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + public SCANamespaceHandlerResolver(String handlerMappingsLocation, ClassLoader classLoader) { + super(classLoader, handlerMappingsLocation); + handler = new ScaNamespaceHandler(/*componentType*/); + } + + @Override + public NamespaceHandler resolve(String namespaceUri) { + if (SCA_NAMESPACE.equals(namespaceUri)) { + return handler; + } + return super.resolve(namespaceUri); + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java new file mode 100644 index 0000000000..f136e45b87 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaNamespaceHandler.java @@ -0,0 +1,38 @@ +/* + * 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.apache.tuscany.sca.implementation.spring.namespace; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +/** + * Handler for the <sca:> namespace in an application context + * + * @version $Rev$ $Date$ + */ +public class ScaNamespaceHandler extends NamespaceHandlerSupport { + + public ScaNamespaceHandler() { + init(); + } + + public final void init() { + registerBeanDefinitionParser("reference", new ScaReferenceBeanDefinitionParser()); + registerBeanDefinitionParser("service", new ScaServiceBeanDefinitionParser()); + registerBeanDefinitionParser("property", new ScaPropertyBeanDefinitionParser()); + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java new file mode 100644 index 0000000000..5b1064d8d8 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaPropertyBeanDefinitionParser.java @@ -0,0 +1,35 @@ +/* + * 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.apache.tuscany.sca.implementation.spring.namespace; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:reference> element + * @version $Rev$ $Date$ + */ +public class ScaPropertyBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, this is handled by Tuscany + return null; + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java new file mode 100644 index 0000000000..fac02760c9 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaReferenceBeanDefinitionParser.java @@ -0,0 +1,36 @@ +/* + * 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.apache.tuscany.sca.implementation.spring.namespace; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:reference> element + * + * @version $Rev$ $Date$ + */ +public class ScaReferenceBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, this is handled by Tuscany + return null; + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java new file mode 100644 index 0000000000..3020dca8bc --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/namespace/ScaServiceBeanDefinitionParser.java @@ -0,0 +1,36 @@ +/* + * 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.apache.tuscany.sca.implementation.spring.namespace; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parser for the <sca:service/> element + * + * @version $Rev$ $Date$ + */ +public class ScaServiceBeanDefinitionParser implements BeanDefinitionParser { + + public BeanDefinition parse(Element element, ParserContext parserContext) { + // do nothing, handled by Tuscany + return null; + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java new file mode 100644 index 0000000000..7613f8166d --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentNameAnnotationProcessor.java @@ -0,0 +1,150 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; +import java.lang.ref.Reference; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.oasisopen.sca.annotation.ComponentName; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +public class ComponentNameAnnotationProcessor implements BeanPostProcessor { + + private Class<? extends Annotation> componentNameAnnotationType = ComponentName.class; + + private String componentName; + + public ComponentNameAnnotationProcessor (String componentName) { + this.componentName = componentName; + } + + /** + * Gets componentName annotation type. + */ + protected Class<? extends Annotation> getComponentNameAnnotationType() { + return this.componentNameAnnotationType; + } + + /** + * Sets componentName annotation type. + */ + public void setComponentNameAnnotationType(Class<? extends Annotation> componentNameAnnotationType) { + Assert.notNull(componentNameAnnotationType, "'componentNameAnnotationType' type must not be null."); + this.componentNameAnnotationType = componentNameAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p> + */ + protected void processAnnotation(final Object bean) { + + final Class<?> clazz = bean.getClass(); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + Annotation annotation = field.getAnnotation(getComponentNameAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + if (field.getType().getName().equals("java.lang.String")) { + Object nameObj = componentName; + if (nameObj != null) + ReflectionUtils.setField(field, bean, nameObj); + } else { + throw new IllegalStateException("ComponentName annotation is supported only on java.lang.String field type."); + } + } + } + }); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + Annotation annotation = method.getAnnotation(getComponentNameAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("ComponentName annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("ComponentName annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + + if (pd.getPropertyType().getName().equals("java.lang.String")) { + Object nameObj = componentName; + if (nameObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { nameObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e); + } + } + } else { + throw new IllegalStateException("ComponentName annotation is supported only on java.lang.String field type."); + } + } + } + }); + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentStub.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentStub.java new file mode 100644 index 0000000000..c72ccd6636 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ComponentStub.java @@ -0,0 +1,54 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Method; + +/** + * This is the Spring runtime side stub for the corresponding Tuscany tie class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the ComponentTie class + * in the implementation-spring module for what the tie does. + */ +public class ComponentStub { + + private Object tie; + private Method getService; + + public ComponentStub(Object tie) { + this.tie = tie; + Class<?> tieClass = tie.getClass(); + try { + getService = tieClass.getMethod("getService", new Class<?>[]{Class.class, String.class}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getService(Class<?> type, String name) { + try { + + return getService.invoke(tie, type, name); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java new file mode 100644 index 0000000000..7eb63678f6 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ConstructorAnnotationProcessor.java @@ -0,0 +1,115 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; +import org.springframework.util.Assert; + +public class ConstructorAnnotationProcessor extends InstantiationAwareBeanPostProcessorAdapter { + + private Class<? extends Annotation> constructorAnnotationType + = org.oasisopen.sca.annotation.Constructor.class; + + private Class<? extends Annotation> autowiredAnnotationType = Autowired.class; + + public ConstructorAnnotationProcessor () { + // Default constructor. + } + + /** + * Set the 'autowired' annotation type, to be used on constructors, fields, + * setter methods and arbitrary config methods. + */ + public void setAutowiredAnnotationType(Class<? extends Annotation> autowiredAnnotationType) { + Assert.notNull(autowiredAnnotationType, "'autowiredAnnotationType' must not be null"); + this.autowiredAnnotationType = autowiredAnnotationType; + } + + /** + * Return the 'autowired' annotation type. + */ + protected Class<? extends Annotation> getAutowiredAnnotationType() { + return this.autowiredAnnotationType; + } + + /** + * Return the 'constructor' annotation type. + */ + protected Class<? extends Annotation> getConstructorAnnotationType() { + return this.constructorAnnotationType; + } + + /** + * Sets the 'constructor' annotation type. + */ + public void setConstructorAnnotationType(Class<? extends Annotation> constructorAnnotationType) { + Assert.notNull(constructorAnnotationType, "'constructorAnnotationType' type must not be null."); + this.constructorAnnotationType = constructorAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + public Constructor[] determineCandidateConstructors(Class beanClass, String beanName) throws BeansException { + /*Constructor[] declaredConstructors = beanClass.getDeclaredConstructors(); + Method[] declaredMethods = beanClass.getDeclaredMethods(); + List candidates = new ArrayList(declaredConstructors.length); + + for (int i = 0; i < declaredMethods.length; i++) { + Method method = declaredMethods[i]; + Annotation annotation = method.getAnnotation(getConstructorAnnotationType()); + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Constructor annotation is not supported on static methods"); + } + + if (candidates.size() == 1) { + throw new IllegalStateException("Only one method is allowed to have constructor annotation in a bean: " + method); + } + + candidates.add(method); + } + } + + return (Constructor[]) candidates.toArray(new Constructor[candidates.size()]);*/ + return null; + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java new file mode 100644 index 0000000000..477582b1d3 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/InitDestroyAnnotationProcessor.java @@ -0,0 +1,75 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.annotation.Annotation; + +import org.oasisopen.sca.annotation.Destroy; +import org.oasisopen.sca.annotation.Init; +import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor; + +public class InitDestroyAnnotationProcessor extends InitDestroyAnnotationBeanPostProcessor { + + private static final long serialVersionUID = 0; + + private Class<? extends Annotation> initAnnotationType = Init.class; + private Class<? extends Annotation> destroyAnnotationType = Destroy.class; + + /** + * Gets init annotation type. + */ + protected Class<? extends Annotation> getInitAnnotationType() { + return this.initAnnotationType; + } + + /** + * Sets init annotation type. + */ + /* + * public void setInitAnnotationType(Class<? extends Annotation> + * initAnnotationType) { Assert.notNull(initAnnotationType, + * "Init annotation type must not be null."); this.initAnnotationType = + * initAnnotationType; } + */ + + /** + * Gets destroy annotation type. + */ + protected Class<? extends Annotation> getDestroyAnnotationType() { + return this.destroyAnnotationType; + } + + /** + * Sets destroy annotation type. + */ + /* + * public void setDestroyAnnotationType(Class<? extends Annotation> + * destroyAnnotationType) { Assert.notNull(destroyAnnotationType, + * "Destroy annotation type must not be null."); this.destroyAnnotationType + * = destroyAnnotationType; } + */ + + public InitDestroyAnnotationProcessor() { + // Set the @Init annotation type + setInitAnnotationType(initAnnotationType); + + // Set the @Destroy annotation type + setDestroyAnnotationType(destroyAnnotationType); + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java new file mode 100644 index 0000000000..f800654c34 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyAnnotationProcessor.java @@ -0,0 +1,161 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.oasisopen.sca.annotation.Property; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +public class PropertyAnnotationProcessor implements BeanPostProcessor { + + private Class<? extends Annotation> propertyAnnotationType = Property.class; + + private PropertyValueStub propertyValue; + + public PropertyAnnotationProcessor (PropertyValueStub propertyValue) { + this.propertyValue = propertyValue; + } + + /** + * Gets property annotation type. + */ + protected Class<? extends Annotation> getPropertyAnnotationType() { + return this.propertyAnnotationType; + } + + /** + * Sets property annotation type. + */ + public void setPropertyAnnotationType(Class<? extends Annotation> propertyAnnotationType) { + Assert.notNull(propertyAnnotationType, "'propertyAnnotationType' type must not be null."); + this.propertyAnnotationType = propertyAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + * <p>Processes a beans fields for injection if it has a {@link Property} annotation.</p> + */ + protected void processAnnotation(final Object bean) { + + final Class<?> clazz = bean.getClass(); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + + Property annotation = (Property) method.getAnnotation(getPropertyAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("Property annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + if (pd != null) { + String propName = annotation.name(); + if ("".equals(propName)) { + injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), pd.getName())); + } else { + injectProperty(bean, pd, propertyValue.getPropertyObj(pd.getPropertyType(), propName)); + } + } + } + } + }); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + + Property annotation = (Property) field.getAnnotation(getPropertyAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("Property annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + Object propertyObj = null; + String propName = annotation.name(); + if ("".equals(propName)) { + propertyObj = propertyValue.getPropertyObj(field.getType(), field.getName()); + } else { + propertyObj = propertyValue.getPropertyObj(field.getType(), propName); + } + + if (propertyObj != null) + ReflectionUtils.setField(field, bean, propertyObj); + } + } + }); + } + + public void injectProperty(Object bean, PropertyDescriptor pd, Object propertyObj) { + + if (propertyObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { propertyObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting property: " + e.getMessage(), e); + } + } + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyValueStub.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyValueStub.java new file mode 100644 index 0000000000..ea8f560ae1 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/PropertyValueStub.java @@ -0,0 +1,55 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.lang.reflect.Method; + +/** + * This is the Spring runtime side stub for the corresponding Tuscany tie class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the PropertyValueTie class + * in the implementation-spring module for what the tie does. + */ +public class PropertyValueStub { + + private Object tie; + private Method getPropertyObj; + + public PropertyValueStub(Object tie) { + this.tie = tie; + Class<?> tieClass = tie.getClass(); + try { + getPropertyObj = tieClass.getMethod("getPropertyObj", new Class<?>[]{Class.class, String.class}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getPropertyObj(Class<?> propertyType, String name) { + try { + + return getPropertyObj.invoke(tie, propertyType, name); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java new file mode 100644 index 0000000000..dd43d63d97 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/processor/ReferenceAnnotationProcessor.java @@ -0,0 +1,164 @@ +/* + * 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.tuscany.sca.implementation.spring.processor; + +import java.beans.PropertyDescriptor; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.oasisopen.sca.annotation.Reference; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +public class ReferenceAnnotationProcessor implements BeanPostProcessor { + + private Class<? extends Annotation> referenceAnnotationType = Reference.class; + private ComponentStub component; + + public ReferenceAnnotationProcessor (ComponentStub component) { + this.component = component; + } + + /** + * Gets referece annotation type. + */ + protected Class<? extends Annotation> getReferenceAnnotationType() { + return this.referenceAnnotationType; + } + + /** + * Sets referece annotation type. + */ + public void setReferenceAnnotationType(Class<? extends Annotation> referenceAnnotationType) { + Assert.notNull(referenceAnnotationType, "'referenceAnnotationType' type must not be null."); + this.referenceAnnotationType = referenceAnnotationType; + } + + /** + * This method is used to execute before a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + processAnnotation(bean); + return bean; + } + + /** + * This method is used to execute after a bean's initialization callback. + * + * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) + */ + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + /** + * <p>Processes a beans fields for injection if it has a {@link Reference} annotation.</p> + */ + protected void processAnnotation(final Object bean) { + + final Class<?> clazz = bean.getClass(); + + ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { + public void doWith(Method method) { + + Reference annotation = (Reference) method.getAnnotation(getReferenceAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(method.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on static methods"); + } + + if (Modifier.isPrivate(method.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on private methods"); + } + + if (method.getParameterTypes().length == 0) { + throw new IllegalStateException("Reference annotation requires at least one argument: " + method); + } + + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method); + if (pd != null) { + String refName = annotation.name(); + if ("".equals(refName)) { + injectReference(bean, pd, pd.getName()); + } else { + injectReference(bean, pd, refName); + } + } + } + } + }); + + ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { + public void doWith(Field field) { + + Reference annotation = (Reference) field.getAnnotation(getReferenceAnnotationType()); + + if (annotation != null) { + if (Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on static fields"); + } + + if (Modifier.isPrivate(field.getModifiers())) { + throw new IllegalStateException("Reference annotation is not supported on private fields"); + } + + ReflectionUtils.makeAccessible(field); + + Object referenceObj = null; + String refName = annotation.name(); + if ("".equals(refName)) { + referenceObj = component.getService(field.getType(), field.getName()); + } else { + referenceObj = component.getService(field.getType(), refName); + } + + if (referenceObj != null) + ReflectionUtils.setField(field, bean, referenceObj); + } + } + }); + } + + /** + * Processes a property descriptor to inject a service. + */ + public void injectReference(Object bean, PropertyDescriptor pd, String name) { + + Object referenceObj = component.getService(pd.getPropertyType(), name); + + if (referenceObj != null) { + try { + pd.getWriteMethod().invoke(bean, new Object[] { referenceObj }); + } catch (Throwable e) { + throw new FatalBeanException("Problem injecting reference: " + e.getMessage(), e); + } + } + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java new file mode 100644 index 0000000000..6426306f26 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAGenericApplicationContext.java @@ -0,0 +1,47 @@ +/* + * 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.tuscany.sca.implementation.spring.runtime.context; + +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; + +public class SCAGenericApplicationContext extends GenericApplicationContext { + + ClassLoader classloader = null; + + public SCAGenericApplicationContext(DefaultListableBeanFactory beanFactory, + ApplicationContext parent, + ClassLoader classloader) { + super(beanFactory, parent); + this.classloader = classloader; + } + + public SCAGenericApplicationContext(ApplicationContext parent, + ClassLoader classloader) { + super(parent); + this.classloader = classloader; + } + + @Override + protected void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) { + beanFactory.setBeanClassLoader(classloader); + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java new file mode 100644 index 0000000000..5ea1c2fd9d --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SCAParentApplicationContext.java @@ -0,0 +1,189 @@ +/* + * 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.tuscany.sca.implementation.spring.runtime.context; + +import java.io.IOException; +import java.util.Locale; +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.NoSuchMessageException; +import org.springframework.core.io.Resource; + +/** + * A Spring ParentApplicationContext for a given Spring Implementation + * + * The Parent application context is responsible for handling those entities within a Spring + * application context that actually belong to SCA rather than to Spring. The principal things + * are Properties and References. These may be present either through explicit <sca:property/> + * and <sca:reference/> elements in the application context or they may be implicit through + * unresolved Spring bean <property.../> elements. In either case, it is the Parent application + * context that must provide Spring beans that correspond to the property or reference, as derived + * from the SCA composite in which the Spring application context is an implementation. + * + * @version $Rev$ $Date$ + */ +class SCAParentApplicationContext implements ApplicationContext { + + // The Spring implementation for which this is the parent application context + private SpringImplementationStub implementation; + + private static final String[] EMPTY_ARRAY = new String[0]; + + public SCAParentApplicationContext(SpringImplementationStub implementation) { + this.implementation = implementation; + } // end constructor + + public Object getBean(String name) throws BeansException { + return getBean(name, (Class) null); + } + + /** + * Get a Bean for a reference or for a property. + * + * @param name - the name of the Bean required + * @param requiredType - the required type of the Bean (either a Java class or a Java interface) + * @return Object - a Bean which matches the requested bean + */ + public Object getBean(String name, Class requiredType) throws BeansException { + return implementation.getBean(name, requiredType); + } // end method getBean( String, Class ) + + public Object getBean(String name, Object[] args) throws BeansException { + return getBean(name, ((Class)null)); + } + + public boolean containsBean(String name) { + // TODO + return false; + } + + public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + // TODO + return false; + } + + public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException { + throw new UnsupportedOperationException(); + } + + public Class getType(String name) throws NoSuchBeanDefinitionException { + return null; + } + + public String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return EMPTY_ARRAY; + } + + public ApplicationContext getParent() { + return null; + } + + public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException { + return null; + } + + public String getId() { + return this.toString(); + } + + public String getDisplayName() { + return implementation.getURI(); + } + + public long getStartupDate() { + return 0; + } + + public boolean containsBeanDefinition(String beanName) { + return false; + } + + public int getBeanDefinitionCount() { + return 0; + } + + public String[] getBeanDefinitionNames() { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type) { + return new String[0]; + } + + public String[] getBeanNamesForType(Class type, boolean includePrototypes, boolean includeFactoryBeans) { + return new String[0]; + } + + public Map getBeansOfType(Class type) throws BeansException { + return null; + } + + public Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans) throws BeansException { + return null; + } + + public boolean isPrototype(String theString) { + return false; + } + + public BeanFactory getParentBeanFactory() { + return null; + } + + public boolean containsLocalBean(String name) { + return false; + } + + public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { + return null; + } + + public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException { + return null; + } + + public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { + return null; + } + + public void publishEvent(ApplicationEvent event) { + + } + + public Resource[] getResources(String locationPattern) throws IOException { + return new Resource[0]; + } + + public Resource getResource(String location) { + return null; + } + + public ClassLoader getClassLoader() { + // REVIEW: this is almost certainly flawed, but it's not clear how the SCA runtime's + // resource loading mechanism is exposed right now. + return this.getClass().getClassLoader(); + } +} diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java new file mode 100644 index 0000000000..77681b600f --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringContextTie.java @@ -0,0 +1,133 @@ +/* + * 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.tuscany.sca.implementation.spring.runtime.context; + +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.implementation.spring.processor.ComponentNameAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.ComponentStub; +import org.apache.tuscany.sca.implementation.spring.processor.ConstructorAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.InitDestroyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.PropertyAnnotationProcessor; +import org.apache.tuscany.sca.implementation.spring.processor.PropertyValueStub; +import org.apache.tuscany.sca.implementation.spring.processor.ReferenceAnnotationProcessor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.io.UrlResource; + +/** + * This is the runtime side tie for the corresponding tuscany side stub class. + * It enables the Tuscany code to invoke methods on a Spring context without + * needing to know about any Spring classes. See the SpringContextStub class + * in the implementation-spring module for what the stub does. + */ +public class SpringContextTie { + + private AbstractApplicationContext springContext; + private SpringImplementationStub implementation; + + public SpringContextTie(SpringImplementationStub implementation, List<URL> resource) { + this.implementation = implementation; + SCAParentApplicationContext scaParentContext = new SCAParentApplicationContext(implementation); + springContext = createApplicationContext(scaParentContext, resource); + } + + public void start() { + // Do refresh here to ensure that Spring Beans are not touched before the SCA config process is complete... + springContext.refresh(); + springContext.start(); + } + + public void close() { + springContext.close(); + if (springContext instanceof GenericApplicationContext) { + springContext.stop(); + } + } + + /** + * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean + */ + private AbstractApplicationContext createApplicationContext(SCAParentApplicationContext scaParentContext, List<URL> resources) { + + XmlBeanFactory beanFactory = null; + AbstractApplicationContext appContext = null; + + if (resources.size() > 1) { + GenericApplicationContext appCtx = + new SCAGenericApplicationContext(scaParentContext, implementation.getClassLoader()); + XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(appCtx); + for (URL resource : resources) { + xmlReader.loadBeanDefinitions(new UrlResource(resource)); + } + xmlReader.setBeanClassLoader(implementation.getClassLoader()); + includeAnnotationProcessors(appCtx.getBeanFactory()); + return appCtx; + } + + // use the generic application context as default + beanFactory = new XmlBeanFactory(new UrlResource(resources.get(0))); + beanFactory.setBeanClassLoader(implementation.getClassLoader()); + includeAnnotationProcessors(beanFactory); + appContext = new SCAGenericApplicationContext(beanFactory, + scaParentContext, + implementation.getClassLoader()); + return appContext; + } + + public Object getBean(String id) throws BeansException { + return springContext.getBean(id); + } + + /** + * Include BeanPostProcessor to deal with SCA Annotations in Spring Bean + */ + private void includeAnnotationProcessors(ConfigurableListableBeanFactory beanFactory) { + + // Processor to deal with @Init and @Destroy SCA Annotations + BeanPostProcessor initDestroyProcessor = new InitDestroyAnnotationProcessor(); + beanFactory.addBeanPostProcessor(initDestroyProcessor); + + // Processor to deal with @Reference SCA Annotations + ComponentStub component = new ComponentStub(implementation.getComponentTie()); + BeanPostProcessor referenceProcessor = new ReferenceAnnotationProcessor(component); + beanFactory.addBeanPostProcessor(referenceProcessor); + + // Processor to deal with @Property SCA Annotations + PropertyValueStub pvs = new PropertyValueStub(implementation.getPropertyValueTie()); + BeanPostProcessor propertyProcessor = new PropertyAnnotationProcessor(pvs); + beanFactory.addBeanPostProcessor(propertyProcessor); + + // Processor to deal with @ComponentName SCA Annotations + BeanPostProcessor componentNameProcessor = new ComponentNameAnnotationProcessor(implementation.getComponentName()); + beanFactory.addBeanPostProcessor(componentNameProcessor); + + // Processor to deal with @Constructor SCA Annotations + BeanPostProcessor constructorProcessor = new ConstructorAnnotationProcessor(); + beanFactory.addBeanPostProcessor(constructorProcessor); + } + +}
\ No newline at end of file diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java new file mode 100644 index 0000000000..af39869522 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/java/org/apache/tuscany/sca/implementation/spring/runtime/context/SpringImplementationStub.java @@ -0,0 +1,129 @@ +/* + * 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.tuscany.sca.implementation.spring.runtime.context; + +import java.lang.reflect.Method; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; + +/** + * This is the runtime side stub for the corresponding Tuscany-side stub class. + * It enables the Spring code in the runtime module to invoke methods on a + * Tuscany SpringImplementation without the Spring runtime module + * needing to know about any Tuscany classes. See the SpringImplementationTie class + * in the implementation-spring module for what the tie does. + */ +public class SpringImplementationStub { + + Object tie; + Method getURI; + Method getBean; + Method getComponentName; + Method getComponentTie; + Method getPropertyValueTie; + Method getClassLoader; + + public SpringImplementationStub(Object tie) { + this.tie = tie; + Class<?> tieClass = tie.getClass(); + try { + getURI = tieClass.getMethod("getURI", new Class<?>[]{}); + getBean = tieClass.getMethod("getBean", new Class<?>[]{String.class, Class.class}); + getComponentName = tieClass.getMethod("getComponentName"); + getComponentTie = tieClass.getMethod("getComponentTie"); + getPropertyValueTie = tieClass.getMethod("getPropertyValueTie"); + getClassLoader = tieClass.getMethod("getClassLoader"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public String getURI() { + try { + + return (String)getURI.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Get a Bean for a reference or for a property. + * + * @param name - the name of the Bean required + * @param requiredType - the required type of the Bean (either a Java class or a Java interface) + * @return Object - a Bean which matches the requested bean + */ + public Object getBean(String name, Class<?> requiredType) throws BeansException { + try { + + Object bean = getBean.invoke(tie, new Object[] {name, requiredType}); + if (bean == null) { + throw new NoSuchBeanDefinitionException("Unable to find Bean with name " + name); + } + return bean; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public String getComponentName() { + try { + + return (String)getComponentName.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getComponentTie() { + try { + + return getComponentTie.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public Object getPropertyValueTie() { + try { + + return getPropertyValueTie.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ClassLoader getClassLoader() { + try { + + return (ClassLoader) getClassLoader.invoke(tie); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.handlers b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.handlers new file mode 100644 index 0000000000..6d29e21024 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.handlers @@ -0,0 +1 @@ +http\://www.springframework.org/schema/sca=org.apache.tuscany.sca.implementation.spring.namespace.ScaNamespaceHandler
diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.schemas b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.schemas new file mode 100644 index 0000000000..249cc21c13 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/META-INF/spring.schemas @@ -0,0 +1 @@ +http\://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd=org/springframework/sca/xml/spring-sca.xsd diff --git a/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/org/springframework/sca/xml/spring-sca.xsd b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/org/springframework/sca/xml/spring-sca.xsd new file mode 100644 index 0000000000..dfa0b931f6 --- /dev/null +++ b/sca-java-2.x/trunk/modules/implementation-spring-sca/src/main/resources/org/springframework/sca/xml/spring-sca.xsd @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<xsd:schema xmlns="http://www.springframework.org/schema/sca" xmlns:xsd="http://www.w3.org/2001/XMLSchema" + attributeFormDefault="unqualified" elementFormDefault="qualified" + targetNamespace="http://www.springframework.org/schema/sca"> + + <xsd:element name="reference"> + <xsd:complexType> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="default" use="optional"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:element name="property"> + <xsd:complexType> + <xsd:attribute name="id" use="optional"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:element name="service"> + <xsd:complexType> + <xsd:attribute name="name" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="type" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="target" use="required"> + <xsd:simpleType> + <xsd:restriction base="xsd:string" /> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + +</xsd:schema> |