/** * Optimus, framework for Model Transformation * * Copyright (C) 2013 Worldline or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.atos.optimus.m2m.engine.ctxinject.internal; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import net.atos.optimus.m2m.engine.core.transformations.AbstractTransformation; import net.atos.optimus.m2m.engine.core.transformations.ITransformationContext; import net.atos.optimus.m2m.engine.ctxinject.api.ContextParameter; import net.atos.optimus.m2m.engine.ctxinject.api.CustomContextElement; import net.atos.optimus.m2m.engine.ctxinject.api.ObjectContextElement; import net.atos.optimus.m2m.engine.ctxinject.api.ParentContextElement; import net.atos.optimus.m2m.engine.ctxinject.api.RootContextElement; import net.atos.optimus.m2m.engine.ctxinject.exceptions.FieldInjectionException; import net.atos.optimus.m2m.engine.ctxinject.exceptions.FieldUpdateException; import net.atos.optimus.m2m.engine.ctxinject.exceptions.NullInstanceException; import net.atos.optimus.m2m.engine.ctxinject.exceptions.NullValueException; /** * * Implementation of ContextElement injection management. This is implemented as * a singleton and supports caching. * * @author mvanbesien * */ public enum ContextElementManager { /** * Instance */ INSTANCE; /** * Cache implementation */ private Map<Field, Injector> injectorCache = new HashMap<Field, Injector>(); /** * true if cache is used, false otherwise */ private boolean cacheEnabled = false; /** * Gets an injector instance. If cache is enabled, it uses it. * * @param field * @return * @throws NullInstanceException */ private Injector getInjector(Field field) throws NullInstanceException { if (this.cacheEnabled) { Injector injector = this.injectorCache.get(field); if (injector == null) { injector = this.createInjector(field); this.injectorCache.put(field, injector); OptimusM2MEngineCtxInjectMessages.CI01.log(field.getDeclaringClass().getName(), field.getName()); } OptimusM2MEngineCtxInjectMessages.CI02.log(field.getDeclaringClass().getName(), field.getName()); return injector; } else { OptimusM2MEngineCtxInjectMessages.CI03.log(field.getDeclaringClass().getName(), field.getName()); return this.createInjector(field); } } /** * Creates an injector for the field. Returns null if field is not * * @param field * @return * @throws NullInstanceException */ private Injector createInjector(Field field) throws NullInstanceException { if (field.getAnnotation(ContextParameter.class) != null) { return new ContextParameterInjector(field); } else if (field.getAnnotation(RootContextElement.class) != null) { return new RootContextElementInjector(field); } else if (field.getAnnotation(ObjectContextElement.class) != null) { return new ObjectContextElementInjector(field); } else if (field.getAnnotation(ParentContextElement.class) != null) { return new ParentContextElementInjector(field); } else if (field.getAnnotation(CustomContextElement.class) != null) { return new CustomContextElementInjector(field); } return null; } /** * * Injects into annotated fields of the transformations, elements from the * context. * * @param transformation * @param context * @throws NullValueException * @throws FieldInjectionException * @throws NullInstanceException */ public void inject(AbstractTransformation<?> transformation, ITransformationContext context) throws NullValueException, FieldInjectionException, NullInstanceException { Class<?> clazz = transformation.getClass(); while (clazz != null && clazz != Object.class) { for (Field field : clazz.getDeclaredFields()) { Injector injector = this.getInjector(field); if (injector != null) { injector.inject(transformation, context); } } clazz = clazz.getSuperclass(); } } /** * * updates context with valies from context-annotated fields of the * transformations. * * @param transformation * @param context * @throws NullValueException * @throws FieldInjectionException * @throws NullInstanceException */ public void update(AbstractTransformation<?> transformation, ITransformationContext context) throws NullValueException, FieldUpdateException, NullInstanceException { Class<?> clazz = transformation.getClass(); while (clazz != null && clazz != Object.class) { for (Field field : clazz.getDeclaredFields()) { Injector injector = this.getInjector(field); if (injector != null) { injector.update(transformation, context); } } clazz = clazz.getSuperclass(); } } /** * Enables the cache */ public void enableCache() { this.cacheEnabled = true; OptimusM2MEngineCtxInjectMessages.CI04.log(); } /** * Disables the cache */ public void disableCache() { this.cacheEnabled = false; OptimusM2MEngineCtxInjectMessages.CI05.log(); } /** * Empties the cache map */ public void clearCache() { this.injectorCache.clear(); OptimusM2MEngineCtxInjectMessages.CI06.log(); } }