All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cayenne.configuration.CayenneRuntime Maven / Gradle / Ivy

There is a newer version: 4.2.1
Show newest version
/*****************************************************************
 *   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 java.util.Collection;

import org.apache.cayenne.DataChannel;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.configuration.web.CayenneFilter;
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 threadInjector = new ThreadLocal();

    /**
     * Binds a DI {@link Injector} bound to the current thread. It is primarily intended
     * for deserialization of ObjectContexts.
     * 

* {@link CayenneFilter} will automatically bind the right injector to each request * thread. If you are not using CayenneFilter, your application is responsible for * calling this method at appropriate points of the lifecycle. * * @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[] modules; /** * Internal helper method to add special extra modules in subclass constructors. */ protected static Module[] mergeModules(Module mainModule, Module... extraModules) { if (extraModules == null || extraModules.length == 0) { return new Module[] { mainModule }; } Module[] allModules = new Module[extraModules.length + 1]; allModules[0] = mainModule; System.arraycopy(extraModules, 0, allModules, 1, extraModules.length); return allModules; } /** * Internal helper method to add special extra modules in subclass constructors. */ protected static Module[] mergeModules( Module mainModule, Collection extraModules) { if (extraModules == null || extraModules.isEmpty()) { return new Module[] { mainModule }; } Module[] allModules = new Module[extraModules.size() + 1]; allModules[0] = mainModule; System.arraycopy(extraModules.toArray(), 0, allModules, 1, extraModules.size()); return allModules; } /** * Creates a CayenneRuntime with configuration based on the supplied array of DI * modules. */ public CayenneRuntime(Module... modules) { if (modules == null) { modules = new Module[0]; } this.modules = modules; this.injector = DIBootstrap.createInjector(modules); } /** * Creates a CayenneRuntime with configuration based on the supplied collection of DI * modules. */ public CayenneRuntime(Collection modules) { if (modules == null) { this.modules = new Module[0]; } else { this.modules = modules.toArray(new Module[modules.size()]); } this.injector = DIBootstrap.createInjector(this.modules); } /** * Returns an array of modules used to initialize this runtime. */ public Module[] getModules() { return modules; } /** * 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. */ public ObjectContext getContext() { 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. */ public ObjectContext getContext(DataChannel parentChannel) { return injector.getInstance(ObjectContextFactory.class).createContext( parentChannel); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy