/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* 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, or (at your option)
* any later version.
*
* 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.
*/
package com.liferay.portal.spring.extender.internal.bean;
import com.liferay.portal.spring.extender.service.ServiceReference;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.util.ReflectionUtils;
/**
* @author Miguel Pastor
*/
public class ServiceReferenceAnnotationBeanPostProcessor
implements ApplicationListener<ContextClosedEvent>, BeanPostProcessor {
public ServiceReferenceAnnotationBeanPostProcessor(
BundleContext bundleContext) {
_bundleContext = bundleContext;
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
for (org.osgi.framework.ServiceReference<?> serviceReference :
_serviceReferences) {
_bundleContext.ungetService(serviceReference);
}
_serviceReferences.clear();
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
autoInject(bean, bean.getClass());
return bean;
}
protected void autoInject(Object targetBean, Class<?> beanClass) {
if ((beanClass == null) || beanClass.isInterface()) {
return;
}
Field[] fields = beanClass.getDeclaredFields();
for (Field field : fields) {
ServiceReference serviceReference = field.getAnnotation(
ServiceReference.class);
if (serviceReference == null) {
continue;
}
Class<?> typeClass = serviceReference.type();
org.osgi.framework.ServiceReference<?> osgiServiceReference =
_bundleContext.getServiceReference(typeClass.getName());
ReflectionUtils.makeAccessible(field);
try {
field.set(
targetBean,
_bundleContext.getService(osgiServiceReference));
}
catch (Throwable t) {
throw new BeanCreationException(
beanClass.getName(),
"Unable to inject bean reference fields", t);
}
_serviceReferences.add(osgiServiceReference);
}
autoInject(targetBean, beanClass.getSuperclass());
}
private final BundleContext _bundleContext;
private final Set<org.osgi.framework.ServiceReference<?>>
_serviceReferences = new HashSet<>();
}