/** * Licensed 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.deephacks.confit; import com.google.common.base.Optional; import org.deephacks.confit.query.ConfigQuery; import org.deephacks.confit.query.ConfigQueryBuilder; import java.util.List; /** * <p> * Central interface for providing configuration to applications. * <p> * Applications use this interface for registering {@link Config} classes with this runtime context * in order to make them visible and available for provisioning in an administrative context. * Configuration instances should not be cached, unless applications have very specific caching needs. * </p> * * @author Kristoffer Sjogren */ public abstract class ConfigContext { private static final String CORE_IMPL = "org.deephacks.confit.internal.core.config.ConfigCoreContext"; private static ConfigContext ctx; protected ConfigContext() { // only core should implement this class if (!getClass().getName().equals(CORE_IMPL)) { throw new IllegalArgumentException("Only RuntimeCoreContext is allowed to" + "implement this interface."); } } /** * Get the context for fetching configurable application instances. * * @return the context. */ public static synchronized ConfigContext lookup() { if (ctx != null) { return ctx; } try { ctx = (ConfigContext) Class.forName(CORE_IMPL).newInstance(); } catch (Exception e) { throw new RuntimeException(e); } return ctx; } /** * Register a configurable class and make it visible and available for provisioning in * an administrative context. * * <p> * Registering classes are optional, and if not, remember that classes will not be visible * for administrative provisioning until they have been touched from this context. * </p> * * <p> * If the same class is registered multiple times, the former class is replaced or upgraded. * <p> * Be cautious of registering a new version of a class that is not compatible with * earlier versions of data of the same class. * </p> * * @param configurable {@link Config} classes. */ public abstract void register(final Class<?>... configurable); /** * Remove a configurable class. This will make the schema unavailable for provisioning * in an administrative context. * <p> * Data will never be removed when unregistering a configurable class. * </p> * * @param configurable {@link Config} classes. */ public abstract void unregister(final Class<?>... configurable); /** * Get a singleton instance. * * <p> * Trying to read instances that are not singletons will result in an error. * </p> * * @param configurable {@link Config} class. * @return The lookup instance of {@link Config} T class. */ public abstract <T> T get(final Class<T> configurable); /** * Get a specific instance with respect to its {@link Id}. All references * and properties will be traversed and fetched eagerly. * * @param id of the instance as specified by {@link Id}. * * @param configurable {@link Config} class. * @return an instance of {@link Config} T class. */ public abstract <T> Optional<T> get(final String id, final Class<T> configurable); /** * List instances of the the provided type. All references and properties * will be traversed and fetched eagerly. * * @param configurable {@link Config} class. * @return list instances of {@link Config} T class. */ public abstract <T> List<T> list(final Class<T> configurable); /** * Create a new query used for retrieving configurable instances using * flexible composition of <tt>Criterion</tt> objects. * * In order to use queries, a cache manager must be available and each field that * is queried must be {@link Index} annotated. * * This feature is currently experimental and must be turned on by setting * 'confit.query.enabled' to true. * * @see {@link ConfigQueryBuilder} * * @param configurable {@link Config} class. * @param <T> Configurable type * @return Used for composing a query in conjuction with {@link ConfigQueryBuilder}. */ public abstract <T> ConfigQuery<T> newQuery(final Class<T> configurable); /** * Register an observer. * * @param observer class of the observer. */ public abstract void registerObserver(ConfigObserver observer); }