CAY-2372 Extracted OSGI module from server module
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/b3a065f2 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/b3a065f2 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/b3a065f2 Branch: refs/heads/master Commit: b3a065f27bc27f0e2f30a9518cd7c31388c9a305 Parents: 066d176 Author: Maxim Petrusevich <maks1...@gmail.com> Authored: Tue Oct 31 08:55:24 2017 +0300 Committer: Arseni Bulatski <ancars...@gmail.com> Committed: Wed Nov 22 10:10:19 2017 +0300 ---------------------------------------------------------------------- cayenne-osgi/pom.xml | 35 ++++++++ .../cayenne/osgi/OsgiClassLoaderManager.java | 75 +++++++++++++++++ .../cayenne/osgi/OsgiDataDomainProvider.java | 78 ++++++++++++++++++ .../org/apache/cayenne/osgi/OsgiModule.java | 61 ++++++++++++++ .../apache/cayenne/osgi/OsgiModuleBuilder.java | 86 ++++++++++++++++++++ .../osgi/OsgiClassLoaderManagerTest.java | 59 ++++++++++++++ .../osgi/OsgiClassLoaderManager.java | 74 ----------------- .../osgi/OsgiDataDomainProvider.java | 77 ------------------ .../cayenne/configuration/osgi/OsgiModule.java | 60 -------------- .../configuration/osgi/OsgiModuleBuilder.java | 85 ------------------- .../osgi/OsgiClassLoaderManagerTest.java | 59 -------------- pom.xml | 4 + 12 files changed, 398 insertions(+), 355 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/pom.xml ---------------------------------------------------------------------- diff --git a/cayenne-osgi/pom.xml b/cayenne-osgi/pom.xml new file mode 100644 index 0000000..724df7e --- /dev/null +++ b/cayenne-osgi/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>cayenne-parent</artifactId> + <groupId>org.apache.cayenne</groupId> + <version>4.1.M2-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>cayenne-osgi</artifactId> + + <dependencies> + <dependency> + <groupId>org.apache.cayenne</groupId> + <artifactId>cayenne-server</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- TEST DEPENDENCIES --> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiClassLoaderManager.java ---------------------------------------------------------------------- diff --git a/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiClassLoaderManager.java b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiClassLoaderManager.java new file mode 100644 index 0000000..eeb7cf9 --- /dev/null +++ b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiClassLoaderManager.java @@ -0,0 +1,75 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.osgi; + +import java.util.Map; + +import org.apache.cayenne.di.ClassLoaderManager; +import org.apache.cayenne.di.Injector; + +/** + * @since 4.0 + */ +public class OsgiClassLoaderManager implements ClassLoaderManager { + + private static final String CAYENNE_PACKAGE = "org/apache/cayenne"; + private static final String CAYENNE_DI_PACKAGE_SUFFIX = "/di"; + + private ClassLoader applicationClassLoader; + private ClassLoader cayenneServerClassLoader; + private ClassLoader cayenneDiClassLoader; + private Map<String, ClassLoader> perResourceClassLoaders; + + public OsgiClassLoaderManager(ClassLoader applicationClassLoader, Map<String, ClassLoader> perResourceClassLoaders) { + this.applicationClassLoader = applicationClassLoader; + this.cayenneDiClassLoader = Injector.class.getClassLoader(); + this.cayenneServerClassLoader = OsgiClassLoaderManager.class.getClassLoader(); + this.perResourceClassLoaders = perResourceClassLoaders; + } + + @Override + public ClassLoader getClassLoader(String resourceName) { + if (resourceName == null || resourceName.length() < 2) { + return resourceClassLoader(resourceName); + } + + String normalizedName = resourceName.charAt(0) == '/' ? resourceName.substring(1) : resourceName; + if (normalizedName.startsWith(CAYENNE_PACKAGE)) { + + return (normalizedName.substring(CAYENNE_PACKAGE.length()).startsWith(CAYENNE_DI_PACKAGE_SUFFIX)) ? cayenneDiClassLoader() + : cayenneServerClassLoader(); + } + + return resourceClassLoader(resourceName); + } + + protected ClassLoader resourceClassLoader(String resourceName) { + ClassLoader cl = perResourceClassLoaders.get(resourceName); + return cl != null ? cl : applicationClassLoader; + } + + protected ClassLoader cayenneDiClassLoader() { + return cayenneDiClassLoader; + } + + protected ClassLoader cayenneServerClassLoader() { + return cayenneServerClassLoader; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiDataDomainProvider.java ---------------------------------------------------------------------- diff --git a/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiDataDomainProvider.java b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiDataDomainProvider.java new file mode 100644 index 0000000..2981102 --- /dev/null +++ b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiDataDomainProvider.java @@ -0,0 +1,78 @@ +/***************************************************************** + * 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.cayenne.osgi; + +import org.apache.cayenne.ConfigurationException; +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.configuration.server.DataDomainProvider; +import org.apache.cayenne.di.ClassLoaderManager; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.map.EntityResolver; +import org.apache.cayenne.map.ObjEntity; + +/** + * @since 4.0 + */ +// TODO: this is really a hack until we can have fully injectable class loading +// at the EntityResolver level per CAY-1887 +public class OsgiDataDomainProvider extends DataDomainProvider { + + private ClassLoaderManager classLoaderManager; + + public OsgiDataDomainProvider(@Inject ClassLoaderManager classLoaderManager) { + this.classLoaderManager = classLoaderManager; + } + + @Override + public DataDomain get() throws ConfigurationException { + + // here goes the class loading hack, temporarily setting application + // bundle ClassLoader to be a thread ClassLoader for runtime to start. + + Thread thread = Thread.currentThread(); + ClassLoader activeCl = thread.getContextClassLoader(); + try { + + // using fake package name... as long as it is not + // org.apache.cayenne, this do the right trick + thread.setContextClassLoader(classLoaderManager.getClassLoader("com/")); + + DataDomain domain = super.get(); + EntityResolver entityResolver = domain.getEntityResolver(); + for (ObjEntity e : entityResolver.getObjEntities()) { + + // it is not enough to just call 'getObjectClass()' on + // ClassDescriptor - there's an optimization that prevents full + // descriptor resolving... so calling some other method... + entityResolver.getClassDescriptor(e.getName()).getProperty("__dummy__"); + entityResolver.getCallbackRegistry(); + } + + // this triggers callbacks initialization using thread class loader + entityResolver.getCallbackRegistry(); + + return domain; + + } finally { + thread.setContextClassLoader(activeCl); + } + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModule.java ---------------------------------------------------------------------- diff --git a/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModule.java b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModule.java new file mode 100644 index 0000000..7dd40d3 --- /dev/null +++ b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModule.java @@ -0,0 +1,61 @@ +/***************************************************************** + * 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.cayenne.osgi; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.di.Binder; +import org.apache.cayenne.di.ClassLoaderManager; +import org.apache.cayenne.di.Module; + +/** + * A DI module that helps to bootstrap Cayenne in OSGi environment. + * + * @since 4.0 + */ +public class OsgiModule implements Module { + + private Class<?> typeFromProjectBundle; + private Map<String, ClassLoader> perTypeClassLoaders; + + OsgiModule() { + this.perTypeClassLoaders = new HashMap<>(); + } + + void setTypeFromProjectBundle(Class<?> typeFromProjectBundle) { + this.typeFromProjectBundle = typeFromProjectBundle; + } + + void putClassLoader(String type, ClassLoader classLoader) { + perTypeClassLoaders.put(type, classLoader); + } + + @Override + public void configure(Binder binder) { + binder.bind(ClassLoaderManager.class).toInstance(createClassLoaderManager()); + binder.bind(DataDomain.class).toProvider(OsgiDataDomainProvider.class); + } + + private ClassLoaderManager createClassLoaderManager() { + return new OsgiClassLoaderManager(typeFromProjectBundle.getClassLoader(), perTypeClassLoaders); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModuleBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModuleBuilder.java b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModuleBuilder.java new file mode 100644 index 0000000..cb0377b --- /dev/null +++ b/cayenne-osgi/src/main/java/org/apache/cayenne/osgi/OsgiModuleBuilder.java @@ -0,0 +1,86 @@ +/***************************************************************** + * 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.cayenne.osgi; + +import java.sql.Driver; + +import org.apache.cayenne.di.Module; + +/** + * A builder of a DI module that helps to bootstrap Cayenne in OSGi environment. + * + * @since 4.0 + */ +public class OsgiModuleBuilder { + + private OsgiModule module; + + public static OsgiModuleBuilder forProject(Class<?> typeFromProjectBundle) { + + if (typeFromProjectBundle == null) { + throw new NullPointerException("Null 'typeFromProjectBundle'"); + } + + return new OsgiModuleBuilder(typeFromProjectBundle); + } + + private OsgiModuleBuilder(Class<?> typeFromProjectBundle) { + this.module = new OsgiModule(); + module.setTypeFromProjectBundle(typeFromProjectBundle); + } + + /** + * Registers a JDBC driver class used by Cayenne. This is an optional piece + * of information used by Cayenne to find JDBC driver in case of Cayenne + * managed DataSource. E.g. don't use this when you are using a JNDI + * DataSource. + */ + public OsgiModuleBuilder withDriver(Class<? extends Driver> driverType) { + return withType(driverType); + } + + /** + * Registers an arbitrary Java class. If Cayenne tries to load it via + * reflection later on, it will be using ClassLoader attached to the class + * passed to this method. + */ + public OsgiModuleBuilder withType(Class<?> type) { + module.putClassLoader(type.getName(), type.getClassLoader()); + return this; + } + + /** + * Registers an arbitrary Java class. If Cayenne tries to load it via + * reflection later on, it will be using ClassLoader attached to the class + * passed to this method. + */ + public OsgiModuleBuilder withTypes(Class<?>... types) { + if (types != null) { + for (Class<?> type : types) { + module.putClassLoader(type.getName(), type.getClassLoader()); + } + } + return this; + } + + public Module module() { + return module; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-osgi/src/test/java/org/apache/cayenne/osgi/OsgiClassLoaderManagerTest.java ---------------------------------------------------------------------- diff --git a/cayenne-osgi/src/test/java/org/apache/cayenne/osgi/OsgiClassLoaderManagerTest.java b/cayenne-osgi/src/test/java/org/apache/cayenne/osgi/OsgiClassLoaderManagerTest.java new file mode 100644 index 0000000..b3d267d --- /dev/null +++ b/cayenne-osgi/src/test/java/org/apache/cayenne/osgi/OsgiClassLoaderManagerTest.java @@ -0,0 +1,59 @@ +/***************************************************************** + * 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.cayenne.osgi; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.Collections; + +public class OsgiClassLoaderManagerTest { + + @Test + public void testGetClassLoader() { + + final ClassLoader appCl = Mockito.mock(ClassLoader.class); + final ClassLoader diCl = Mockito.mock(ClassLoader.class); + final ClassLoader serverCl = Mockito.mock(ClassLoader.class); + + OsgiClassLoaderManager manager = new OsgiClassLoaderManager(appCl, Collections.<String, ClassLoader> emptyMap()) { + @Override + protected ClassLoader cayenneDiClassLoader() { + return diCl; + } + + @Override + protected ClassLoader cayenneServerClassLoader() { + return serverCl; + } + }; + + Assert.assertSame(appCl, manager.getClassLoader(null)); + Assert.assertSame(appCl, manager.getClassLoader("")); + Assert.assertSame(appCl, manager.getClassLoader("org/example/test")); + Assert.assertSame(appCl, manager.getClassLoader("/org/example/test")); + Assert.assertSame(serverCl, manager.getClassLoader("/org/apache/cayenne/access/DataContext.class")); + Assert.assertSame(diCl, manager.getClassLoader("/org/apache/cayenne/di/Injector.class")); + Assert.assertSame(diCl, manager.getClassLoader("org/apache/cayenne/di/Injector.class")); + + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManager.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManager.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManager.java deleted file mode 100644 index a1b9714..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManager.java +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************** - * 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.cayenne.configuration.osgi; - -import java.util.Map; - -import org.apache.cayenne.di.ClassLoaderManager; -import org.apache.cayenne.di.Injector; - -/** - * @since 4.0 - */ -public class OsgiClassLoaderManager implements ClassLoaderManager { - - private static final String CAYENNE_PACKAGE = "org/apache/cayenne"; - private static final String CAYENNE_DI_PACKAGE_SUFFIX = "/di"; - - private ClassLoader applicationClassLoader; - private ClassLoader cayenneServerClassLoader; - private ClassLoader cayenneDiClassLoader; - private Map<String, ClassLoader> perResourceClassLoaders; - - public OsgiClassLoaderManager(ClassLoader applicationClassLoader, Map<String, ClassLoader> perResourceClassLoaders) { - this.applicationClassLoader = applicationClassLoader; - this.cayenneDiClassLoader = Injector.class.getClassLoader(); - this.cayenneServerClassLoader = OsgiClassLoaderManager.class.getClassLoader(); - this.perResourceClassLoaders = perResourceClassLoaders; - } - - @Override - public ClassLoader getClassLoader(String resourceName) { - if (resourceName == null || resourceName.length() < 2) { - return resourceClassLoader(resourceName); - } - - String normalizedName = resourceName.charAt(0) == '/' ? resourceName.substring(1) : resourceName; - if (normalizedName.startsWith(CAYENNE_PACKAGE)) { - - return (normalizedName.substring(CAYENNE_PACKAGE.length()).startsWith(CAYENNE_DI_PACKAGE_SUFFIX)) ? cayenneDiClassLoader() - : cayenneServerClassLoader(); - } - - return resourceClassLoader(resourceName); - } - - protected ClassLoader resourceClassLoader(String resourceName) { - ClassLoader cl = perResourceClassLoaders.get(resourceName); - return cl != null ? cl : applicationClassLoader; - } - - protected ClassLoader cayenneDiClassLoader() { - return cayenneDiClassLoader; - } - - protected ClassLoader cayenneServerClassLoader() { - return cayenneServerClassLoader; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java deleted file mode 100644 index fafe4d5..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiDataDomainProvider.java +++ /dev/null @@ -1,77 +0,0 @@ -/***************************************************************** - * 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.cayenne.configuration.osgi; - -import org.apache.cayenne.ConfigurationException; -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.configuration.server.DataDomainProvider; -import org.apache.cayenne.di.ClassLoaderManager; -import org.apache.cayenne.di.Inject; -import org.apache.cayenne.map.EntityResolver; -import org.apache.cayenne.map.ObjEntity; - -/** - * @since 4.0 - */ -// TODO: this is really a hack until we can have fully injectable class loading -// at the EntityResolver level per CAY-1887 -public class OsgiDataDomainProvider extends DataDomainProvider { - - private ClassLoaderManager classLoaderManager; - - public OsgiDataDomainProvider(@Inject ClassLoaderManager classLoaderManager) { - this.classLoaderManager = classLoaderManager; - } - - @Override - public DataDomain get() throws ConfigurationException { - - // here goes the class loading hack, temporarily setting application - // bundle ClassLoader to be a thread ClassLoader for runtime to start. - - Thread thread = Thread.currentThread(); - ClassLoader activeCl = thread.getContextClassLoader(); - try { - - // using fake package name... as long as it is not - // org.apache.cayenne, this do the right trick - thread.setContextClassLoader(classLoaderManager.getClassLoader("com/")); - - DataDomain domain = super.get(); - EntityResolver entityResolver = domain.getEntityResolver(); - for (ObjEntity e : entityResolver.getObjEntities()) { - - // it is not enough to just call 'getObjectClass()' on - // ClassDescriptor - there's an optimization that prevents full - // descriptor resolving... so calling some other method... - entityResolver.getClassDescriptor(e.getName()).getProperty("__dummy__"); - entityResolver.getCallbackRegistry(); - } - - // this triggers callbacks initialization using thread class loader - entityResolver.getCallbackRegistry(); - - return domain; - - } finally { - thread.setContextClassLoader(activeCl); - } - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java deleted file mode 100644 index 7b1a602..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModule.java +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************** - * 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.cayenne.configuration.osgi; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.di.Binder; -import org.apache.cayenne.di.ClassLoaderManager; -import org.apache.cayenne.di.Module; - -/** - * A DI module that helps to bootstrap Cayenne in OSGi environment. - * - * @since 4.0 - */ -public class OsgiModule implements Module { - - private Class<?> typeFromProjectBundle; - private Map<String, ClassLoader> perTypeClassLoaders; - - OsgiModule() { - this.perTypeClassLoaders = new HashMap<>(); - } - - void setTypeFromProjectBundle(Class<?> typeFromProjectBundle) { - this.typeFromProjectBundle = typeFromProjectBundle; - } - - void putClassLoader(String type, ClassLoader classLoader) { - perTypeClassLoaders.put(type, classLoader); - } - - @Override - public void configure(Binder binder) { - binder.bind(ClassLoaderManager.class).toInstance(createClassLoaderManager()); - binder.bind(DataDomain.class).toProvider(OsgiDataDomainProvider.class); - } - - private ClassLoaderManager createClassLoaderManager() { - return new OsgiClassLoaderManager(typeFromProjectBundle.getClassLoader(), perTypeClassLoaders); - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModuleBuilder.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModuleBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModuleBuilder.java deleted file mode 100644 index 481f220..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/osgi/OsgiModuleBuilder.java +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************** - * 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.cayenne.configuration.osgi; - -import java.sql.Driver; - -import org.apache.cayenne.di.Module; - -/** - * A builder of a DI module that helps to bootstrap Cayenne in OSGi environment. - * - * @since 4.0 - */ -public class OsgiModuleBuilder { - - private OsgiModule module; - - public static OsgiModuleBuilder forProject(Class<?> typeFromProjectBundle) { - - if (typeFromProjectBundle == null) { - throw new NullPointerException("Null 'typeFromProjectBundle'"); - } - - return new OsgiModuleBuilder(typeFromProjectBundle); - } - - private OsgiModuleBuilder(Class<?> typeFromProjectBundle) { - this.module = new OsgiModule(); - module.setTypeFromProjectBundle(typeFromProjectBundle); - } - - /** - * Registers a JDBC driver class used by Cayenne. This is an optional piece - * of information used by Cayenne to find JDBC driver in case of Cayenne - * managed DataSource. E.g. don't use this when you are using a JNDI - * DataSource. - */ - public OsgiModuleBuilder withDriver(Class<? extends Driver> driverType) { - return withType(driverType); - } - - /** - * Registers an arbitrary Java class. If Cayenne tries to load it via - * reflection later on, it will be using ClassLoader attached to the class - * passed to this method. - */ - public OsgiModuleBuilder withType(Class<?> type) { - module.putClassLoader(type.getName(), type.getClassLoader()); - return this; - } - - /** - * Registers an arbitrary Java class. If Cayenne tries to load it via - * reflection later on, it will be using ClassLoader attached to the class - * passed to this method. - */ - public OsgiModuleBuilder withTypes(Class<?>... types) { - if (types != null) { - for (Class<?> type : types) { - module.putClassLoader(type.getName(), type.getClassLoader()); - } - } - return this; - } - - public Module module() { - return module; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManagerTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManagerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManagerTest.java deleted file mode 100644 index bf06086..0000000 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/osgi/OsgiClassLoaderManagerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************** - * 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.cayenne.configuration.osgi; - -import org.junit.Test; - -import java.util.Collections; - -import static org.junit.Assert.assertSame; -import static org.mockito.Mockito.mock; - -public class OsgiClassLoaderManagerTest { - - @Test - public void testGetClassLoader() { - - final ClassLoader appCl = mock(ClassLoader.class); - final ClassLoader diCl = mock(ClassLoader.class); - final ClassLoader serverCl = mock(ClassLoader.class); - - OsgiClassLoaderManager manager = new OsgiClassLoaderManager(appCl, Collections.<String, ClassLoader> emptyMap()) { - @Override - protected ClassLoader cayenneDiClassLoader() { - return diCl; - } - - @Override - protected ClassLoader cayenneServerClassLoader() { - return serverCl; - } - }; - - assertSame(appCl, manager.getClassLoader(null)); - assertSame(appCl, manager.getClassLoader("")); - assertSame(appCl, manager.getClassLoader("org/example/test")); - assertSame(appCl, manager.getClassLoader("/org/example/test")); - assertSame(serverCl, manager.getClassLoader("/org/apache/cayenne/access/DataContext.class")); - assertSame(diCl, manager.getClassLoader("/org/apache/cayenne/di/Injector.class")); - assertSame(diCl, manager.getClassLoader("org/apache/cayenne/di/Injector.class")); - - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/b3a065f2/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8ac1e2c..b890722 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,11 @@ <module>tutorials</module> <module>docs</module> <module>assembly</module> +<<<<<<< HEAD <module>cayenne-web</module> +======= + <module>cayenne-osgi</module> +>>>>>>> e8768c6e3... CAY-2372 Extracted OSGI module from server module </modules> <issueManagement> <system>jira</system>