/* * Copyright 2014 MovingBlocks * * 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.terasology.registry; import org.reflections.ReflectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.context.Context; import org.terasology.util.reflection.ParameterProvider; import org.terasology.util.reflection.SimpleClassFactory; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Map; import java.util.Optional; /** */ public final class InjectionHelper { private static final Logger logger = LoggerFactory.getLogger(InjectionHelper.class); private InjectionHelper() { } public static void inject(final Object object, Context context) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { for (Field field : ReflectionUtils.getAllFields(object.getClass(), ReflectionUtils.withAnnotation(In.class))) { Object value = context.get(field.getType()); if (value != null) { try { field.setAccessible(true); field.set(object, value); } catch (IllegalAccessException e) { logger.error("Failed to inject value {} into field {} of {}", value, field, object, e); } } } return null; }); } public static void inject(final Object object) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { for (Field field : ReflectionUtils.getAllFields(object.getClass(), ReflectionUtils.withAnnotation(In.class))) { Object value = CoreRegistry.get(field.getType()); if (value != null) { try { field.setAccessible(true); field.set(object, value); } catch (IllegalAccessException e) { logger.error("Failed to inject value {} into field {} of {}", value, field, object, e); } } } return null; }); } public static <T> void inject(final Object object, final Class<? extends Annotation> annotation, final Map<Class<? extends T>, T> source) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { for (Field field : ReflectionUtils.getAllFields(object.getClass(), ReflectionUtils.withAnnotation(annotation))) { Object value = source.get(field.getType()); if (value != null) { try { field.setAccessible(true); field.set(object, value); } catch (IllegalAccessException e) { logger.error("Failed to inject value {} into field {}", value, field, e); } } else { logger.error("Failed to inject into field {}, nothing to inject", field); } } return null; }); } public static void share(Object object) { Share share = object.getClass().getAnnotation(Share.class); if (share != null && share.value() != null) { for (Class interfaceType : share.value()) { CoreRegistry.put(interfaceType, object); } } } public static <E> E createWithConstructorInjection(Class<? extends E> clazz, Context context) { SimpleClassFactory simpleClassFactory = new SimpleClassFactory(new ParameterProvider() { @Override public <T> Optional<T> get(Class<T> x) { return Optional.of(context.get(x)); } }); return simpleClassFactory.instantiateClass(clazz).get(); } }