blob: 7c19482ba0ff7eca371147cd95e6ddefd457013e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.struts2.osgi.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.struts2.osgi.host.OsgiHost;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import javax.servlet.ServletContext;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* If a class implements BundleContextAware, this interceptor will call the setBundleContext(BundleContext)
* method on it. If a class implements ServiceAware<T>, this interceptor will call setService(List<T>)
*/
public class OsgiInterceptor extends AbstractInterceptor {
private static final Logger LOG = LogManager.getLogger(OsgiInterceptor.class);
private BundleContext bundleContext;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
LOG.trace("OSGi Interceptor - intercept() called - ActionInvocation: [{}]", invocation);
if (bundleContext != null) {
Object action = invocation.getAction();
injectBundleContext(action);
injectServicesUsingDeprecatedInterface(action);
injectServices(action);
} else {
LOG.warn("The OSGi interceptor was not able to find the BundleContext in the ServletContext");
}
return invocation.invoke();
}
private void injectBundleContext(Object action) {
if (action instanceof BundleContextAware) {
((BundleContextAware) action).setBundleContext(bundleContext);
}
if (action instanceof org.apache.struts2.osgi.action.BundleContextAware) {
((org.apache.struts2.osgi.action.BundleContextAware) action).withBundleContext(bundleContext);
}
}
@Deprecated
private void injectServicesUsingDeprecatedInterface(Object action) throws InvalidSyntaxException {
//inject service implementations
if (action instanceof ServiceAware) {
Type[] types = action.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType() instanceof Class) {
Class clazz = (Class) parameterizedType.getRawType();
if (ServiceAware.class.equals(clazz)) {
Class serviceClass = (Class) parameterizedType.getActualTypeArguments()[0];
ServiceReference[] refs = bundleContext.getAllServiceReferences(serviceClass.getName(), null);
//get the services
if (refs != null) {
List services = new ArrayList(refs.length);
for (ServiceReference ref : refs) {
Object service = bundleContext.getService(ref);
//wow, that's a lot of nested ifs
if (service != null) {
services.add(service);
}
}
if (!services.isEmpty()) {
((ServiceAware) action).setServices(services);
}
}
}
}
}
}
}
}
}
private void injectServices(Object action) throws InvalidSyntaxException {
//inject service implementations
if (action instanceof org.apache.struts2.osgi.action.ServiceAware) {
Type[] types = action.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType() instanceof Class) {
Class clazz = (Class) parameterizedType.getRawType();
if (org.apache.struts2.osgi.action.ServiceAware.class.equals(clazz)) {
Class serviceClass = (Class) parameterizedType.getActualTypeArguments()[0];
ServiceReference[] refs = bundleContext.getAllServiceReferences(serviceClass.getName(), null);
//get the services
if (refs != null) {
List<Object> services = new ArrayList<>(refs.length);
for (ServiceReference ref : refs) {
Object service = bundleContext.getService(ref);
//wow, that's a lot of nested ifs
if (service != null) {
services.add(service);
}
}
if (!services.isEmpty()) {
((org.apache.struts2.osgi.action.ServiceAware) action).withServices(services);
}
}
}
}
}
}
}
}
}
@Inject
public void setServletContext(ServletContext servletContext) {
LOG.trace("OSGi Interceptor - setServletContext() called - ServletContext: [{}] ", servletContext);
this.bundleContext = (BundleContext) servletContext.getAttribute(OsgiHost.OSGI_BUNDLE_CONTEXT);
}
}