
org.atmosphere.inject.InjectableObjectFactory Maven / Gradle / Ivy
/*
* Copyright 2015 Async-IO.org
*
* 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.atmosphere.inject;
import org.atmosphere.cpr.AtmosphereConfig;
import org.atmosphere.cpr.AtmosphereFramework;
import org.atmosphere.cpr.AtmosphereObjectFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.ServiceLoader;
import java.util.Set;
/**
* Support injection of Atmosphere's Internal object using
* {@link org.atmosphere.cpr.AtmosphereConfig},{@link AtmosphereFramework},{@link org.atmosphere.cpr.BroadcasterFactory,
* {@link org.atmosphere.cpr.AtmosphereResourceFactory } ,{@link org.atmosphere.cpr.DefaultMetaBroadcaster } and
* {@link org.atmosphere.cpr.AtmosphereResourceSessionFactory } and classes implementing the {@link Injectable} defined inside
* META_INF/services/org.atmosphere.inject.Inject
*
* @author Jeanfrancois Arcand
*/
public class InjectableObjectFactory implements AtmosphereObjectFactory> {
protected static final Logger logger = LoggerFactory.getLogger(AtmosphereFramework.class);
private final static ServiceLoader injectableServiceLoader = ServiceLoader.load(Injectable.class);
private final LinkedList> injectables = new LinkedList>();
private AtmosphereConfig config;
@Override
public void configure(AtmosphereConfig config) {
this.config = config;
for (Injectable i : injectableServiceLoader) {
try {
logger.debug("Adding class {} as injectable", i.getClass());
injectables.addFirst(i);
} catch (Exception e) {
logger.error("", e);
}
}
}
@Override
public U newClassInstance(Class classType,
Class defaultType) throws InstantiationException, IllegalAccessException {
U instance = defaultType.newInstance();
injectAtmosphereInternalObject(instance, defaultType, config.framework());
postConstructExecution(instance, defaultType);
return instance;
}
/**
* Execute {@PostConstruct} method.
*
* @param instance the requested object.
* @param defaultType the type of the requested object
* @param
* @throws IllegalAccessException
*/
public void postConstructExecution(U instance, Class defaultType) throws IllegalAccessException {
Set methods = new HashSet();
methods.addAll(Arrays.asList(defaultType.getDeclaredMethods()));
methods.addAll(Arrays.asList(defaultType.getMethods()));
injectMethods(methods, instance);
}
private void injectMethods(Set methods, U instance) throws IllegalAccessException {
for (Method m : methods) {
if (m.isAnnotationPresent(PostConstruct.class)) {
try {
m.setAccessible(true);
m.invoke(instance);
break;
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* @param instance the requested object.
* @param defaultType the type of the requested object
* @param framework the {@link org.atmosphere.cpr.AtmosphereFramework}
* @param
* @throws IllegalAccessException
*/
public void injectAtmosphereInternalObject(U instance, Class defaultType, AtmosphereFramework framework) throws IllegalAccessException {
Set fields = new HashSet();
fields.addAll(Arrays.asList(defaultType.getDeclaredFields()));
fields.addAll(Arrays.asList(defaultType.getFields()));
injectFields(fields, instance, framework);
}
private void injectFields(Set fields, U instance, AtmosphereFramework framework) throws IllegalAccessException {
for (Field field : fields) {
if (field.isAnnotationPresent(Inject.class)) {
for (Injectable c : injectables) {
if (c.supportedType(field.getType())) {
field.setAccessible(true);
field.set(instance, c.injectable(framework.getAtmosphereConfig()));
break;
}
}
}
}
}
public AtmosphereObjectFactory allowInjectionOf(Injectable> injectable) {
injectables.add(injectable);
return this;
}
@Override
public String toString() {
return InjectableObjectFactory.class.getName();
}
/**
* Use this method to retrieve available {@link Injectable}. This method is for application that inject their
* own {@link Injectable} and needs already constructed classes.
*
* @param u the class
* @param the type
* @return the class if exists, null if not
*/
public U getInjectable(Class u) {
for (Injectable c : injectables) {
if (c.supportedType(u)) {
return (U) c.injectable(config);
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy