blob: 9ee53794abf644ec1889c02605f9eb4496739870 [file] [log] [blame]
/*****************************************************************
* 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);
}
}