You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by zo...@apache.org on 2011/02/27 19:08:17 UTC

svn commit: r1075099 [2/7] - in /aries/tags/jpa-0.1-incubating: ./ jpa-api/ jpa-api/src/ jpa-api/src/main/ jpa-api/src/main/java/ jpa-api/src/main/java/org/ jpa-api/src/main/java/org/apache/ jpa-api/src/main/java/org/apache/aries/ jpa-api/src/main/java...

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/PersistenceUnitConstants.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/PersistenceUnitConstants.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/PersistenceUnitConstants.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/PersistenceUnitConstants.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,39 @@
+/*
+ * 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 WARRANTIESOR 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.jpa.container;
+
+import javax.persistence.spi.PersistenceProvider;
+
+/**
+ * Constants used when registering Persistence Units in the service registry
+ */
+public interface PersistenceUnitConstants {
+  /** The service property key mapped to the persistence unit name */
+  public static final String OSGI_UNIT_NAME = "osgi.unit.name";
+  /** The version of the persistence bundle as a {@link Version} object*/
+  public static final String OSGI_UNIT_VERSION = "osgi.unit.version";
+  /** The service property key mapped to the {@link PersistenceProvider} implementation class name */
+  public static final String OSGI_UNIT_PROVIDER = "osgi.unit.provider";
+  /** The service property key mapped to a Boolean indicating whether this persistence unit is container managed */ 
+  public static final String CONTAINER_MANAGED_PERSISTENCE_UNIT = "org.apache.aries.jpa.container.managed";
+  /** The service property key mapped to a Boolean indicating whether this persistence unit has the default (empty string) unit name 
+   *  This allows clients to filter for empty string persistence unit names.
+   */
+  public static final String EMPTY_PERSISTENCE_UNIT_NAME = "org.apache.aries.jpa.default.unit.name";
+}

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/context/PersistenceContextProvider.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/context/PersistenceContextProvider.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/context/PersistenceContextProvider.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/context/PersistenceContextProvider.java Sun Feb 27 18:08:10 2011
@@ -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.aries.jpa.container.context;
+
+import java.util.HashMap;
+
+import javax.persistence.PersistenceContextType;
+
+import org.osgi.framework.Bundle;
+
+public interface PersistenceContextProvider {
+  
+  /** The key to use when storing the {@link PersistenceContextType} for this context */
+  public static final String PERSISTENCE_CONTEXT_TYPE = "org.apache.aries.jpa.context.type";
+  
+  /**
+   * The service property key indicating that a registered EMF is used to create
+   * managed persistence contexts
+   */
+  public static final String PROXY_FACTORY_EMF_ATTRIBUTE = "org.apache.aries.jpa.proxy.factory";
+  
+  /**
+   * This method will be called whenever a persistence context element is processed by the jpa
+   * blueprint namespace handler.
+   * 
+   * @param unitName   The name of the persistence unit
+   * @param client     The blueprint bundle that declares the dependency
+   * @param properties Properties that should be used to create the persistence unit
+   */
+  void registerContext(String unitName, Bundle client, HashMap<String,Object> properties);
+}

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/ParsedPersistenceUnit.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/ParsedPersistenceUnit.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/ParsedPersistenceUnit.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/ParsedPersistenceUnit.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,90 @@
+/*
+ * 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 WARRANTIESOR 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.jpa.container.parsing;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * This interface provides access to the information defined by a 
+ * persistence unit in a persistence descriptor.
+ * 
+ * Implementations of this interface will be returned by calls to
+ * {@link PersistenceDescriptorParser}.
+ */
+public interface ParsedPersistenceUnit {
+  /*
+   * Keys for use in the PersistenceXml Map
+   * Stored values are Strings unless otherwise specified, and all values
+   * other than the schema version and unit name may be null. A null value
+   * indicates that the element/attribute was not present in the xml.
+   */
+  
+  /** The version of the JPA schema being used */
+  public static final String SCHEMA_VERSION = "org.apache.aries.jpa.schema.version";
+  /** The name of the persistence unit */
+  public static final String UNIT_NAME = "org.apache.aries.jpa.unit.name";
+  /** The Transaction type of the persistence unit */
+  public static final String TRANSACTION_TYPE = "org.apache.aries.jpa.transaction.type";
+  /** A {@link List} of {@link String} mapping file names */
+  public static final String MAPPING_FILES = "org.apache.aries.jpa.mapping.files";
+  /** A {@link List} of {@link String} jar file names */
+  public static final String JAR_FILES = "org.apache.aries.jpa.jar.files";
+  /** A {@link List} of {@link String} managed class names */
+  public static final String MANAGED_CLASSES = "org.apache.aries.jpa.managed.classes";
+  /** A {@link Properties} object containing the properties from the persistence unit */
+  public static final String PROPERTIES = "org.apache.aries.jpa.properties";
+  /** The provider class name */
+  public static final String PROVIDER_CLASSNAME = "org.apache.aries.jpa.provider";
+  /** The jta-datasource name */
+  public static final String JTA_DATASOURCE = "org.apache.aries.jpa.jta.datasource";
+  /** The non-jta-datasource name */
+  public static final String NON_JTA_DATASOURCE = "org.apache.aries.jpa.non.jta.datasource";
+  /** A {@link Boolean} indicating whether unlisted classes should be excluded */
+  public static final String EXCLUDE_UNLISTED_CLASSES = "org.apache.aries.jpa.exclude.unlisted";
+  
+  /* JPA 2 extensions */
+  
+  /** The caching type of the persistence unit. This will only be available for JPA2 persistence units. */
+  public static final String SHARED_CACHE_MODE = "org.apache.aries.jpa2.shared.cache.mode";
+  /** The validation mode of the persistence unit. This will only be available for JPA2 persistence units. */
+  public static final String VALIDATION_MODE = "org.apache.aries.jpa2.validation.mode";
+  
+  
+  /* End of Map keys */
+  
+  /** This property is used in the JPA properties to indicate a provider version range */
+  public static final String JPA_PROVIDER_VERSION = "org.apache.aries.jpa.provider.version";
+
+  /**
+   * Return the persistence bundle that defines this persistence unit
+   * @return
+   */
+  public Bundle getDefiningBundle();
+
+  /**
+   * Returns a deep copy of the persistence metadata, modifications to the
+   * returned {@link Map} will not be reflected in future calls. 
+   * @return
+   */
+  public Map<String, Object> getPersistenceXmlMetadata();
+}

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptor.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptor.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptor.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptor.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,50 @@
+/*
+ * 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 WARRANTIESOR 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.jpa.container.parsing;
+
+import java.io.InputStream;
+
+/**
+ * This is a utility interface that is used by the {@link PersistenceDescriptorParser}.
+ *
+ * This interfaces provides access to a single {@link InputStream} that returns the bytes
+ * of the persistence descriptor, and a String denoting the location of the persistence
+ * descriptor as present in the persistence bundle's Meta-Persistence header. 
+ */
+public interface PersistenceDescriptor {
+
+  /**
+   * Get the location of the persistence descriptor as it appears in the
+   * Meta-Persistence header. The default location should be returned as
+   * "META-INF/persistence.xml".
+   * @return
+   */
+  public String getLocation();
+
+  /**
+   * Get an {@link InputStream} to the persistence descriptor. This method need not return a
+   * new {@link InputStream} each time, and it is undefined for multiple clients to attempt to use
+   * the {@link InputStream} from this {@link PersistenceDescriptor}. It is also undefined for a
+   * client to try to retrieve multiple {@link InputStream} objects from this method.
+   *
+   * @return An {@link InputStream} to the persistence descriptor.
+   */
+  public InputStream getInputStream();
+
+}
\ No newline at end of file

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParser.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParser.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParser.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParser.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,43 @@
+/**
+ * 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.jpa.container.parsing;
+
+import java.util.Collection;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A utility service for parsing JPA persistence descriptors 
+ */
+public interface PersistenceDescriptorParser {
+
+  /**
+   * Parse the supplied {@link PersistenceDescriptor} 
+   * 
+   * @param b  The bundle that contains the persistence descriptor
+   * @param descriptor The descriptor
+   * 
+   * @return A collection of {@link ParsedPersistenceUnit}
+   * @throws PersistenceDescriptorParserException  if any error occurs in parsing
+   */
+  public abstract Collection<ParsedPersistenceUnit> parse(Bundle b,
+      PersistenceDescriptor descriptor)
+      throws PersistenceDescriptorParserException;
+
+}
\ No newline at end of file

