001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.xbean.recipe;
019
020 import java.util.LinkedList;
021 import java.util.List;
022 import java.util.Map;
023
024 public abstract class ExecutionContext {
025 private static final ThreadLocal<ExecutionContext> context = new ThreadLocal<ExecutionContext>();
026
027 public static boolean isContextSet() {
028 return context.get() != null;
029 }
030
031 public static ExecutionContext getContext() {
032 ExecutionContext executionContext = context.get();
033 if (executionContext == null) {
034 throw new IllegalStateException("Execution context has not been set");
035 }
036 return executionContext;
037 }
038
039 public static ExecutionContext setContext(ExecutionContext newContext) {
040 ExecutionContext oldContext = context.get();
041 context.set(newContext);
042 return oldContext;
043 }
044
045 /**
046 * Adds a recipe to the top of the execution stack. If the recipe is already on
047 * the stack, a CircularDependencyException is thrown.
048 * @param recipe the recipe to add to the stack
049 * @throws CircularDependencyException if the recipe is already on the stack
050 */
051 public abstract void push(Recipe recipe) throws CircularDependencyException;
052
053 /**
054 * Removes the top recipe from the execution stack.
055 * @return the top recipe on the stack
056 */
057 public abstract Recipe pop();
058
059 /**
060 * Gets a snapshot of the current execution stack. The returned list is
061 * a snapshot so any modification of the returned list does not modify
062 * the stack contained in this object.
063 * @return a snapshot of the current execution stack
064 */
065 public abstract LinkedList<Recipe> getStack();
066
067 /**
068 * Does this context contain a object with the specified name.
069 *
070 * @param name the unique name of the object instance
071 * @return true if this context contain a object with the specified name
072 */
073 public abstract boolean containsObject(String name);
074
075 /**
076 * Gets the object or recipe with the specified name from the repository.
077 *
078 * @param name the unique name of the object instance
079 * @return the object instance, a recipe to build the object or null
080 */
081 public abstract Object getObject(String name);
082
083 /**
084 * Add an object to the repository.
085 *
086 * @param name the unique name of the object instance
087 * @param object the object instance
088 * @throws ConstructionException if another object instance is already registered with the name
089 */
090 public abstract void addObject(String name, Object object);
091
092 /**
093 * Adds a reference to an object to this context. If an object is already registered under
094 * the referenced name, the reference will immedately be set. Otherwise, the reference will be set
095 * when an object is added with the referenced name.
096 *
097 * @param reference the reference to set
098 */
099 public abstract void addReference(Reference reference);
100
101 /**
102 * Gets the unresolved references by name.
103 *
104 * @return the unresolved references by name
105 */
106 public abstract Map<String, List<Reference>> getUnresolvedRefs();
107
108 /**
109 * Gets the class loader used for loading of all classes during the
110 * life of this execution context
111 * @return the class loader for loading classes in this context
112 */
113 public abstract ClassLoader getClassLoader();
114 }