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 }