aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1716829 [1/3] - in /aries/trunk/blueprint: ./ blueprint-spring-extender/ blueprint-spring-extender/src/ blueprint-spring-extender/src/main/ blueprint-spring-extender/src/main/java/ blueprint-spring-extender/src/main/java/org/ blueprint-spr...
Date Fri, 27 Nov 2015 11:08:40 GMT
Author: gnodet
Date: Fri Nov 27 11:08:40 2015
New Revision: 1716829

URL: http://svn.apache.org/viewvc?rev=1716829&view=rev
Log:
[ARIES-1456] Spring extender support
Works similar to spring-dm extender by building an blueprint container from the META-INF/spring/*.xml files (or those specified in the Spring-Context bundle header).
Partial support for the osgi spring namespace (reference and service are partially supported).

Added:
    aries/trunk/blueprint/blueprint-spring-extender/
    aries/trunk/blueprint/blueprint-spring-extender/pom.xml
    aries/trunk/blueprint/blueprint-spring-extender/src/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/Activator.java
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiCompendiumNamespaceHandler.java
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtender.java
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtension.java
    aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.0.xsd
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.1.xsd
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.2.xsd
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-compendium-1.0.xsd
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-compendium-1.1.xsd
    aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-compendium-1.2.xsd
    aries/trunk/blueprint/blueprint-spring/src/main/java/org/apache/aries/blueprint/spring/SpringNamespaceHandler.java
Modified:
    aries/trunk/blueprint/blueprint-spring/src/main/java/org/apache/aries/blueprint/spring/BlueprintNamespaceHandler.java
    aries/trunk/blueprint/blueprint-spring/src/main/java/org/apache/aries/blueprint/spring/SpringNamespaceHandlerResolver.java
    aries/trunk/blueprint/pom.xml

Added: aries/trunk/blueprint/blueprint-spring-extender/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/pom.xml?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/pom.xml (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/pom.xml Fri Nov 27 11:08:40 2015
@@ -0,0 +1,214 @@
+<?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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.aries</groupId>
+        <artifactId>parent</artifactId>
+        <version>2.0.1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.aries.blueprint</groupId>
+    <artifactId>org.apache.aries.blueprint.spring.extender</artifactId>
+    <packaging>bundle</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+    <name>Apache Aries Blueprint Spring Extender Support</name>
+    <description>
+        This bundle contains Spring support for blueprint.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-spring-extender</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-spring-extender</developerConnection>
+        <url>http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender</url>
+    </scm>
+
+    <properties>
+        <!-- Export package versions are maintained in packageinfo files -->
+        <aries.osgi.export.pkg />
+        <aries.osgi.import.pkg>
+           org.apache.aries.blueprint;provide:=true;version="[1.0,2.0)",
+           org.apache.aries.blueprint.ext;provide:=true;version="[1.0,2.0)",
+           *
+        </aries.osgi.import.pkg>
+        <aries.osgi.private.pkg>
+            org.apache.aries.blueprint.spring.extender,
+            org.apache.felix.utils.extender
+        </aries.osgi.private.pkg>
+        <aries.osgi.activator>
+            org.apache.aries.blueprint.spring.extender.Activator
+        </aries.osgi.activator>
+        <blueprint.api.version>1.0.0</blueprint.api.version>
+        <blueprint.core.version>1.5.0-SNAPSHOT</blueprint.core.version>
+        <blueprint.parser.version>1.4.0-SNAPSHOT</blueprint.parser.version>
+        <!--
+        <lastReleaseVersion>1.0.4</lastReleaseVersion>
+        -->
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <blueprint.api.version>1.0.1</blueprint.api.version>
+                <blueprint.core.version>1.5.0-SNAPSHOT</blueprint.core.version>
+                <blueprint.parser.version>1.4.0-SNAPSHOT</blueprint.parser.version>
+            </properties>
+        </profile>
+    </profiles>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.api</artifactId>
+            <version>${blueprint.api.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>blueprint-parser</artifactId>
+            <version>${blueprint.parser.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.core</artifactId>
+            <version>${blueprint.core.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+            <version>4.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>4.2.2.RELEASE</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>4.2.2.RELEASE</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <version>1.8.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.googlecode.pojosr</groupId>
+            <artifactId>de.kalpatec.pojosr.framework</artifactId>
+            <version>0.1.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.swissbox</groupId>
+            <artifactId>pax-swissbox-tinybundles</artifactId>
+            <version>1.3.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.7</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>1.7.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.proxy</groupId>
+            <artifactId>org.apache.aries.proxy.impl</artifactId>
+            <version>1.0.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configadmin</artifactId>
+            <version>1.2.8</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+            <version>4.2.2.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>4.2.2.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.testbundles</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.aries.versioning</groupId>
+                <artifactId>org.apache.aries.versioning.plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>default-verify</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>version-check</goal>
+                        </goals>
+                        <configuration>
+                            <skip>true</skip>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/Activator.java?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/Activator.java (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/Activator.java Fri Nov 27 11:08:40 2015
@@ -0,0 +1,91 @@
+/**
+ *  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.aries.blueprint.spring.extender;
+
+import java.util.Hashtable;
+
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.services.BlueprintExtenderService;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator,
+        ServiceTrackerCustomizer<BlueprintExtenderService, SpringOsgiExtender> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
+
+    BundleContext bundleContext;
+    ServiceTracker<BlueprintExtenderService, SpringOsgiExtender> tracker;
+    ServiceRegistration<NamespaceHandler> osgiNamespaceRegistration;
+    ServiceRegistration<NamespaceHandler> compendiumNamespaceRegistration;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        this.bundleContext = context;
+        tracker = new ServiceTracker<BlueprintExtenderService, SpringOsgiExtender>(
+                bundleContext, BlueprintExtenderService.class, this
+        );
+        tracker.open();
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put("osgi.service.blueprint.namespace", "http://www.springframework.org/schema/osgi");
+        osgiNamespaceRegistration = bundleContext.registerService(
+                NamespaceHandler.class, new SpringOsgiNamespaceHandler(), props);
+        props = new Hashtable<String, String>();
+        props.put("osgi.service.blueprint.namespace", "http://www.springframework.org/schema/osgi-compendium");
+        compendiumNamespaceRegistration = bundleContext.registerService(
+                NamespaceHandler.class, new SpringOsgiCompendiumNamespaceHandler(), props);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+        osgiNamespaceRegistration.unregister();
+        compendiumNamespaceRegistration.unregister();
+    }
+
+    @Override
+    public SpringOsgiExtender addingService(ServiceReference<BlueprintExtenderService> reference) {
+        BlueprintExtenderService blueprintExtenderService = bundleContext.getService(reference);
+        SpringOsgiExtender extender = new SpringOsgiExtender(blueprintExtenderService);
+        try {
+            extender.start(bundleContext);
+        } catch (Exception e) {
+            LOGGER.error("Error starting SpringOsgiExtender", e);
+        }
+        return extender;
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<BlueprintExtenderService> reference, SpringOsgiExtender service) {
+    }
+
+    @Override
+    public void removedService(ServiceReference<BlueprintExtenderService> reference, SpringOsgiExtender service) {
+        try {
+            service.stop(bundleContext);
+        } catch (Exception e) {
+            LOGGER.error("Error stopping SpringOsgiExtender", e);
+        }
+        bundleContext.ungetService(reference);
+    }
+}

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiCompendiumNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiCompendiumNamespaceHandler.java?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiCompendiumNamespaceHandler.java (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiCompendiumNamespaceHandler.java Fri Nov 27 11:08:40 2015
@@ -0,0 +1,52 @@
+package org.apache.aries.blueprint.spring.extender;
+
+import java.net.URL;
+import java.util.Set;
+
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ParserContext;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class SpringOsgiCompendiumNamespaceHandler implements NamespaceHandler {
+
+    @Override
+    public URL getSchemaLocation(String namespace) {
+        if (namespace.startsWith("http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium")) {
+            String sub = namespace.substring("http://www.springframework.org/schema/osgi-compendium/".length());
+            if ("spring-osgi-compendium.xsd".equals(sub)) {
+                sub = "spring-osgi-compendium-1.2.xsd";
+            }
+            return getClass().getResource(sub);
+        }
+        return null;
+    }
+
+    @Override
+    public Set<Class> getManagedClasses() {
+        return null;
+    }
+
+    @Override
+    public Metadata parse(Element element, ParserContext context) {
+        if ("managed-properties".equals(element.getLocalName())) {
+
+        }
+        else if ("managed-service-factory".equals(element.getLocalName())) {
+
+        }
+        else if ("cm-properties".equals(element.getLocalName())) {
+
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+        return component;
+    }
+}

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtender.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtender.java?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtender.java (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtender.java Fri Nov 27 11:08:40 2015
@@ -0,0 +1,128 @@
+/**
+ *  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.aries.blueprint.spring.extender;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.aries.blueprint.services.BlueprintExtenderService;
+import org.apache.aries.blueprint.utils.HeaderParser;
+import org.apache.aries.blueprint.utils.HeaderParser.PathElement;
+import org.apache.felix.utils.extender.AbstractExtender;
+import org.apache.felix.utils.extender.Extension;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Spring namespace extender.
+ * This OSGi extender is responsible for registering spring namespaces for blueprint.
+ *
+ * @see SpringOsgiExtension
+ */
+public class SpringOsgiExtender extends AbstractExtender {
+
+    public static final String SPRING_CONTEXT_HEADER = "Spring-Context";
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SpringOsgiExtender.class);
+
+    private final BlueprintExtenderService blueprintExtenderService;
+
+    public SpringOsgiExtender(BlueprintExtenderService blueprintExtenderService) {
+        this.blueprintExtenderService = blueprintExtenderService;
+    }
+
+    @Override
+    protected Extension doCreateExtension(Bundle bundle) throws Exception {
+        List<URL> paths = getSpringPaths(bundle);
+        if (paths != null && !paths.isEmpty()) {
+            return new SpringOsgiExtension(blueprintExtenderService, bundle, paths);
+        }
+        return null;
+    }
+
+    private List<URL> getSpringPaths(Bundle bundle) throws Exception {
+        LOGGER.debug("Scanning bundle {}/{} for spring application", bundle.getSymbolicName(), bundle.getVersion());
+        List<URL> pathList = new ArrayList<URL>();
+        String springHeader = bundle.getHeaders().get(SPRING_CONTEXT_HEADER);
+        if (springHeader == null) {
+            springHeader = "*";
+        }
+        List<PathElement> paths = HeaderParser.parseHeader(springHeader);
+        for (PathElement path : paths) {
+            String name = path.getName();
+            if ("*".equals(name)) {
+                name = "META-INF/spring/*.xml";
+            }
+            String baseName;
+            String filePattern;
+            int pos = name.lastIndexOf('/');
+            if (pos < 0) {
+                baseName = "/";
+                filePattern = name;
+            } else {
+                baseName = name.substring(0, pos + 1);
+                filePattern = name.substring(pos + 1);
+            }
+            if (filePattern.contains("*")) {
+                Enumeration<URL> e = bundle.findEntries(baseName, filePattern, false);
+                while (e != null && e.hasMoreElements()) {
+                    pathList.add(e.nextElement());
+                }
+            } else {
+                pathList.add(bundle.getEntry(name));
+            }
+        }
+        if (!pathList.isEmpty()) {
+            LOGGER.debug("Found spring application in bundle {}/{} with paths: {}", bundle.getSymbolicName(), bundle.getVersion(), pathList);
+            // Check compatibility
+            // TODO: For lazy bundles, the class is either loaded from an imported package or not found, so it should
+            // not trigger the activation.  If it does, we need to use something else like package admin or
+            // ServiceReference, or just not do this check, which could be quite harmful.
+            if (isCompatible(bundle)) {
+                return pathList;
+            } else {
+                LOGGER.info("Bundle {}/{} is not compatible with this blueprint extender", bundle.getSymbolicName(), bundle.getVersion());
+            }
+        } else {
+            LOGGER.debug("No blueprint application found in bundle {}/{}", bundle.getSymbolicName(), bundle.getVersion());
+        }
+        return null;
+    }
+
+    private boolean isCompatible(Bundle bundle) {
+        return true;
+    }
+
+    @Override
+    protected void debug(Bundle bundle, String msg) {
+        LOGGER.debug(msg + ": " + bundle.getSymbolicName() + "/" + bundle.getVersion());
+    }
+
+    @Override
+    protected void warn(Bundle bundle, String msg, Throwable t) {
+        LOGGER.warn(msg + ": " + bundle.getSymbolicName() + "/" + bundle.getVersion(), t);
+    }
+
+    @Override
+    protected void error(String msg, Throwable t) {
+        LOGGER.error(msg, t);
+    }
+
+}

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtension.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtension.java?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtension.java (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiExtension.java Fri Nov 27 11:08:40 2015
@@ -0,0 +1,122 @@
+/**
+ *  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.aries.blueprint.spring.extender;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.aries.blueprint.services.BlueprintExtenderService;
+import org.apache.felix.utils.extender.Extension;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+public class SpringOsgiExtension implements Extension {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SpringOsgiExtension.class);
+
+    private final BlueprintExtenderService blueprintExtenderService;
+    private final Bundle bundle;
+    private final List<URL> paths;
+
+    BlueprintContainer container;
+
+    public SpringOsgiExtension(BlueprintExtenderService blueprintExtenderService, Bundle bundle, List<URL> paths) {
+        // TODO: parse Spring-Context header directives
+        // TODO:   create-asynchrously
+        // TODO:   wait-for-dependencies
+        // TODO:   timeout
+        // TODO:   publish-context
+        this.blueprintExtenderService = blueprintExtenderService;
+        this.bundle = bundle;
+        this.paths = paths;
+    }
+
+    @Override
+    public void start() throws Exception {
+        List<Object> bpPaths = new ArrayList<Object>();
+
+        Set<String> namespaces = new LinkedHashSet<String>();
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        for (URL url : paths) {
+            InputStream is = url.openStream();
+            try {
+                InputSource inputSource = new InputSource(is);
+                DocumentBuilder builder = dbf.newDocumentBuilder();
+                Document doc = builder.parse(inputSource);
+                Attr schemaLoc = doc.getDocumentElement().getAttributeNodeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
+                if (schemaLoc != null) {
+                    List<String> locs = new ArrayList<String>(Arrays.asList(schemaLoc.getValue().split("\\s+")));
+                    locs.remove("");
+                    for (int i = 0; i < locs.size() / 2; i++) {
+                        namespaces.add(locs.get(i * 2));
+                    }
+                }
+            } finally {
+                is.close();
+            }
+        }
+
+        File file = File.createTempFile("blueprint-spring-extender", ".xml");
+        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
+        try {
+            writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+            writer.write("<blueprint xmlns=\"http://www.osgi.org/xmlns/blueprint/v1.0.0\"\n");
+            writer.write("\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
+            writer.write("\txmlns:bean=\"http://www.springframework.org/schema/beans\"\n");
+            writer.write("\txsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd\">\n");
+            // TODO: improve that, this is a big hack to force the reference to namespace handlers
+            for (String namespace : namespaces) {
+                writer.write("\t<bean class=\"java.lang.String\" scope=\"ns1:dummy\" xmlns:ns1=\"" + namespace + "\"/>\n");
+            }
+            for (URL url : paths) {
+                writer.write("\t<bean:import resource=\"" + url.toString() + "\"/>\n");
+            }
+            writer.write("</blueprint>\n");
+        } finally {
+            writer.close();
+        }
+        LOGGER.info("Generated blueprint for bundle {}/{} at {}", bundle.getSymbolicName(), bundle.getVersion(), file);
+        bpPaths.add(file.toURI().toURL());
+        container = blueprintExtenderService.createContainer(bundle, bpPaths);
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        // Make sure the container has not been destroyed yet
+        if (container == blueprintExtenderService.getContainer(bundle)) {
+            blueprintExtenderService.destroyContainer(bundle, container);
+        }
+    }
+
+}

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/java/org/apache/aries/blueprint/spring/extender/SpringOsgiNamespaceHandler.java Fri Nov 27 11:08:40 2015
@@ -0,0 +1,225 @@
+package org.apache.aries.blueprint.spring.extender;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.mutable.MutableRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
+import org.apache.aries.blueprint.mutable.MutableServiceMetadata;
+import org.apache.aries.blueprint.mutable.MutableValueMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.NonNullMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.*;
+
+public class SpringOsgiNamespaceHandler implements NamespaceHandler {
+
+    @Override
+    public URL getSchemaLocation(String namespace) {
+        if (namespace.startsWith("http://www.springframework.org/schema/osgi/spring-osgi")) {
+            String sub = namespace.substring("http://www.springframework.org/schema/osgi/".length());
+            if ("spring-osgi.xsd".equals(sub)) {
+                sub = "spring-osgi-1.2.xsd";
+            }
+            return getClass().getResource(sub);
+        }
+        return null;
+    }
+
+    @Override
+    public Set<Class> getManagedClasses() {
+        return null;
+    }
+
+    @Override
+    public Metadata parse(Element element, ParserContext context) {
+        if ("reference".equals(element.getLocalName())) {
+            MutableReferenceMetadata metadata = context.createMetadata(MutableReferenceMetadata.class);
+            // Parse attributes
+            // TODO: auto generate id ?
+            metadata.setId(element.getAttribute("id"));
+            metadata.setAvailability("0..1".equals(element.getAttribute("cardinality"))
+                    ? ReferenceMetadata.AVAILABILITY_OPTIONAL
+                    : ReferenceMetadata.AVAILABILITY_MANDATORY);
+            metadata.setTimeout(getLong(element.getAttribute("timeout"), 300000));
+            metadata.setInterface(element.getAttribute("interface"));
+            metadata.setFilter(element.getAttribute("filter"));
+            String[] dependsOn = StringUtils.tokenizeToStringArray(element.getAttribute("depends-on"), ",; ");
+            metadata.setDependsOn(dependsOn != null ? Arrays.asList(dependsOn) : null);
+            metadata.setComponentName(element.getAttribute("bean-name"));
+            // TODO: @context-class-loader
+            // Parse child elements
+            for (Element child : getChildren(element)) {
+                if (element.getNamespaceURI().equals(child.getNamespaceURI())) {
+                    if ("interfaces".equals(child.getLocalName())) {
+                        List<String> extra = new ArrayList<String>();
+                        for (Element e : getChildren(child)) {
+                            if ("value".equals(e.getLocalName())) {
+                                extra.add(getTextValue(e));
+                            } else {
+                                // TODO: support other elements ?
+                                throw new UnsupportedOperationException("Unsupported child: " + element.getLocalName());
+                            }
+                        }
+                        metadata.setExtraInterfaces(extra);
+                    }
+                    else if ("listener".equals(child.getLocalName())) {
+                        // TODO: listener
+
+                    }
+                }
+                else {
+                    throw new UnsupportedOperationException("Custom namespaces not supported");
+                }
+            }
+            return metadata;
+        }
+        else if ("service".equals(element.getLocalName())) {
+            MutableServiceMetadata metadata = context.createMetadata(MutableServiceMetadata.class);
+            // Parse attributes
+            // TODO: auto generate id ?
+            metadata.setId(element.getAttribute("id"));
+            if (element.getAttribute("ref") != null) {
+                MutableRefMetadata ref = context.createMetadata(MutableRefMetadata.class);
+                ref.setComponentId(element.getAttribute("ref"));
+                metadata.setServiceComponent(ref);
+            }
+            metadata.setRanking(element.getAttribute("ranking") != null
+                    ? Integer.parseInt(element.getAttribute("ranking"))
+                    : 0);
+            String itf = element.getAttribute("interface");
+            if (itf != null) {
+                metadata.addInterface(itf);
+            }
+            String[] dependsOn = StringUtils.tokenizeToStringArray(element.getAttribute("depends-on"), ",; ");
+            metadata.setDependsOn(dependsOn != null ? Arrays.asList(dependsOn) : null);
+            String autoExp = element.getAttribute("auto-export");
+            if ("interfaces".equals(autoExp)) {
+                metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_INTERFACES);
+            } else if ("class-hierarchy".equals(autoExp)) {
+                metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY);
+            } else if ("all-classes".equals(autoExp)) {
+                metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_ALL_CLASSES);
+            } else {
+                metadata.setAutoExport(ServiceMetadata.AUTO_EXPORT_DISABLED);
+            }
+            // TODO: @context-class-loader
+            // Parse child elements
+            for (Element child : getChildren(element)) {
+                if (element.getNamespaceURI().equals(child.getNamespaceURI())) {
+                    if ("interfaces".equals(child.getLocalName())) {
+                        for (Element e : getChildren(child)) {
+                            if ("value".equals(e.getLocalName())) {
+                                metadata.addInterface(getTextValue(e));
+                            } else {
+                                // TODO: support other elements ?
+                                throw new UnsupportedOperationException("Unsupported child: " + element.getLocalName());
+                            }
+                        }
+                    }
+                    else if ("registration-listener".equals(child.getLocalName())) {
+                        // TODO: registration-listener
+
+                    }
+                    else if ("service-properties".equals(child.getLocalName())) {
+                        // TODO: @key-type
+                        for (Element e : getChildren(child)) {
+                            if ("entry".equals(e.getLocalName())) {
+                                NonNullMetadata key;
+                                Metadata val;
+                                boolean hasKeyAttribute = e.hasAttribute("key");
+                                boolean hasKeyRefAttribute = e.hasAttribute("key-ref");
+                                if (hasKeyRefAttribute && !hasKeyAttribute) {
+                                    MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class);
+                                    r.setComponentId(e.getAttribute("key-ref"));
+                                    key = r;
+                                } else if (hasKeyAttribute && !hasKeyRefAttribute) {
+                                    MutableValueMetadata v = context.createMetadata(MutableValueMetadata.class);
+                                    v.setStringValue(e.getAttribute("key"));
+                                    key = v;
+                                } else {
+                                    throw new IllegalStateException("Either key or key-ref must be specified");
+                                }
+                                // TODO: support children elements ?
+                                boolean hasValAttribute = e.hasAttribute("value");
+                                boolean hasValRefAttribute = e.hasAttribute("value-ref");
+                                if (hasValRefAttribute && !hasValAttribute) {
+                                    MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class);
+                                    r.setComponentId(e.getAttribute("value-ref"));
+                                    val = r;
+                                } else if (hasValAttribute && !hasValRefAttribute) {
+                                    MutableValueMetadata v = context.createMetadata(MutableValueMetadata.class);
+                                    v.setStringValue(e.getAttribute("value"));
+                                    val = v;
+                                } else {
+                                    throw new IllegalStateException("Either val or val-ref must be specified");
+                                }
+                                // TODO: support children elements ?
+                                metadata.addServiceProperty(key, val);
+                            }
+                        }
+                    }
+                }
+                else {
+                    throw new UnsupportedOperationException("Custom namespaces not supported");
+                }
+            }
+            return metadata;
+        }
+        else if ("bundle".equals(element.getLocalName())) {
+
+        }
+        else if ("set".equals(element.getLocalName())) {
+
+        }
+        else if ("list".equals(element.getLocalName())) {
+
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+        return component;
+    }
+
+    private List<Element> getChildren(Element element) {
+        List<Element> children = new ArrayList<Element>();
+        for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
+            if (child instanceof Element) {
+                children.add((Element) child);
+            }
+        }
+        return children;
+    }
+
+    private long getLong(String str, long def) {
+        if (str == null || str.isEmpty()) {
+            return def;
+        } else {
+            return Long.parseLong(str);
+        }
+    }
+
+    public static String getTextValue(Element valueEle) {
+        Assert.notNull(valueEle, "Element must not be null");
+        StringBuilder sb = new StringBuilder();
+        NodeList nl = valueEle.getChildNodes();
+        for(int i = 0; i < nl.getLength(); ++i) {
+            Node item = nl.item(i);
+            if(item instanceof CharacterData && !(item instanceof Comment) || item instanceof EntityReference) {
+                sb.append(item.getNodeValue());
+            }
+        }
+        return sb.toString();
+    }
+}

Added: aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.0.xsd
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.0.xsd?rev=1716829&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.0.xsd (added)
+++ aries/trunk/blueprint/blueprint-spring-extender/src/main/resources/org.apache.aries.blueprint.spring.extender/spring-osgi-1.0.xsd Fri Nov 27 11:08:40 2015
@@ -0,0 +1,590 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<xsd:schema xmlns="http://www.springframework.org/schema/osgi"
+            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:beans="http://www.springframework.org/schema/beans"
+            xmlns:tool="http://www.springframework.org/schema/tool"
+            targetNamespace="http://www.springframework.org/schema/osgi"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            version="1.0">
+
+    <xsd:import namespace="http://www.springframework.org/schema/beans"/>
+    <xsd:import namespace="http://www.springframework.org/schema/tool"/>
+
+    <xsd:annotation>
+        <xsd:documentation><![CDATA[
+            Namespace support for the core services provided by Spring Dynamic Modules.
+        ]]></xsd:documentation>
+    </xsd:annotation>
+    
+    <xsd:attributeGroup name="defaults">
+    	<xsd:annotation>
+    		<xsd:documentation><![CDATA[Defaults for Spring-DM OSGi declarations.]]>
+    		</xsd:documentation>
+    	</xsd:annotation>
+    	<!-- attributes -->
+    	<xsd:attribute name="default-timeout" type="xsd:long" default="30000">
+    		<xsd:annotation>
+    			<xsd:documentation><![CDATA[
+    			Default timeout (in milliseconds) for all reference (service importers) elements that do not explicitly specify one.
+    			Default value is 300000 ms (5 minutes).
+    			]]></xsd:documentation>
+    		</xsd:annotation>
+    	</xsd:attribute>
+    	<xsd:attribute name="default-cardinality" type="TdefaultCardinalityOptions" default="1..X">
+    		<xsd:annotation>
+    			<xsd:documentation><![CDATA[
+            	Default cardinality (of the relationship to the backing service(s)) for all OSGi references (singular or collections) 
+            	elements that do not explicitly specify one.
+            	Default value is '1..X' (resolved to '1..1' for osgi:reference and '1..N' for osgi:list/set) which means that a backing 
+            	service must exist (this is a mandatory service reference). A value of '0..X' (resolved to '0..1' for osgi:reference 
+            	and '0..N' for osgi:list/set) indicates that it is acceptable to be no backing service (an optional service reference).
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+    </xsd:attributeGroup>
+    
+    <xsd:simpleType name="TdefaultCardinalityOptions">
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="1..X">
+            	<xsd:annotation>
+            		<xsd:documentation><![CDATA[
+            		A backing service must exist (this is a mandatory service reference).
+            		]]></xsd:documentation>
+            	</xsd:annotation>
+            </xsd:enumeration>
+            <xsd:enumeration value="0..X">
+            	<xsd:annotation>
+            		<xsd:documentation><![CDATA[
+            		A backing service can be missing (this is an optional service reference).
+            		]]></xsd:documentation>
+            	</xsd:annotation>
+            </xsd:enumeration>
+        </xsd:restriction>
+    </xsd:simpleType>
+	
+    <!-- reference -->
+    <xsd:element name="reference" type="TsingleReference">
+        <xsd:annotation>
+            <xsd:documentation><![CDATA[
+            Defines a reference to a service obtained via the OSGi service registry.
+            ]]></xsd:documentation>
+        </xsd:annotation>
+    </xsd:element>
+
+    <xsd:complexType name="Treference">
+        <xsd:complexContent>
+            <xsd:extension base="beans:identifiedType">
+                <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+                	<xsd:element name="interfaces" type="beans:listOrSetType" minOccurs="0" maxOccurs="1">
+                    	<xsd:annotation>
+                    		<xsd:documentation><![CDATA[
+                    		The set of service interfaces to advertise in the service registry.
+                    		]]></xsd:documentation>
+                    	</xsd:annotation>
+                    </xsd:element>                
+                    <xsd:element name="listener" type="Tlistener" minOccurs="0" maxOccurs="unbounded">
+                      <xsd:annotation>
+                      	<xsd:documentation><![CDATA[
+                      	  Defines a listener that will receive notification when a service backing this reference is 
+                      	  bound or unbound. 
+                      	]]></xsd:documentation>
+                      </xsd:annotation>
+                    </xsd:element>
+                </xsd:sequence>
+                <xsd:attribute name="interface" use="optional" type="xsd:token">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                		The service interface that the services obtained via the registry are required to support.
+                		By convention this is a Java interface type, but may also be a (non-final) class type.
+                		]]></xsd:documentation>
+                		<xsd:appinfo>
+                			<tool:annotation>
+                				<tool:expected-type type="java.lang.Class" />
+                			</tool:annotation>
+                		</xsd:appinfo>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="filter" use="optional" type="xsd:string">
+                      <xsd:annotation>
+                      	<xsd:documentation><![CDATA[
+                      	  Defines an OSGi filter expression that is used to constrain the set of matching services
+                      	  in the service registry. 
+                      	]]></xsd:documentation>
+                      </xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="depends-on" type="xsd:string" use="optional">
+					<xsd:annotation>
+						<xsd:documentation><![CDATA[
+							Used to refer to the name of another bean that this bean depends on. Ensures that the
+							service registry look-up does not happen until after the dependent bean has been created 
+							(most commonly used to refer to a bundle bean).
+						]]></xsd:documentation>
+					</xsd:annotation>                
+                </xsd:attribute>
+                <xsd:attribute name="bean-name" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Convenient shortcut for specifying a filter expression that matches on the bean-name property
+                			that is automatically advertised for beans published using the service element.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="context-class-loader" type="TreferenceClassLoaderOptions" default="client">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Defines how the context class loader is managed when invoking operations on a service
+                			backing this service reference. The default value is 'client' which means that the context
+                			class loader has visibility of the resources on this bundle's classpath. Alternate
+                			options are 'service-provider' which means that the context class loader has visibility of 
+                			resources on the bundle classpath of the bundle that exported the service, and 'unmanaged'
+                			which does not do any management of the context class loader.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+    
+    <xsd:simpleType name="TreferenceClassLoaderOptions">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="client"/>
+            <xsd:enumeration value="service-provider"/>
+            <xsd:enumeration value="unmanaged"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <xsd:complexType name="Tlistener">
+    	<xsd:annotation>
+    		<xsd:documentation><![CDATA[
+    			Defines a listener that will be notified when the service backing the enclosing service reference element is bound or 
+    			unbound. Use either the 'ref' attribute or a nested bean declaration for the listener bean.
+    		]]></xsd:documentation>
+    	</xsd:annotation>
+        <xsd:sequence minOccurs="0" maxOccurs="1">
+            <!-- nested bean declaration -->
+            <xsd:any namespace="##other" minOccurs="1" maxOccurs="1" processContents="skip"/>
+        </xsd:sequence>
+
+        <!-- shortcut for bean references -->
+        <xsd:attribute name="ref" type="xsd:string" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			Refers by name to the bean that will receive bind and unbind events
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="bind-method" type="xsd:token" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			The name of the method to be invoked when a backing service is bound.
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="unbind-method" type="xsd:token" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			The name of the method to be invoked when a backing service is unbound.
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+    </xsd:complexType>
+    
+    <!-- single reference -->
+    <xsd:complexType name="TsingleReference">
+        <xsd:complexContent>
+            <xsd:extension base="Treference">
+                 <xsd:attribute name="cardinality" use="optional" type="TsingleReferenceCardinality">
+                	<xsd:annotation>
+                      	<xsd:documentation><![CDATA[
+                      	  Defines the required cardinality of the relationship to the backing service. If not specified, 
+                      	  the default-cardinality attribute will apply. A value is '1..1' means that a backing service 
+                      	  must exist (this is a mandatory service reference). A value of '0..1' indicates that it is 
+                      	  acceptable to be no backing service (an optional service reference).
+                      	]]></xsd:documentation>
+                      </xsd:annotation>
+                </xsd:attribute>
+				<xsd:attribute name="timeout" use="optional" type="xsd:long">
+                    <xsd:annotation>
+                      	<xsd:documentation><![CDATA[
+                      	  For a 'reference' element, the amount of time (in milliseconds) to wait for a backing service to be 
+                      	  available when an operation is invoked. If not specified, the default-timeout attribute will apply.
+                      	  See also the default-timeout attribute of the osgi element.
+                      	]]></xsd:documentation>
+                      </xsd:annotation>
+                </xsd:attribute>
+            </xsd:extension>
+        </xsd:complexContent>
+   </xsd:complexType>
+   
+   <xsd:simpleType name="TsingleReferenceCardinality">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="1..1"/>
+            <xsd:enumeration value="0..1"/>
+        </xsd:restriction>
+   </xsd:simpleType>
+
+	<!-- reference collections (set, list) -->
+	<xsd:element name="list" type="TreferenceCollection">
+		<xsd:annotation>
+			<xsd:documentation source="java:org.springframework.osgi.service.importer.support.OsgiServiceCollectionProxyFactoryBean"><![CDATA[
+			  Defines a bean of type 'List' that contains all of the services matching the given criteria.
+			  The list members are managed dynamically as matching backing services come and go.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="java.util.List"/>
+				</tool:annotation>
+			</xsd:appinfo>			
+		</xsd:annotation>
+	</xsd:element>
+
+	<xsd:element name="set" type="TreferenceCollection">
+		<xsd:annotation>
+			<xsd:documentation source="java:org.springframework.osgi.service.importer.support.OsgiServiceCollectionProxyFactoryBean"><![CDATA[
+			  Defines a bean of type 'Set' that contains all of the services matching the given criteria.
+			  The set members are managed dynamically as matching backing services come and go.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="java.util.Set"/>
+				</tool:annotation>
+			</xsd:appinfo>			
+		</xsd:annotation>
+	</xsd:element>
+
+	<xsd:complexType name="TreferenceCollection">
+		<xsd:complexContent>
+			<xsd:extension base="Treference">
+				<xsd:sequence minOccurs="0" maxOccurs="1">
+					<xsd:element name="comparator" type="Tcomparator">
+						<xsd:annotation>
+							<xsd:documentation source="java:java.util.Comparator"><![CDATA[
+							  Used to define an inline bean of type Comparator that will be used to sort the matching services.
+							]]></xsd:documentation>
+							<xsd:appinfo>
+								<tool:annotation>
+									<tool:expected-type type="java.util.Comparator" />
+  								</tool:annotation>
+							</xsd:appinfo>
+						</xsd:annotation>
+					</xsd:element>
+				</xsd:sequence>
+				<xsd:attribute name="comparator-ref" type="xsd:string" use="optional">
+					<xsd:annotation>
+						<xsd:documentation><![CDATA[
+							Used to refer to a named bean implementing the Comparator interface that will be used to 
+							sort the matching services.
+						]]></xsd:documentation>
+					</xsd:annotation>
+				</xsd:attribute>
+			
+			    <xsd:attribute name="cardinality" use="optional" type="TcollectionCardinality">
+                	<xsd:annotation>
+                      	<xsd:documentation><![CDATA[
+                      	  Defines the required cardinality of the relationship to the backing services. If not specified, 
+                      	  the default-cardinality attribute will apply. A value of '1..N' means that at least one backing 
+                      	  service must exist (this is a mandatory service reference. A value of '0..N' indicates that it 
+                      	  is acceptable for there to be no backing service (an optional service reference).
+                      	]]></xsd:documentation>
+                      </xsd:annotation>
+                </xsd:attribute>				
+			</xsd:extension>
+		</xsd:complexContent>
+	</xsd:complexType>
+	
+	<xsd:complexType name="Tcomparator">
+		<xsd:annotation>
+			<xsd:documentation source="java:java.util.Comparator"><![CDATA[
+			  Used to define an inline bean of type Comparator that will be used to sort the matching services.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="java.util.Comparator" />
+  				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:choice>
+		   <xsd:element name="natural" type="TnaturalOrdering"/>
+     	   <xsd:sequence minOccurs="1" maxOccurs="1">
+        	    <!-- nested bean declaration -->
+           		<xsd:any namespace="##other" minOccurs="1" maxOccurs="1" processContents="skip"/>
+        	</xsd:sequence>
+        </xsd:choice>
+	</xsd:complexType>
+	
+	<xsd:complexType name="TnaturalOrdering">
+		<xsd:attribute name="basis" type="TorderingBasis" use="required"/>
+	</xsd:complexType>
+	
+	<xsd:simpleType name="TorderingBasis">
+		<xsd:restriction base="xsd:token">
+            <xsd:enumeration value="service"/>
+            <xsd:enumeration value="service-reference"/>
+        </xsd:restriction>
+	</xsd:simpleType>
+	
+	<xsd:simpleType name="TcollectionCardinality">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="1..N"/>
+            <xsd:enumeration value="0..N"/>
+        </xsd:restriction>
+   </xsd:simpleType>
+	
+    <!-- service -->
+    
+    <xsd:element name="service" type="Tservice"/>
+
+    <xsd:complexType name="Tservice">
+    	<xsd:annotation>
+    		<xsd:documentation source="java:org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean"><![CDATA[
+    			Exports the reference bean as a service in the OSGi service registry. The bean defined by this element is of 
+    			type org.osgi.framework.ServiceRegistration.
+    		]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.osgi.framework.ServiceRegistration"/>
+				</tool:annotation>
+			</xsd:appinfo>			
+    	</xsd:annotation>
+        <xsd:complexContent>
+            <xsd:extension base="beans:identifiedType">
+                <xsd:sequence minOccurs="0" maxOccurs="1">
+                    <xsd:element name="interfaces" type="beans:listOrSetType" minOccurs="0">
+                    	<xsd:annotation>
+                    		<xsd:documentation><![CDATA[
+                    			The set of service interfaces to advertise in the service registry.
+                    		]]></xsd:documentation>
+                    	</xsd:annotation>
+                    </xsd:element>
+                    <xsd:element name="service-properties" minOccurs="0" type="beans:mapType">
+                       	<xsd:annotation>
+                    		<xsd:documentation><![CDATA[
+                    			Defines the service properties.
+                    		]]></xsd:documentation>
+                    	</xsd:annotation>
+                    </xsd:element>
+                    <xsd:element name="registration-listener" type="TserviceRegistrationListener" minOccurs="0" maxOccurs="unbounded">
+                    	<xsd:annotation>
+                    		<xsd:documentation><![CDATA[
+                    			Defines a listener that will be notified when this service is registered or unregistered in the
+                    			OSGi service registry.
+                    		]]></xsd:documentation>
+                    	</xsd:annotation>
+                    </xsd:element>
+                    
+                    <!-- nested bean declaration -->
+                    <xsd:any namespace="##other" minOccurs="0" maxOccurs="1" processContents="skip"/>
+                </xsd:sequence>
+                <xsd:attribute name="interface" type="xsd:token" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Defines the interface to advertise for this service in the service registry.
+                		]]></xsd:documentation>
+						<xsd:appinfo>
+							<tool:annotation>
+  								<tool:expected-type type="java.lang.Class" />
+  							</tool:annotation>
+						</xsd:appinfo>  							
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="ref" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Refers to the named bean to be exported as a service in the service registry.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="depends-on" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Used to ensure that the service is not exported to the registry before the named bean
+                			has been created. 
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="context-class-loader" type="TserviceClassLoaderOptions" default="unmanaged">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Defines how the context class loader will be managed when an operation is invoked on the 
+                			exported service. The default value is 'unmanaged' which means that no management of 
+                			the context class loader is attempted. A value of 'service-provider' guarantees that
+                			the context class loader will have visibility of all the resources on the class path of 
+                			bundle exporting the service.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="auto-export" type="TautoExportModes" default="disabled">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Enables Spring to automatically manage the set of service interfaces advertised for the
+                			service. By default this facility is disabled. A value of 'interfaces' advertises all 
+                			of the Java interfaces supported by the exported service. A value of 'class-hierarchy' 
+                			advertises all the Java classes in the hierarchy of the exported service. A value of 
+                			'all-classes' advertises all Java interfaces and classes. 
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="ranking" type="xsd:int" default="0">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Specify the service ranking to be used when advertising the service.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="TserviceRegistrationListener">
+    	<xsd:annotation>
+    		<xsd:documentation><![CDATA[
+    			Defines a listener that will be notified when the bean is registered or unregistered in the OSGi Service Registry. 
+    			Use either the 'ref' attribute or a nested bean declaration for the listener bean.
+    		]]></xsd:documentation>
+    	</xsd:annotation>
+        <xsd:sequence minOccurs="0" maxOccurs="1">
+            <!-- nested bean declaration -->
+            <xsd:any namespace="##other" minOccurs="1" maxOccurs="1" processContents="skip"/>
+        </xsd:sequence>
+
+        <!-- shortcut for bean references -->
+        <xsd:attribute name="ref" type="xsd:string" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			Refers by name to the bean that will receive register and unregister events.
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="registration-method" type="xsd:token" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			The name of the method to be invoked when the service is registered.
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+        <xsd:attribute name="unregistration-method" type="xsd:token" use="optional">
+        	<xsd:annotation>
+        		<xsd:documentation><![CDATA[
+        			The name of the method to be invoked when the service is unregistered.
+        		]]></xsd:documentation>
+        	</xsd:annotation>
+        </xsd:attribute>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TserviceClassLoaderOptions">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="service-provider"/>
+            <xsd:enumeration value="unmanaged"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <xsd:simpleType name="TautoExportModes">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="disabled"/>
+            <xsd:enumeration value="interfaces"/>
+            <xsd:enumeration value="class-hierarchy"/>
+            <xsd:enumeration value="all-classes"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!-- bundle -->
+
+    <xsd:element name="bundle" type="Tbundle">
+    	<xsd:annotation>
+    		<xsd:documentation source="java:org.springframework.osgi.bundle.BundleFactoryBean"><![CDATA[
+    			Defines a bean representing a Bundle object. May be used to drive bean lifecycle transitions.
+    		]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.osgi.framework.Bundle"/>
+				</tool:annotation>
+			</xsd:appinfo>    		
+    	</xsd:annotation>
+    </xsd:element>
+
+    <xsd:complexType name="Tbundle">
+        <xsd:complexContent>
+            <xsd:extension base="beans:identifiedType">
+              	<!-- optional nested bean declaration -->
+                <xsd:sequence minOccurs="0" maxOccurs="1">
+		    		<xsd:any namespace="##other" minOccurs="1" maxOccurs="1" processContents="lax">
+            		   	<xsd:annotation>
+                    		<xsd:documentation><![CDATA[
+                    			OSGi bundle to work with.
+                    		]]></xsd:documentation>
+							<xsd:appinfo>
+								<tool:annotation>
+  									<tool:expected-type type="org.osgi.framework.Bundle" />
+  								</tool:annotation>
+							</xsd:appinfo>  							
+                    	</xsd:annotation>
+            		</xsd:any>
+        		</xsd:sequence>
+        		
+                <xsd:attribute name="symbolic-name" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			The bundle symbolic name of the bundle object. Normally used when interacting with an already
+                			installed bundle.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="depends-on" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Indicates that this bundle object should not be created until the named bean has been created.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+               
+                <xsd:attribute name="location" type="xsd:string" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Location used to install, update or/and identify a bundle.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="action" type="TbundleAction" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                		Lifecyle action to drive on the bundle. 'start' starts the bundle, installing if necessary.
+                		'stop' stops the bundle if it is currently ACTIVE. 'install' installs the bundle if it is 
+                		currently uninstalled. 'uninstall' stops the bundle if needed, and then uninstalls it.
+                		'update' installs the bundle if needed, and then invokes the Bundle.update() operation.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="destroy-action" type="TbundleAction" use="optional">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                		Lifecyle action to drive on the bundle. 'start' starts the bundle, installing if necessary.
+                		'stop' stops the bundle if it is currently ACTIVE. 'install' installs the bundle if it is 
+                		currently uninstalled. 'uninstall' stops the bundle if needed, and then uninstalls it.
+                		'update' installs the bundle if needed, and then invokes the Bundle.update() operation.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+                <xsd:attribute name="start-level" type="xsd:int" use="optional" default="0">
+                	<xsd:annotation>
+                		<xsd:documentation><![CDATA[
+                			Start level to set for the bundle.
+                		]]></xsd:documentation>
+                	</xsd:annotation>
+                </xsd:attribute>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TbundleAction">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="start"/>
+            <xsd:enumeration value="stop"/>
+            <xsd:enumeration value="install"/>
+            <xsd:enumeration value="uninstall"/>
+            <xsd:enumeration value="update"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+
+</xsd:schema>
\ No newline at end of file



Mime
View raw message