Repository: aries-jpa Updated Branches: refs/heads/master 4ce1a5a6a -> 5bb0454e6
Ensure that spec bundles can use the static factory in OSGi Project: http://git-wip-us.apache.org/repos/asf/aries-jpa/repo Commit: http://git-wip-us.apache.org/repos/asf/aries-jpa/commit/5bb0454e Tree: http://git-wip-us.apache.org/repos/asf/aries-jpa/tree/5bb0454e Diff: http://git-wip-us.apache.org/repos/asf/aries-jpa/diff/5bb0454e Branch: refs/heads/master Commit: 5bb0454e679c22c8b4da69d6a2394287ecf2c940 Parents: 4ce1a5a Author: timothyjward <[email protected]> Authored: Mon Jun 5 19:53:47 2017 +0100 Committer: timothyjward <[email protected]> Committed: Mon Jun 5 19:53:47 2017 +0100 ---------------------------------------------------------------------- javax-persistence/2_0/osgi.bnd | 14 +-- javax-persistence/2_0/pom.xml | 5 + .../persistence/AriesJPASpecActivator.java | 70 +++++++++++ .../persistence/EMFBuilderServiceResolver.java | 103 ++++++++++++++++ javax-persistence/2_1/osgi.bnd | 14 +-- javax-persistence/2_1/pom.xml | 5 + .../persistence/AriesJPASpecActivator.java | 71 +++++++++++ .../persistence/EMFBuilderServiceResolver.java | 117 +++++++++++++++++++ 8 files changed, 385 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_0/osgi.bnd ---------------------------------------------------------------------- diff --git a/javax-persistence/2_0/osgi.bnd b/javax-persistence/2_0/osgi.bnd index 5af8309..536e09f 100644 --- a/javax-persistence/2_0/osgi.bnd +++ b/javax-persistence/2_0/osgi.bnd @@ -19,7 +19,7 @@ Provide-Capability:\ # Make the API substitutable with unversioned imports and a contract requirement Import-Package: \ - !org.apache.geronimo.osgi.registry.api,\ + !org.apache.geronimo.*,\ javax.persistence;version=0.0.0,\ javax.persistence.criteria;version=0.0.0,\ javax.persistence.metamodel;version=0.0.0,\ @@ -27,12 +27,12 @@ Import-Package: \ * Require-Capability:\ - osgi.contract;filter:="(&(osgi.contract=JavaJPA)(version=2)(!(version>=2.1)))",\ - -Private-Package:\ - org.apache.geronimo.osgi.locator,\ - org.apache.geronimo.specs.jpa + osgi.contract;filter:="(&(osgi.contract=JavaJPA)(version=2)(!(version>=2.1)))" + +Private-Package: \ + org.apache.aries.jpa.javax.persistence,\ + org.apache.geronimo.osgi.locator -Bundle-Activator: org.apache.geronimo.specs.jpa.PersistenceActivator +Bundle-Activator: org.apache.aries.jpa.javax.persistence.AriesJPASpecActivator Bundle-SymbolicName: org.apache.aries.jpa.javax.persistence_2.0 http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_0/pom.xml ---------------------------------------------------------------------- diff --git a/javax-persistence/2_0/pom.xml b/javax-persistence/2_0/pom.xml index a889e17..17d38c1 100644 --- a/javax-persistence/2_0/pom.xml +++ b/javax-persistence/2_0/pom.xml @@ -39,6 +39,11 @@ <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> <version>1.1</version> http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java ---------------------------------------------------------------------- diff --git a/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java b/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java new file mode 100644 index 0000000..27896a2 --- /dev/null +++ b/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java @@ -0,0 +1,70 @@ +/* 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.javax.persistence; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceProviderResolver; +import javax.persistence.spi.PersistenceProviderResolverHolder; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +public class AriesJPASpecActivator implements BundleActivator, PersistenceProviderResolver { + + private ServiceTracker<PersistenceProvider, PersistenceProvider> tracker; + + private EMFBuilderServiceResolver emfResolver; + + @Override + public void start(BundleContext context) throws Exception { + emfResolver = new EMFBuilderServiceResolver(context); + + tracker = new ServiceTracker<PersistenceProvider, PersistenceProvider>(context, + PersistenceProvider.class, null); + tracker.open(); + + PersistenceProviderResolverHolder.setPersistenceProviderResolver(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + PersistenceProviderResolverHolder.setPersistenceProviderResolver(null); + tracker.close(); + emfResolver.close(); + } + + @Override + public List<PersistenceProvider> getPersistenceProviders() { + Collection<PersistenceProvider> services = tracker.getTracked().values(); + + List<PersistenceProvider> providers = new ArrayList<PersistenceProvider>(services.size() + 1); + + providers.add(emfResolver); + providers.addAll(services); + + return providers; + } + + @Override + public void clearCachedProviders() { + // This is a no-op + } +} http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java ---------------------------------------------------------------------- diff --git a/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java b/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java new file mode 100644 index 0000000..29391cd --- /dev/null +++ b/javax-persistence/2_0/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java @@ -0,0 +1,103 @@ +/* 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.javax.persistence; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Map.Entry; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceException; +import javax.persistence.spi.LoadState; +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.ProviderUtil; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +public class EMFBuilderServiceResolver implements PersistenceProvider, ProviderUtil { + + + + private final ServiceTracker<Object, Object> tracker; + + public EMFBuilderServiceResolver(BundleContext context) { + tracker = new ServiceTracker<Object, Object>(context, + "org.osgi.service.jpa.EntityManagerFactoryBuilder", null); + + tracker.open(); + } + + public void close() { + tracker.close(); + } + + /** + * This method looks for a matching EntityManagerFactoryBuilder service to create the + * EMF with. + */ + @Override + public EntityManagerFactory createEntityManagerFactory(String emName, @SuppressWarnings("rawtypes") Map map) { + for (Entry<ServiceReference<Object>, Object> e : tracker.getTracked().entrySet()) { + String serviceUnitName = String.valueOf(e.getKey().getProperty("osgi.unit.name")); + + if(serviceUnitName.equals(emName)) { + try { + Object emfBuilder = e.getValue(); + Method m = emfBuilder.getClass().getMethod("createEntityManagerFactory", Map.class); + return (EntityManagerFactory) m.invoke(emfBuilder, map); + } catch (Exception ex) { + throw new PersistenceException("Failed to create an EntityManagerFactory for unit " + + emName, ex); + } + } + } + return null; + } + + /** + * This method is not intended to be used, as this PersistenceProvider is internal to + * the Spec API for supporting static factory usage (see OSGi JPA spec 127.7.1) + */ + @Override + public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, @SuppressWarnings("rawtypes") Map map) { + return null; + } + + @Override + public ProviderUtil getProviderUtil() { + return this; + } + + @Override + public LoadState isLoadedWithoutReference(Object entity, String attributeName) { + return LoadState.UNKNOWN; + } + + @Override + public LoadState isLoadedWithReference(Object entity, String attributeName) { + return LoadState.UNKNOWN; + } + + @Override + public LoadState isLoaded(Object entity) { + return LoadState.UNKNOWN; + } + +} http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_1/osgi.bnd ---------------------------------------------------------------------- diff --git a/javax-persistence/2_1/osgi.bnd b/javax-persistence/2_1/osgi.bnd index 21dab65..5f2c551 100644 --- a/javax-persistence/2_1/osgi.bnd +++ b/javax-persistence/2_1/osgi.bnd @@ -19,7 +19,7 @@ Provide-Capability:\ # Make the API substitutable with unversioned imports and a contract requirement Import-Package: \ - !org.apache.geronimo.osgi.registry.api,\ + !org.apache.geronimo.*,\ javax.persistence;version=0.0.0,\ javax.persistence.criteria;version=0.0.0,\ javax.persistence.metamodel;version=0.0.0,\ @@ -27,12 +27,12 @@ Import-Package: \ * Require-Capability:\ - osgi.contract;filter:="(&(osgi.contract=JavaJPA)(version=2.1)(!(version>=2.2)))",\ - -Private-Package:\ - org.apache.geronimo.osgi.locator,\ - org.apache.geronimo.specs.jpa + osgi.contract;filter:="(&(osgi.contract=JavaJPA)(version=2.1)(!(version>=2.2)))" -Bundle-Activator: org.apache.geronimo.specs.jpa.PersistenceActivator +Private-Package: \ + org.apache.aries.jpa.javax.persistence,\ + org.apache.geronimo.osgi.locator + +Bundle-Activator: org.apache.aries.jpa.javax.persistence.AriesJPASpecActivator Bundle-SymbolicName: org.apache.aries.jpa.javax.persistence_2.1 http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_1/pom.xml ---------------------------------------------------------------------- diff --git a/javax-persistence/2_1/pom.xml b/javax-persistence/2_1/pom.xml index c0957a2..12b9b7a 100644 --- a/javax-persistence/2_1/pom.xml +++ b/javax-persistence/2_1/pom.xml @@ -39,6 +39,11 @@ <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.1_spec</artifactId> <version>1.0-alpha-1</version> http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java ---------------------------------------------------------------------- diff --git a/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java b/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java new file mode 100644 index 0000000..bfcb745 --- /dev/null +++ b/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/AriesJPASpecActivator.java @@ -0,0 +1,71 @@ +/* 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.javax.persistence; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceProviderResolver; +import javax.persistence.spi.PersistenceProviderResolverHolder; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +public class AriesJPASpecActivator implements BundleActivator, PersistenceProviderResolver { + + private ServiceTracker<PersistenceProvider, PersistenceProvider> tracker; + + private EMFBuilderServiceResolver emfResolver; + + @Override + public void start(BundleContext context) throws Exception { + emfResolver = new EMFBuilderServiceResolver(context); + + tracker = new ServiceTracker<PersistenceProvider, PersistenceProvider>(context, + PersistenceProvider.class, null); + tracker.open(); + + PersistenceProviderResolverHolder.setPersistenceProviderResolver(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + PersistenceProviderResolverHolder.setPersistenceProviderResolver(null); + tracker.close(); + emfResolver.close(); + } + + @Override + public List<PersistenceProvider> getPersistenceProviders() { + Collection<PersistenceProvider> services = tracker.getTracked().values(); + + List<PersistenceProvider> providers = new ArrayList<PersistenceProvider>(services.size() + 1); + + providers.add(emfResolver); + providers.addAll(services); + + return providers; + } + + @Override + public void clearCachedProviders() { + // This is a no-op + } +} http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/5bb0454e/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java ---------------------------------------------------------------------- diff --git a/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java b/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java new file mode 100644 index 0000000..69d7ed4 --- /dev/null +++ b/javax-persistence/2_1/src/main/java/org/apache/aries/jpa/javax/persistence/EMFBuilderServiceResolver.java @@ -0,0 +1,117 @@ +/* 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.javax.persistence; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Map.Entry; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceException; +import javax.persistence.spi.LoadState; +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.ProviderUtil; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +public class EMFBuilderServiceResolver implements PersistenceProvider, ProviderUtil { + + private final ServiceTracker<Object, Object> tracker; + + public EMFBuilderServiceResolver(BundleContext context) { + tracker = new ServiceTracker<Object, Object>(context, + "org.osgi.service.jpa.EntityManagerFactoryBuilder", null); + + tracker.open(); + } + + public void close() { + tracker.close(); + } + + /** + * This method looks for a matching EntityManagerFactoryBuilder service to create the + * EMF with. + */ + @Override + public EntityManagerFactory createEntityManagerFactory(String emName, @SuppressWarnings("rawtypes") Map map) { + for (Entry<ServiceReference<Object>, Object> e : tracker.getTracked().entrySet()) { + String serviceUnitName = String.valueOf(e.getKey().getProperty("osgi.unit.name")); + + if(serviceUnitName.equals(emName)) { + try { + Object emfBuilder = e.getValue(); + Method m = emfBuilder.getClass().getMethod("createEntityManagerFactory", Map.class); + return (EntityManagerFactory) m.invoke(emfBuilder, map); + } catch (Exception ex) { + throw new PersistenceException("Failed to create an EntityManagerFactory for unit " + + emName, ex); + } + } + } + return null; + } + + /** + * This method is not intended to be used, as this PersistenceProvider is internal to + * the Spec API for supporting static factory usage (see OSGi JPA spec 127.7.1) + */ + @Override + public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, @SuppressWarnings("rawtypes") Map map) { + return null; + } + + @Override + public ProviderUtil getProviderUtil() { + return this; + } + + @Override + public LoadState isLoadedWithoutReference(Object entity, String attributeName) { + return LoadState.UNKNOWN; + } + + @Override + public LoadState isLoadedWithReference(Object entity, String attributeName) { + return LoadState.UNKNOWN; + } + + @Override + public LoadState isLoaded(Object entity) { + return LoadState.UNKNOWN; + } + + /** + * This operation is not provided for OSGi JPA Static Factory access + */ + @Override + public void generateSchema(PersistenceUnitInfo arg0, @SuppressWarnings("rawtypes") Map arg1) { + return; + } + + /** + * This operation is not provided for OSGi JPA Static Factory access + */ + @Override + public boolean generateSchema(String arg0, @SuppressWarnings("rawtypes") Map arg1) { + return false; + } + +}
