package alien4cloud.tosca.parser; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import org.springframework.beans.BeanWrapper; import org.yaml.snakeyaml.nodes.Node; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @Slf4j public class ParsingContextExecution { private final static ThreadLocal<Context> CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); /** * Create a new context from a given file name. */ public static void init() { CONTEXT_THREAD_LOCAL.set(new Context()); } /** * Allow to know if a context is initialized for the current thread. * * @return True if the context is initialized, false if not. */ public static boolean exist() { return CONTEXT_THREAD_LOCAL.get() != null; } /** * Get the current context. * * @return The current context. */ public static Context get() { return CONTEXT_THREAD_LOCAL.get(); } /** * Set an existing context. * * @param context The context to set. */ public static void set(Context context) { CONTEXT_THREAD_LOCAL.set(context); } /** * Set the registry of parsers to use for the parsing. * * @param registry the registry of parsers to use for the parsing. */ public static void setRegistry(Map<String, INodeParser> registry) { CONTEXT_THREAD_LOCAL.get().setRegistry(registry); } /** * Get th name of the file under parsing. * * @return The name of the file under parsing. */ public static String getFileName() { return CONTEXT_THREAD_LOCAL.get().getFileName(); } /** * Get th name of the file under parsing. * * @return The name of the file under parsing. */ public static void setFileName(String fileName) { CONTEXT_THREAD_LOCAL.get().setFileName(fileName); } /** * Get the registry of parsers. * * @return The registry of parsers. */ public static Map<String, INodeParser> getRegistry() { return CONTEXT_THREAD_LOCAL.get().getRegistry(); } /** * Get an identity hashmap parsed object to yaml node. * * @return identity hashmap parsed object to yaml node. */ public static Map<Object, Node> getObjectToNodeMap() { return CONTEXT_THREAD_LOCAL.get().getObjectToNodeMap(); } /** * Set the parent object in the object hierarchy. * * @param parent the parent object in the object hierarchy. */ public static void setParent(Object parent) { CONTEXT_THREAD_LOCAL.get().setParent(parent); } /** * Get the parent object in the object hierarchy. * * @return the parent object in the object hierarchy. */ public static Object getParent() { return CONTEXT_THREAD_LOCAL.get().getParent(); } /** * Set the parent object in the object hierarchy. * * @param parent the parent object in the object hierarchy. */ public static void setParent(Object parent, Object child) { CONTEXT_THREAD_LOCAL.get().getObjectToParentMap().put(child, parent); } /** * Get the parent from the given child object. * * @param child The child object. * @return The parent of the given child. */ public static Object getParent(Object child) { return CONTEXT_THREAD_LOCAL.get().getObjectToParentMap().get(child); } /** * Get the instance of the root object under parsing. * * @return the instance of the root object under parsing. */ public static <T> T getRootObj() { return (T) CONTEXT_THREAD_LOCAL.get().getRoot().getWrappedInstance(); } /** * Get the bean wrapper of the root object under parsing. * * @return the bean wrapper of the root object under parsing. */ public static BeanWrapper getRoot() { return CONTEXT_THREAD_LOCAL.get().getRoot(); } /** * Set the bean wrapper of the root object under parsing. * * @param beanWrapper the bean wrapper of the root object under parsing. */ public static void setRoot(BeanWrapper beanWrapper) { CONTEXT_THREAD_LOCAL.get().setRoot(beanWrapper); } /** * Get the list of parsing errors. * * @return The list of parsing errors. */ public static List<ParsingError> getParsingErrors() { return CONTEXT_THREAD_LOCAL.get().getParsingErrors(); } /** * Get the inner Parsing context that contains the actual resulting bean as well as the list of errors. * * @return the inner Parsing context that contains the actual resulting bean as well as the list of errors. */ public static ParsingContext getParsingContext() { return CONTEXT_THREAD_LOCAL.get().getParsingContext(); } /** * Get the definition version of the archive * * @return the definition version of the archive */ public static String getDefinitionVersion() { return CONTEXT_THREAD_LOCAL.get().getDefinitionVersion(); } /** * Set the definition version of the archive to the context * * @param definitionVersion the definition version to be set */ public static void setDefinitionVersion(String definitionVersion) { CONTEXT_THREAD_LOCAL.get().setDefinitionVersion(definitionVersion); } /** * Destroy the execution context. */ public static void destroy() { CONTEXT_THREAD_LOCAL.remove(); } @Getter @Setter public static class Context { /** The definition version of the archive **/ private String definitionVersion; /** Root node under parsing. */ private BeanWrapper root; /** Eventually, the current node parent object. */ private Object parent; /** Map of parsers by type */ private Map<String, INodeParser> registry; /** Map of all parsed objects and the node from which they where parsed. */ private Map<Object, Node> objectToNodeMap = new IdentityHashMap<>(); /** Map that allows to get the parent object from a given object. */ private Map<Object, Object> objectToParentMap = new IdentityHashMap<>(); /** The parsing context. */ private final ParsingContext parsingContext = new ParsingContext(); public void setFileName(String fileName) { parsingContext.setFileName(fileName); } public String getFileName() { return parsingContext.getFileName(); } public List<ParsingError> getParsingErrors() { return parsingContext.getParsingErrors(); } } }