| /***************************************************************** |
| * 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; |
| |
| import org.apache.cayenne.DataChannel; |
| import org.apache.cayenne.ObjectContext; |
| import org.apache.cayenne.di.BeforeScopeEnd; |
| import org.apache.cayenne.di.DIBootstrap; |
| import org.apache.cayenne.di.Injector; |
| import org.apache.cayenne.di.Module; |
| |
| /** |
| * A superclass of various Cayenne runtime stacks. A Runtime is the main access |
| * point to Cayenne for a user application. It provides a default Cayenne |
| * configuration as well as a way to customize this configuration via a built-in |
| * dependency injection (DI) container. In fact implementation-wise, Runtime |
| * object is just a convenience thin wrapper around a DI {@link Injector}. |
| * |
| * @since 3.1 |
| */ |
| public abstract class CayenneRuntime { |
| |
| /** |
| * A holder of an Injector bound to the current thread. Used mainly to allow |
| * serializable contexts to attach to correct Cayenne stack on |
| * deserialization. |
| * |
| * @since 3.1 |
| */ |
| protected static final ThreadLocal<Injector> threadInjector = new ThreadLocal<Injector>(); |
| |
| /** |
| * Binds a DI {@link Injector} bound to the current thread. It is primarily |
| * intended for deserialization of ObjectContexts. |
| * |
| * @since 3.1 |
| */ |
| public static void bindThreadInjector(Injector injector) { |
| threadInjector.set(injector); |
| } |
| |
| /** |
| * Returns the {@link Injector} bound to the current thread. Will return |
| * null if none is bound. |
| * |
| * @since 3.1 |
| */ |
| public static Injector getThreadInjector() { |
| return threadInjector.get(); |
| } |
| |
| protected Injector injector; |
| protected Module module; |
| |
| /** |
| * Creates a CayenneRuntime with configuration based on the supplied array |
| * of DI modules. |
| */ |
| public CayenneRuntime(Module module) { |
| this.module = module; |
| this.injector = DIBootstrap.createInjector(module); |
| } |
| |
| /** |
| * Returns an array of modules used to initialize this runtime. |
| * |
| * @deprecated since 4.0. We only keep one module now, so use |
| * {@link #getModule()}. |
| */ |
| @Deprecated |
| public Module[] getModules() { |
| return new Module[] { module }; |
| } |
| |
| /** |
| * |
| * Returns the module used to initialize this runtime. |
| * |
| * @since 4.0 |
| */ |
| public Module getModule() { |
| return module; |
| } |
| |
| /** |
| * Returns DI injector used by this runtime. |
| */ |
| public Injector getInjector() { |
| return injector; |
| } |
| |
| /** |
| * Shuts down the DI injector of this runtime, giving all services that need |
| * to release some resources a chance to do that. |
| */ |
| // the following annotation is for environments that manage CayenneRuntimes |
| // within |
| // another DI registry (e.g. unit tests) |
| @BeforeScopeEnd |
| public void shutdown() { |
| injector.shutdown(); |
| } |
| |
| /** |
| * Returns the runtime {@link DataChannel}. |
| */ |
| public DataChannel getChannel() { |
| return injector.getInstance(DataChannel.class); |
| } |
| |
| /** |
| * Returns a new ObjectContext instance based on the runtime's main |
| * DataChannel. |
| * |
| * @since 4.0 |
| */ |
| public ObjectContext newContext() { |
| return injector.getInstance(ObjectContextFactory.class).createContext(); |
| } |
| |
| /** |
| * Returns a new ObjectContext which is a child of the specified |
| * DataChannel. This method is used for creation of nested ObjectContexts, |
| * with parent ObjectContext passed as an argument. |
| * |
| * @since 4.0 |
| */ |
| public ObjectContext newContext(DataChannel parentChannel) { |
| return injector.getInstance(ObjectContextFactory.class).createContext(parentChannel); |
| } |
| |
| /** |
| * @deprecated since 3.1 use better named {@link #newContext()} instead. |
| */ |
| @Deprecated |
| public ObjectContext getContext() { |
| return newContext(); |
| } |
| |
| /** |
| * @deprecated since 3.1 use better named {@link #newContext(DataChannel)} |
| * instead. |
| */ |
| @Deprecated |
| public ObjectContext getContext(DataChannel parentChannel) { |
| return newContext(parentChannel); |
| } |
| } |