Added: aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParserException.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParserException.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParserException.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-api/src/main/java/org/apache/aries/jpa/container/parsing/PersistenceDescriptorParserException.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,49 @@
+/*
+ * 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 WARRANTIESOR 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.jpa.container.parsing;
+
+/**
+ * This Exception will be thrown when there was an error parsing a PersistenceDescriptor
+ * It will use the standard chaining mechanism to wrap the Exception thrown by the parser. 
+ */
+public class PersistenceDescriptorParserException extends Exception {
+
+  /**
+   * Construct a PersistenceDescriptorException
+   * @param string 
+   * @param e the exception to wrap
+   */
+  public PersistenceDescriptorParserException(String string, Exception e) {
+    super(string, e);
+  }
+
+  /**
+   * Construct a PersistenceDescriptorException
+   * @param string 
+   */
+  public PersistenceDescriptorParserException(String string) {
+    super(string);
+  }
+  
+  /**
+   * For Serialization
+   */
+  private static final long serialVersionUID = -8960763303021136544L;
+
+}

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/pom.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/pom.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/pom.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,102 @@
+<?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">
+    <parent>
+        <artifactId>jpa</artifactId>
+        <groupId>org.apache.aries.jpa</groupId>
+        <version>0.1-incubating</version>
+    </parent>
+    <name>Aries JPA Container blueprint integration for Aries blueprint</name>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.aries.jpa.blueprint.aries</artifactId>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <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>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_2.0_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.jpa</groupId>
+            <artifactId>org.apache.aries.jpa.api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.testsupport</groupId>
+            <artifactId>org.apache.aries.testsupport.unit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Import-Package>
+                            javax.persistence;version="[1.0.0,3.0.0)",
+                            org.apache.aries.jpa.container.context;version="[0.1.0,1.1.0)",
+                            org.apache.aries.blueprint;version="[0.1.0,1.1.0)",
+                            *
+                        </Import-Package>
+                        <Export-Service>
+                            org.apache.aries.blueprint.NamespaceHandler;osgi.service.blueprint.namespace=http://aries.apache.org/xmlns/jpa/v1.0.0
+                        </Export-Service>
+                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+                        <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Bundle-DocURL</_removeheaders>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/java/org/apache/aries/jpa/blueprint/aries/impl/NSHandler.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/java/org/apache/aries/jpa/blueprint/aries/impl/NSHandler.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/java/org/apache/aries/jpa/blueprint/aries/impl/NSHandler.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/java/org/apache/aries/jpa/blueprint/aries/impl/NSHandler.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,411 @@
+/**
+ * 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.jpa.blueprint.aries.impl;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.persistence.PersistenceUnit;
+
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.aries.blueprint.mutable.MutableRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
+import org.apache.aries.jpa.container.PersistenceUnitConstants;
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.MapEntry;
+import org.osgi.service.blueprint.reflect.MapMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.osgi.service.blueprint.reflect.Target;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class handles the JPA namespace in blueprint xml files, it configures
+ * injection for managed persistence units and managed persistence contexts. The
+ * namespace handler also registers clients of managed persistence contexts with
+ * the {@link GlobalPersistenceManager}.
+ */
+public class NSHandler implements NamespaceHandler {
+    /** Logger */
+    private static final Logger _logger = LoggerFactory
+            .getLogger("org.apache.aries.jpa.blueprint.aries");
+
+    /** The JPA namespace */
+    public static final String NS_URI = "http://aries.apache.org/xmlns/jpa/v1.0.0";
+    /** The standard blueprint namespace */
+    private static final String BLUEPRINT_NS = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
+
+    /**
+     * The element name for an injected persistence unit (see
+     * {@link PersistenceUnit})
+     */
+    private static final String TAG_UNIT = "unit";
+    /**
+     * The element name for an injected persistence context (see
+     * {@link PersistenceContext})
+     */
+    private static final String TAG_CONTEXT = "context";
+    /** The element name for a blueprint map */
+    private static final String TAG_MAP = "map";
+
+    /** The jpa attribute for property injection, provides the injection site */
+    private static final String ATTR_PROPERTY = "property";
+    /** The {@link PersistenceContextType} of a persistence context */
+    private static final String ATTR_TYPE = "type";
+    /** The name of the persistence unit */
+    private static final String ATTR_UNIT_NAME = "unitname";
+    /** The default name to use if no unit name is specified */
+    private static final String DEFAULT_UNIT_NAME = "";
+
+    /** A filter to find persistence units that specify an empty name */
+    public static final String EMPTY_UNIT_NAME_FILTER = "("
+            + PersistenceUnitConstants.EMPTY_PERSISTENCE_UNIT_NAME + "=true)";
+
+    /** The blueprint attribute value to make a bean eager */
+    private static final String ACTIVATION_EAGER = "EAGER";
+    /** The {@link PersistenceManager} to register contexts with */
+    private PersistenceContextProvider manager;
+    /** Used to indicate whether the PersistenceContextProvider is available */
+    private final AtomicBoolean contextsAvailable = new AtomicBoolean();
+    
+    public void setManager(PersistenceContextProvider manager) {
+        this.manager = manager;
+    }
+
+    /**
+     * Called by blueprint when we meet a JPA namespace element
+     */
+    public ComponentMetadata decorate(Node node, ComponentMetadata component,
+            ParserContext context) {
+        // The node should always be an element
+        if (node.getNodeType() != Node.ELEMENT_NODE) {
+            _logger.error("The JPA namespace handler does not understand the DOM node {}.",
+                            new Object[] { node });
+            throw new IllegalArgumentException(node.toString());
+        }
+
+        Element element = (Element) node;
+        // The surrounding component should always be a bean
+        if (!(component instanceof BeanMetadata)) {
+            _logger.error("The JPA namespace should only be used to inject properties into a bean. The surrounding component was {}.",
+                            new Object[] { component });
+            throw new IllegalArgumentException(component.toString());
+        }
+        
+        if (!(component instanceof MutableBeanMetadata)) {
+            _logger.error("The JPA namespace should only be used to inject properties into beans " +
+                            "that implement the MutableBeanMetadata interface. " +
+                            "The surrounding component was {}.", new Object[] { component });
+            throw new IllegalArgumentException(component.toString());
+        }
+
+        MutableBeanMetadata bean = (MutableBeanMetadata) component;
+
+        if (!NS_URI.equals(element.getNamespaceURI())) {
+            _logger
+                    .error(
+                            "The JPA namespace handler should not be called for the namespace {}.",
+                            new Object[] { element.getNamespaceURI() });
+            throw new IllegalArgumentException();
+        }
+
+        if (!TAG_UNIT.equals(element.getLocalName())
+                && !TAG_CONTEXT.equals(element.getLocalName())) {
+            _logger
+                    .error(
+                            "The JPA namespace handler did not recognize the element named {}.",
+                            new Object[] { element.getLocalName() });
+            throw new IllegalArgumentException();
+        }
+
+        // Create an injection point for the JPA resource (a blueprint property)
+        final BeanProperty beanProperty = createInjectMetadata(element,
+                TAG_UNIT.equals(element.getLocalName()), context);
+
+        // If this is a persistence context then register it with the manager
+        if (TAG_CONTEXT.equals(element.getLocalName())) {
+            Bundle client = getBlueprintBundle(context);
+            String unitName = parseUnitName(element);
+
+            if (client != null) {
+                HashMap<String, Object> properties = new HashMap<String, Object>();
+                // Remember to add the PersistenceContextType so that we can create
+                // the correct type of
+                // EntityManager    
+                properties.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE,
+                        parseType(element));
+                properties.putAll(parseJPAProperties(element, context));
+                if(contextsAvailable.get()) {
+                    manager.registerContext(unitName, client, properties);
+                } else {
+                    _logger.warn("The bundle {} is a client of persistence unit {} with properties {}, but no PersistenceContextProvider is available in the runtime. " +
+                    		"The blueprint for this bundle will not start correctly unless the managed persistence context is registered through some other mechanism",
+                    		new Object[] {client.getSymbolicName() + "_" + client.getVersion(), unitName, properties});
+                }
+            } else {
+                _logger.debug("No bundle: this must be a dry, parse only run.");
+            }
+        }
+
+        bean.addProperty(beanProperty);
+        
+        return bean;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Set<Class> getManagedClasses() {
+        // This is a no-op
+        return null;
+    }
+
+    public URL getSchemaLocation(String namespace) {
+        if(NS_URI.equals(namespace))
+            return getClass().getResource("/org/apache/aries/jpa/blueprint/namespace/jpa.xsd");
+        else
+            return null;
+    }
+
+    public Metadata parse(Element element, ParserContext context) {
+        /*
+         * The namespace does not define any top-level elements, so we should
+         * never get here. In case we do -> explode.
+         */
+        _logger.error("The JPA namespace handler was called to parse a top level element.");
+        throw new UnsupportedOperationException();
+    }
+    
+    /**
+     * Called when a {@link PersistenceContextProvider} is available
+     * @param ref
+     */
+    public void contextAvailable(ServiceReference ref) {
+        boolean log = contextsAvailable.compareAndSet(false, true);
+      
+        if(log && _logger.isDebugEnabled())
+            _logger.debug("Managed persistence context support is now available for use with the Aries Blueprint container");
+    }
+
+    /**
+     * Called when a {@link PersistenceContextProvider} is no longer available
+     * @param ref
+     */
+    public void contextUnavailable(ServiceReference ref) {
+        contextsAvailable.set(false);
+        _logger.warn("Managed persistence context support is no longer available for use with the Aries Blueprint container");
+    }
+    
+    /**
+     * Create a BeanProperty that will inject a JPA resource into a bean
+     * 
+     * @param element
+     *            The element being parsed
+     * @param isPersistenceUnit
+     *            true if this is a persistence unit
+     * @param ctx
+     *            The current parser context
+     * @return
+     */
+    private BeanProperty createInjectMetadata(Element element,
+            boolean isPersistenceUnit, ParserContext ctx) {
+        String unitName = parseUnitName(element);
+        final String property = element.getAttribute(ATTR_PROPERTY);
+
+        if (_logger.isDebugEnabled()) {
+            if (isPersistenceUnit)
+                _logger.debug("Creating blueprint injection metadata to inject the unit {} into bean property {}",
+                                new Object[] { unitName, property });
+            else
+                _logger.debug("Creating blueprint injection metadata to inject the context {} into bean property {}",
+                                new Object[] { unitName, property });
+        }
+
+        // Create a service reference for the EMF (it is an EMF for persistence
+        // contexts and units)
+        final MutableReferenceMetadata refMetadata = (MutableReferenceMetadata) ctx
+                .createMetadata(ReferenceMetadata.class);
+        refMetadata.setActivation(ACTIVATION_EAGER.equalsIgnoreCase(ctx
+                .getDefaultActivation()) ? ReferenceMetadata.ACTIVATION_EAGER
+                : ReferenceMetadata.ACTIVATION_LAZY);
+        refMetadata.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
+        refMetadata.setInterface(EntityManagerFactory.class.getName());
+
+        // Pick the right EMF by looking for the presence, or absence, of the
+        // PROXY_FACTORY service property
+        StringBuilder filter = new StringBuilder("(&");
+        // Persistence units do not have the property, persistence contexts do
+        if (isPersistenceUnit)
+            filter.append("(!(").append(PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE)
+            .append("=*))");
+        else
+            filter.append("(").append(PersistenceContextProvider.PROXY_FACTORY_EMF_ATTRIBUTE)
+                    .append("=*)");
+
+        // Add the empty name filter if necessary
+        if (!"".equals(unitName))
+            filter.append("(" + PersistenceUnitConstants.OSGI_UNIT_NAME + "="
+                    + unitName + ")");
+        else
+            filter.append(EMPTY_UNIT_NAME_FILTER);
+
+        filter.append(")");
+
+        refMetadata.setFilter(filter.toString());
+        refMetadata.setTimeout(Integer.parseInt(ctx.getDefaultTimeout()));
+        refMetadata.setDependsOn((List<String>) Collections.EMPTY_LIST);
+        refMetadata.setId(ctx.generateId());
+
+        // Finally, if this is a persistence context we need to create the
+        // entity manager as the Target
+        final Metadata target = isPersistenceUnit ? refMetadata
+                : createInjectionBeanMetedata(ctx, refMetadata);
+
+        return new BeanProperty() {
+            public Metadata getValue() {
+                return target;
+            }
+
+            public String getName() {
+                return property;
+            }
+        };
+    }
+
+    /**
+     * This method turns a persistence context factory into an
+     * {@link EntityManager} using blueprint factories
+     * 
+     * @param ctx
+     *            the {@link ParserContext}
+     * @param factory
+     *            the reference bean for the persistence context factory
+     * @return
+     */
+    private Metadata createInjectionBeanMetedata(ParserContext ctx,
+            ReferenceMetadata factory) {
+
+        if (_logger.isDebugEnabled())
+            _logger.debug("Creating a managed persistence context definition for injection");
+
+        // Register the factory bean, and then create an entitymanager from it
+        ctx.getComponentDefinitionRegistry().registerComponentDefinition(
+                factory);
+
+        MutableBeanMetadata meta = (MutableBeanMetadata) ctx
+                .createMetadata(BeanMetadata.class);
+        MutableRefMetadata ref = (MutableRefMetadata) ctx
+                .createMetadata(RefMetadata.class);
+        ref.setComponentId(factory.getId());
+        meta.setFactoryComponent(ref);
+        meta.setActivation(factory.getActivation());
+        meta.setFactoryMethod("createEntityManager");
+        meta.setScope(BeanMetadata.SCOPE_PROTOTYPE);
+        meta.setDestroyMethod("internalClose");
+
+        return meta;
+    }
+
+    /**
+     * Get hold of the blueprint bundle using the built in components
+     * 
+     * @param context
+     * @return
+     */
+    private Bundle getBlueprintBundle(ParserContext context) {
+        PassThroughMetadata metadata = (PassThroughMetadata) context
+                .getComponentDefinitionRegistry().getComponentDefinition(
+                        "blueprintBundle");
+
+        Bundle result = null;
+        if (metadata != null) {
+            result = (Bundle) metadata.getObject();
+        }
+
+        return result;
+    }
+
+    private PersistenceContextType parseType(Element element) {
+        if (element.hasAttribute(ATTR_TYPE))
+            return PersistenceContextType.valueOf(element
+                    .getAttribute(ATTR_TYPE));
+        else
+            return PersistenceContextType.TRANSACTION;
+    }
+
+    private String parseUnitName(Element element) {
+        return element.hasAttribute(ATTR_UNIT_NAME) ? element
+                .getAttribute(ATTR_UNIT_NAME) : DEFAULT_UNIT_NAME;
+    }
+
+    /**
+     * Parse any properties for creating the persistence context
+     * 
+     * @param element
+     * @param context
+     * @return
+     */
+    private Map<String, Object> parseJPAProperties(Element element,
+            ParserContext context) {
+        Map<String, Object> result = new HashMap<String, Object>();
+        NodeList ns = element.getElementsByTagNameNS(BLUEPRINT_NS, TAG_MAP);
+        // Use the parser context to parse the map for us
+        for (int i = 0; i < ns.getLength(); i++) {
+            MapMetadata metadata = context.parseElement(MapMetadata.class,
+                    null, (Element) ns.item(i));
+            for (MapEntry entry : (List<MapEntry>) metadata.getEntries()) {
+                if (entry.getKey() instanceof ValueMetadata
+                        && entry.getValue() instanceof ValueMetadata) {
+                    ValueMetadata key = (ValueMetadata) entry.getKey();
+                    ValueMetadata value = (ValueMetadata) entry.getValue();
+
+                    result.put(key.getStringValue(), value.getStringValue());
+                } else {
+                    _logger.error("There was a problem parsing a map of JPA properties");
+                    throw new UnsupportedOperationException();
+                }
+            }
+        }
+
+        return result;
+    }
+}

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/OSGI-INF/blueprint/jpa.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/OSGI-INF/blueprint/jpa.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/OSGI-INF/blueprint/jpa.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/OSGI-INF/blueprint/jpa.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,40 @@
+<?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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+            
+  <service ref="namespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
+    <service-properties>
+      <entry key="osgi.service.blueprint.namespace" 
+             value="http://aries.apache.org/xmlns/jpa/v1.0.0"/>
+    </service-properties>
+  </service>
+  
+  <bean id="namespaceHandler" class="org.apache.aries.jpa.blueprint.aries.impl.NSHandler">
+    <property name="manager" ref="persistenceContextProvider" />
+  </bean>
+  
+  <reference id="persistenceContextProvider" availability="optional"
+       interface="org.apache.aries.jpa.container.context.PersistenceContextProvider">
+    <reference-listener ref="namespaceHandler" bind-method="contextAvailable" 
+            unbind-method="contextUnavailable"/>
+  </reference>
+</blueprint>
\ No newline at end of file

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/org/apache/aries/jpa/blueprint/namespace/jpa.xsd
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/org/apache/aries/jpa/blueprint/namespace/jpa.xsd?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/org/apache/aries/jpa/blueprint/namespace/jpa.xsd (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/main/resources/org/apache/aries/jpa/blueprint/namespace/jpa.xsd Sun Feb 27 18:08:10 2011
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+    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://aries.apache.org/xmlns/jpa/v1.0.0"
+            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:osgi="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            targetNamespace="http://aries.apache.org/xmlns/jpa/v1.0.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            version="1.0.0">
+
+    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0"/>
+
+  <xsd:element name="context" type="TcontextType" />
+  <xsd:element name="unit" type="TunitType" />
+  
+  <xsd:complexType name="TcontextType">
+    <xsd:sequence>
+      <xsd:element name="map" type="osgi:Tmap" minOccurs="0" maxOccurs="1" />
+    </xsd:sequence>
+    <xsd:attribute name="property" type="xsd:string" use="required" />
+    <xsd:attribute name="unitname" type="xsd:string" use="optional" />
+    <xsd:attribute name="type" type="TcontextScopeType" use="optional" />
+  </xsd:complexType>
+
+  <xsd:complexType name="TunitType">
+    <xsd:attribute name="property" type="xsd:string" use="required" />
+    <xsd:attribute name="unitname" type="xsd:string" use="optional" />
+  </xsd:complexType>
+
+   <xsd:simpleType name="TcontextScopeType">
+        <xsd:restriction base="xsd:token">
+            <xsd:enumeration value="TRANSACTION"/>
+            <xsd:enumeration value="EXTENDED"/>
+        </xsd:restriction>
+   </xsd:simpleType>
+
+</xsd:schema>
+  

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/java/org/apache/aries/jpa/blueprint/aries/test/NSHandlerTest.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/java/org/apache/aries/jpa/blueprint/aries/test/NSHandlerTest.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/java/org/apache/aries/jpa/blueprint/aries/test/NSHandlerTest.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/java/org/apache/aries/jpa/blueprint/aries/test/NSHandlerTest.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,296 @@
+/**
+ * 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.jpa.blueprint.aries.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContextType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.container.Parser;
+import org.apache.aries.blueprint.reflect.BeanMetadataImpl;
+import org.apache.aries.blueprint.reflect.RefMetadataImpl;
+import org.apache.aries.blueprint.reflect.ReferenceMetadataImpl;
+import org.apache.aries.jpa.blueprint.aries.impl.NSHandler;
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.apache.aries.unittest.mocks.MethodCall;
+import org.apache.aries.unittest.mocks.Skeleton;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class NSHandlerTest {
+  private Element root;
+  private NSHandler sut;
+  private PersistenceContextProvider manager;
+  private ParserContext parserCtx;
+  private Bundle clientBundle;
+  private List<ComponentMetadata> registeredComponents = new ArrayList<ComponentMetadata>();
+  
+  @Before
+  public void setup() throws Exception {
+    registeredComponents.clear();
+    
+    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+    factory.setNamespaceAware(true);
+    DocumentBuilder builder = factory.newDocumentBuilder();
+    Document doc = builder.parse(getClass().getClassLoader().getResourceAsStream("jpa.xml"));
+    root = doc.getDocumentElement();
+    
+    sut = new NSHandler();
+    manager = Skeleton.newMock(PersistenceContextProvider.class);
+    sut.setManager(manager);
+    sut.contextAvailable(null);
+    
+    clientBundle = Skeleton.newMock(Bundle.class);
+        
+    ComponentDefinitionRegistry registry = Skeleton.newMock(new ComponentDefinitionRegistryMock(), 
+        ComponentDefinitionRegistry.class);
+    
+    parserCtx = Skeleton.newMock(new ParserContextMock(), ParserContext.class);
+    Skeleton.getSkeleton(parserCtx).setReturnValue(
+        new MethodCall(ParserContext.class,"getComponentDefinitionRegistry"), registry);
+    Skeleton.getSkeleton(parserCtx).setReturnValue(
+        new MethodCall(ParserContext.class, "getDefaultActivation"), "eager");
+    Skeleton.getSkeleton(parserCtx).setReturnValue(
+        new MethodCall(ParserContext.class, "getDefaultTimeout"), "5000");
+  }
+  
+  private static class ParserContextMock {
+    public<T> T parseElement(Class<T> type, ComponentMetadata enclosingComponent, Element element) {
+      return new Parser().parseElement(type, enclosingComponent, element);
+    }
+    
+    public<T extends Metadata> T createMetadata(Class<T> clazz) {
+      if (clazz.isAssignableFrom(ReferenceMetadata.class))
+        return clazz.cast(new ReferenceMetadataImpl());
+      else if (clazz.isAssignableFrom(RefMetadata.class))
+        return clazz.cast(new RefMetadataImpl());
+      else
+        return clazz.cast(new BeanMetadataImpl());
+    }
+  }
+  
+  private class ComponentDefinitionRegistryMock {
+    public ComponentMetadata getComponentDefinition(String id) {
+      PassThroughMetadata bundleMeta =  Skeleton.newMock(PassThroughMetadata.class);
+      Skeleton.getSkeleton(bundleMeta).setReturnValue(
+          new MethodCall(PassThroughMetadata.class, "getObject"), clientBundle);
+      return bundleMeta;
+    }
+    
+    public void registerComponentDefinition(ComponentMetadata component) {
+      registeredComponents.add(component);
+    }
+  }
+  
+  @Test
+  public void testUnit() {
+    Element e = getTestElement("unit");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanProperty property = (BeanProperty) bean.getProperties().get(0);
+    ReferenceMetadata reference = (ReferenceMetadata) property.getValue();
+    
+    assertEquals("emf", property.getName());
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))(osgi.unit.name=myUnit))", reference.getFilter());
+    
+    Skeleton.getSkeleton(manager).assertSkeletonNotCalled();
+    
+    assertTrue(registeredComponents.isEmpty());
+  }
+  
+  @Test
+  public void testUnitNoName() {
+    Element e = getTestElement("unitNoName");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanProperty property = (BeanProperty) bean.getProperties().get(0);
+    ReferenceMetadata reference = (ReferenceMetadata) property.getValue();
+    
+    assertEquals("emf2", property.getName());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))"+NSHandler.EMPTY_UNIT_NAME_FILTER+")", 
+        reference.getFilter());
+
+    assertTrue(registeredComponents.isEmpty());
+  }
+  
+  @Test
+  public void testEmptyUnitName() {
+    Element e = getTestElement("emptyUnitName");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanProperty property = (BeanProperty) bean.getProperties().get(0);
+    ReferenceMetadata reference = (ReferenceMetadata) property.getValue();
+    
+    assertEquals("emf3", property.getName());
+    assertEquals("(&(!(org.apache.aries.jpa.proxy.factory=*))"+NSHandler.EMPTY_UNIT_NAME_FILTER+")",
+        reference.getFilter());
+    
+    assertTrue(registeredComponents.isEmpty());
+  }
+  
+  @Test 
+  public void testBeanMetadataOverwrite() {
+    Element e = getTestElement("unit");
+    BeanMetadataImpl oldBean = new BeanMetadataImpl();
+    oldBean.setId("myid");
+    oldBean.setProperties(Arrays.asList(Skeleton.newMock(BeanProperty.class)));
+    
+    BeanMetadata bean = (BeanMetadata) sut.decorate(e, oldBean, parserCtx);
+
+    assertEquals("myid", bean.getId());
+    assertEquals(2, bean.getProperties().size());
+    
+    assertTrue(registeredComponents.isEmpty());
+  }
+
+  @Test
+  public void testDefaultContext() {
+    Element e = getTestElement("context");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanMetadata innerBean = (BeanMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+
+    assertEquals("createEntityManager", innerBean.getFactoryMethod());
+    assertEquals("internalClose", innerBean.getDestroyMethod());
+
+    assertEquals(1, registeredComponents.size());
+    ReferenceMetadata reference = (ReferenceMetadata) registeredComponents.get(0);
+    
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(org.apache.aries.jpa.proxy.factory=*)(osgi.unit.name=myUnit))", reference.getFilter());
+    
+    Map<String,Object> props = new HashMap<String, Object>();
+    props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.TRANSACTION);
+    Skeleton.getSkeleton(manager).assertCalled(
+        new MethodCall(PersistenceContextProvider.class, "registerContext", "myUnit", clientBundle, props));
+  }
+  
+  @Test
+  public void testContextNoPersistenceContextProvider() {
+    
+    sut.contextUnavailable(null);
+    Element e = getTestElement("context");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanMetadata innerBean = (BeanMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+
+    assertEquals("createEntityManager", innerBean.getFactoryMethod());
+    assertEquals("internalClose", innerBean.getDestroyMethod());
+
+    assertEquals(1, registeredComponents.size());
+    ReferenceMetadata reference = (ReferenceMetadata) registeredComponents.get(0);
+    
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(org.apache.aries.jpa.proxy.factory=*)(osgi.unit.name=myUnit))", reference.getFilter());
+    
+    Map<String,Object> props = new HashMap<String, Object>();
+    props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.TRANSACTION);
+    Skeleton.getSkeleton(manager).assertNotCalled(
+        new MethodCall(PersistenceContextProvider.class, "registerContext", String.class, Bundle.class, Map.class));
+  }
+  
+  @Test
+  public void testContextWithProps() {
+    Element e = getTestElement("contextWithProps");
+    BeanMetadata bean = 
+      (BeanMetadata) sut.decorate(e, new BeanMetadataImpl(), parserCtx);
+    BeanMetadata innerBean = (BeanMetadata) ((BeanProperty) bean.getProperties().get(0)).getValue();
+    
+    assertEquals("createEntityManager", innerBean.getFactoryMethod());
+    
+    assertEquals(1, registeredComponents.size());
+    ReferenceMetadata reference = (ReferenceMetadata) registeredComponents.get(0);
+    
+    assertEquals(EntityManagerFactory.class.getName(), reference.getInterface());
+    assertEquals("(&(org.apache.aries.jpa.proxy.factory=*)"+NSHandler.EMPTY_UNIT_NAME_FILTER+")", 
+        reference.getFilter());
+    
+    Map<String,Object> props = new HashMap<String, Object>();
+    props.put(PersistenceContextProvider.PERSISTENCE_CONTEXT_TYPE, PersistenceContextType.EXTENDED);
+    props.put("one", "eins");
+    props.put("two", "zwo");
+    Skeleton.getSkeleton(manager).assertCalled(
+        new MethodCall(PersistenceContextProvider.class, "registerContext", "", clientBundle, props));    
+  }
+  
+  @Test
+  public void testNoMoreProxying() {
+      Element e = getTestElement("contextWithProps");
+      BeanMetadata input = new BeanMetadataImpl();
+      Object output = sut.decorate(e, input, parserCtx);
+      assertTrue(input == output);
+  }
+  
+  private Element getTestElement(String beanName) {
+    NodeList ns = root.getElementsByTagName("bean");
+    
+    Element bean = null;
+    for (int i=0; i<ns.getLength(); i++) {
+      bean = (Element) ns.item(i);
+      if (beanName.equals(bean.getAttribute("id")))
+        break;
+    }
+    
+    ns = bean.getChildNodes();
+    for (int i=0; i<ns.getLength(); i++) {
+      if (ns.item(i).getNodeType() == Node.ELEMENT_NODE) {
+        Element e = (Element) ns.item(i);
+        if (NSHandler.NS_URI.equals(e.getNamespaceURI()))
+          return e;
+      }
+    }
+    
+    return null;
+  }
+  
+  @Test
+  public void testgetSchemaLocation()
+  {
+    assertNotNull("No schema found", sut.getSchemaLocation(NSHandler.NS_URI));
+    assertNull("No schema expected", sut.getSchemaLocation("http://maven.apache.org/POM/4.0.0"));
+  }
+}

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/resources/jpa.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/resources/jpa.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/resources/jpa.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-aries/src/test/resources/jpa.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,46 @@
+<?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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
+  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0">
+
+  <bean id="unit">
+    <jpa:unit property="emf" unitname="myUnit" />
+  </bean>
+  
+  <bean id="unitNoName">
+    <jpa:unit property="emf2" />
+  </bean>
+  
+  <bean id="emptyUnitName">
+    <jpa:unit property="emf3" unitname="" />
+  </bean>
+  
+  <bean id="context">
+    <jpa:context property="em" unitname="myUnit"/>
+  </bean>
+  
+  <bean id="contextWithProps">
+    <jpa:context property="em" type="EXTENDED">
+      <map>
+        <entry key="one" value="eins" />
+        <entry key="two" value="zwo" />
+      </map>
+    </jpa:context>
+  </bean>
+
+</blueprint>
\ No newline at end of file

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/pom.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/pom.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/pom.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,62 @@
+<?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">
+    <parent>
+        <artifactId>jpa</artifactId>
+        <groupId>org.apache.aries.jpa</groupId>
+        <version>0.1-incubating</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.aries.jpa.blueprint.itest.bundle</artifactId>
+    <packaging>bundle</packaging>
+    <name>Test Bundle for Aries JPA Blueprint iTests</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_2.0_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Import-Package>
+                            javax.persistence;version="[1.0.0,3.0.0)",
+                            *
+                        </Import-Package>
+						<Export-Package>
+                            org.apache.aries.jpa.blueprint.itest*;version="${pom.version}",
+						</Export-Package>
+                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+                        <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Bundle-DocURL</_removeheaders>
+                        <Meta-Persistence>OSGI-INF/persistence/persistence.xml</Meta-Persistence>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/JPATestBean.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/JPATestBean.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/JPATestBean.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/JPATestBean.java Sun Feb 27 18:08:10 2011
@@ -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 WARRANTIESOR 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.jpa.blueprint.itest;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityManager;
+
+public class JPATestBean {
+  
+  private EntityManagerFactory persistenceUnit;
+  
+  private EntityManager persistenceContext;
+  
+  public void setPersistenceUnit(EntityManagerFactory emf) {
+    persistenceUnit = emf;
+  }
+
+  public void setPersistenceContext(EntityManager em) {
+    persistenceContext = em;
+  }
+  
+  /**
+   * @return True if we sucessfully called a method on the EMF
+   */
+  public boolean pUnitAvailable() {
+    persistenceUnit.isOpen();
+    return true;
+  }
+  
+  /**
+   * @return True if we sucessfully called a method on the EM
+   */
+  public boolean pContextAvailable() {
+    persistenceContext.isOpen();
+    return true;
+  }
+  
+}

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/entities/Car.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/entities/Car.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/entities/Car.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/java/org/apache/aries/jpa/blueprint/itest/entities/Car.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,68 @@
+/*
+ * 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 WARRANTIESOR 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.jpa.blueprint.itest.entities;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Car {
+  @Id
+  private String numberPlate;
+  
+  private String colour;
+  
+  private int engineSize;
+  
+  private int numberOfSeats;
+
+  public String getNumberPlate() {
+    return numberPlate;
+  }
+
+  public void setNumberPlate(String numberPlate) {
+    this.numberPlate = numberPlate;
+  }
+
+  public String getColour() {
+    return colour;
+  }
+
+  public void setColour(String colour) {
+    this.colour = colour;
+  }
+
+  public int getEngineSize() {
+    return engineSize;
+  }
+
+  public void setEngineSize(int engineSize) {
+    this.engineSize = engineSize;
+  }
+
+  public int getNumberOfSeats() {
+    return numberOfSeats;
+  }
+
+  public void setNumberOfSeats(int numberOfSeats) {
+    this.numberOfSeats = numberOfSeats;
+  }
+  
+  
+}

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/injection.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/injection.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/injection.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/blueprint/injection.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,32 @@
+<?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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+  
+  <service interface="org.apache.aries.jpa.blueprint.itest.JPATestBean">
+    <bean class="org.apache.aries.jpa.blueprint.itest.JPATestBean">
+      <jpa:unit property="persistenceUnit" unitname="test-unit"/>
+      <jpa:context property="persistenceContext" unitname="test-context"/>
+    </bean>
+  </service>
+            
+</blueprint>
\ No newline at end of file

Added: aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/persistence/persistence.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/persistence/persistence.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/persistence/persistence.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-blueprint-testbundle/src/main/resources/OSGI-INF/persistence/persistence.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,35 @@
+<?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.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+   version="1.0">
+  
+  <persistence-unit name="test-unit" transaction-type="JTA">
+    <description>Test persistence unit for the JPA Blueprint integration iTest</description>
+    <class>org.apache.aries.jpa.blueprint.itest.entities.Car</class>
+    <exclude-unlisted-classes/>
+  </persistence-unit>
+  <persistence-unit name="test-context" transaction-type="JTA">
+    <description>Test persistence context for the JPA Integration iTest</description>
+    <class>org.apache.aries.jpa.blueprint.itest.entities.Car</class>
+    <exclude-unlisted-classes/>
+  </persistence-unit>
+</persistence>

Added: aries/tags/jpa-0.1-incubating/jpa-container-context/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-container-context/pom.xml?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-container-context/pom.xml (added)
+++ aries/tags/jpa-0.1-incubating/jpa-container-context/pom.xml Sun Feb 27 18:08:10 2011
@@ -0,0 +1,107 @@
+<?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">
+    <parent>
+        <artifactId>jpa</artifactId>
+        <groupId>org.apache.aries.jpa</groupId>
+        <version>0.1-incubating</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.aries.jpa.container.context</artifactId>
+    <name>Aries JPA Container Managed Contexts</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <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>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_2.0_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jta_1.1_spec</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.jpa</groupId>
+            <artifactId>org.apache.aries.jpa.api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.testsupport</groupId>
+            <artifactId>org.apache.aries.testsupport.unit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Import-Package>
+                            javax.persistence;version="[1.0.0,2.1.0)",
+                            javax.persistence.criteria;version="[1.1.0,2.1.0)";resolution:=optional,
+                            javax.persistence.metamodel;version="[1.1.0,2.1.0)";resolution:=optional,
+                            org.apache.aries.jpa.container.context;version="[0.1.0,1.1.0)",
+                            *
+                        </Import-Package>
+                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+                        <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Bundle-DocURL</_removeheaders>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Added: aries/tags/jpa-0.1-incubating/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
URL: http://svn.apache.org/viewvc/aries/tags/jpa-0.1-incubating/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java?rev=1075099&view=auto
==============================================================================
--- aries/tags/jpa-0.1-incubating/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java (added)
+++ aries/tags/jpa-0.1-incubating/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java Sun Feb 27 18:08:10 2011
@@ -0,0 +1,165 @@
+/**
+ * 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.jpa.container.context.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.jpa.container.context.PersistenceContextProvider;
+import org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class that coordinates PersistenceContextManagers across multiple (nested) OSGi frameworks.
+ */
+public class GlobalPersistenceManager implements PersistenceContextProvider, SynchronousBundleListener {
+  /** Logger */
+  private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
+  
+  private JTAPersistenceContextRegistry registry;
+  
+  /** 
+   *    The list of persistence context managers. Each is valid for exactly one framework
+   *    as identified by the respective system bundle. This allows us to work properly in 
+   *    a multi (nested) framework environment without using the (deprecated) CompositeBundle API.
+   */
+  private Map<Bundle, PersistenceContextManager> managers = 
+    new HashMap<Bundle, PersistenceContextManager>();
+  
+  /**
+   *  This Map relates persistence context clients to persistence contexts. A bundle may be
+   *  a client of more than one persistence context. 
+   */
+  private Map<Bundle, Set<String>> persistenceContexts = 
+    new HashMap<Bundle, Set<String>>();
+  
+
+  public void setRegistry(JTAPersistenceContextRegistry registry) {
+    this.registry = registry;
+  }
+  
+  public void registerContext(String unitName, Bundle client, HashMap<String, Object> properties) {
+    if (_logger.isDebugEnabled()) {
+      _logger.debug("Registering bundle {} as a client of persistence unit {} with properties {}.", 
+          new Object[] {client.getSymbolicName() + "_" + client.getVersion(), unitName, properties});
+    }
+    
+    if(!!!registry.jtaIntegrationAvailable())
+      _logger.warn("No JTA integration is currently available. The managed persistence context {} used by the bundle {} will operate " +
+      		"with no transaction context and be read only until a JTA Transaction Services implementation is available in" +
+      		"the runtime", new Object[] {unitName, client.getSymbolicName() + "_" + client.getVersion()});
+    
+    //Find the framework for this bundle (we may be in a composite)
+    Bundle frameworkBundle = client.getBundleContext().getBundle(0);
+    PersistenceContextManager manager = null;
+    boolean newManager = false;
+    
+    //Synchronize to update internal state atomically
+    synchronized (this) {
+      //If we already have a manager use it
+      if (managers.containsKey(frameworkBundle)) {
+        manager = managers.get(frameworkBundle);
+      } else {
+        if (_logger.isDebugEnabled()) {
+          _logger.debug("No existing manager for the framework with identity hash code {}. Creating a new one.",
+              new Object[] {System.identityHashCode(frameworkBundle)});
+        }
+        manager = new PersistenceContextManager(frameworkBundle.getBundleContext(), registry);
+        managers.put(frameworkBundle, manager);
+        //Remember to listen to this new framework so that we know when bundles are starting/stopping
+        frameworkBundle.getBundleContext().addBundleListener(this);
+        
+        newManager = true;
+      }
+      
+      //Register the new bundle as a client
+      if (!persistenceContexts.containsKey(client)) {
+        persistenceContexts.put(client, new HashSet<String>());
+      }
+      
+      persistenceContexts.get(client).add(unitName);
+    }
+    //Remember to start the manager if it was new. This MUST occur outside the synchronized block.
+    if (newManager)
+      manager.open();
+    
+    manager.registerContext(unitName, client, properties);
+  }
+
+  /**
+   * This method is used to track the lifecycle of bundles inside composites
+   */
+  public void bundleChanged(BundleEvent event) {
+    Bundle bundle = event.getBundle();
+    
+    //We only care about bundles stopping
+    if (event.getType() == BundleEvent.STOPPING) {
+      Set<String> contextsToBeRemoved = Collections.emptySet();
+      Bundle frameworkBundle = bundle.getBundleContext().getBundle(0);
+      PersistenceContextManager manager = null;
+      boolean removeManager = false;
+      
+      //Synchronize to update internal state atomically
+      synchronized (this) {
+        if (persistenceContexts.containsKey(bundle)) {
+          //This is a client, find the contexts to remove
+          contextsToBeRemoved = persistenceContexts.remove(bundle);
+          
+          if (_logger.isDebugEnabled()) {
+            _logger.debug("The bundle {} in framework {}, which is a client of the persistence contexts {} is stopping.",
+                new Object[] {bundle.getSymbolicName() + "_" + bundle.getVersion(), 
+                System.identityHashCode(frameworkBundle), contextsToBeRemoved});
+          }
+          
+          manager = managers.get(frameworkBundle);
+          if (manager == null) {
+              _logger.error("There was no context manager for framework {}. This should never happen");
+            throw new IllegalStateException();
+          }
+        } else if (managers.containsKey(bundle)) {
+          //The framework is stopping, tidy up the manager
+          if (_logger.isDebugEnabled()) {
+            _logger.debug("The framework {} is stopping.",
+                new Object[] {bundle.getSymbolicName() + "_" + bundle.getVersion(), 
+                System.identityHashCode(frameworkBundle)});
+          }
+          removeManager = true;
+          manager = managers.remove(bundle);
+          bundle.getBundleContext().removeBundleListener(this);
+        }
+      }
+      
+      if (removeManager) {
+        manager.close();
+      } else {
+        for (String context : contextsToBeRemoved) {
+          manager.unregisterContext(context, bundle);
+        }
+      }
+    }
+  }
+
+}