diff --git a/plugins/osgi/src/main/java/org/apache/struts2/osgi/action/ServiceAware.java b/plugins/osgi/src/main/java/org/apache/struts2/osgi/action/ServiceAware.java new file mode 100644 index 000000000..45d356610 --- /dev/null +++ b/plugins/osgi/src/main/java/org/apache/struts2/osgi/action/ServiceAware.java @@ -0,0 +1,34 @@ +/* + * 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.action; + +import java.util.List; + +/** + * Classes implementing this interface, will be injected a list of services + * registered with the type of the parameterized type + * + * @param The type of the service + * @since 2.6 + */ +public interface ServiceAware { + + void withServices(List services); + +} diff --git a/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java b/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java index 11dd1f9a0..62c676ce0 100644 --- a/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java +++ b/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/OsgiInterceptor.java @@ -21,10 +21,11 @@ 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.logging.log4j.Logger; 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; @@ -46,39 +47,85 @@ public class OsgiInterceptor extends AbstractInterceptor { public String intercept(ActionInvocation invocation) throws Exception { if (bundleContext != null) { Object action = invocation.getAction(); + injectBundleContext(action); + injectServicesUsingDeprecatedInterface(action); + injectServices(action); + } else if (LOG.isWarnEnabled()) { + LOG.warn("The OSGi interceptor was not able to find the BundleContext in the ServletContext"); + } - //inject BundleContext - if (action instanceof BundleContextAware) - ((BundleContextAware)action).setBundleContext(bundleContext); + return invocation.invoke(); + } - if (action instanceof org.apache.struts2.osgi.action.BundleContextAware) { - ((org.apache.struts2.osgi.action.BundleContextAware) action).withBundleContext(bundleContext); + 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); + } + } + } + } + } } + } + } - //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); - } + 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 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); + if (!services.isEmpty()) { + ((org.apache.struts2.osgi.action.ServiceAware) action).withServices(services); } } } @@ -86,11 +133,7 @@ public class OsgiInterceptor extends AbstractInterceptor { } } } - } else if (LOG.isWarnEnabled()){ - LOG.warn("The OSGi interceptor was not able to find the BundleContext in the ServletContext"); } - - return invocation.invoke(); } @Inject diff --git a/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java b/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java index bc6e916fe..c5c1c8e83 100644 --- a/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java +++ b/plugins/osgi/src/main/java/org/apache/struts2/osgi/interceptor/ServiceAware.java @@ -24,9 +24,15 @@ import java.util.List; * Classes implementing this interface, will be injected a list of services * registered with the type of the parameterized type * @param The type of the service + * @deprecated please use {@link org.apache.struts2.osgi.action.ServiceAware} instead */ +@Deprecated public interface ServiceAware { + /** + * @deprecated please use {@link org.apache.struts2.osgi.action.ServiceAware#withServices(List)} instead + */ + @Deprecated void setServices(List services); } diff --git a/plugins/osgi/src/test/java/org/apache/struts2/osgi/action/ServiceAction.java b/plugins/osgi/src/test/java/org/apache/struts2/osgi/action/ServiceAction.java new file mode 100644 index 000000000..df6c2588a --- /dev/null +++ b/plugins/osgi/src/test/java/org/apache/struts2/osgi/action/ServiceAction.java @@ -0,0 +1,34 @@ +/* + * 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.action; + +import java.util.List; + +public class ServiceAction implements ServiceAware { + private List services; + + + public List getServices() { + return services; + } + + public void withServices(List services) { + this.services = services; + } +} diff --git a/plugins/osgi/src/test/java/org/apache/struts2/osgi/interceptor/OsgiInterceptorTest.java b/plugins/osgi/src/test/java/org/apache/struts2/osgi/interceptor/OsgiInterceptorTest.java index 96f287569..e464d405e 100644 --- a/plugins/osgi/src/test/java/org/apache/struts2/osgi/interceptor/OsgiInterceptorTest.java +++ b/plugins/osgi/src/test/java/org/apache/struts2/osgi/interceptor/OsgiInterceptorTest.java @@ -18,6 +18,7 @@ */ package org.apache.struts2.osgi.interceptor; +import org.apache.struts2.osgi.action.ServiceAction; import org.easymock.EasyMock; import org.apache.struts2.osgi.host.OsgiHost; import org.osgi.framework.BundleContext; @@ -141,4 +142,33 @@ public class OsgiInterceptorTest extends TestCase { assertNotNull(objects); assertSame(someObject, objects.get(0)); } + + public void testActionServiceAware() throws Exception { + ServletContext servletContext = EasyMock.createStrictMock(ServletContext.class); + BundleContext bundleContext = EasyMock.createStrictMock(BundleContext.class); + ActionInvocation actionInvocation = EasyMock.createStrictMock(ActionInvocation.class); + ServiceAction serviceAction = new ServiceAction(); + + //service refs + ServiceReference objectRef = EasyMock.createNiceMock(ServiceReference.class); + Object someObject = new Object(); + + EasyMock.expect(servletContext.getAttribute(OsgiHost.OSGI_BUNDLE_CONTEXT)).andReturn(bundleContext); + EasyMock.expect(actionInvocation.getAction()).andReturn(serviceAction); + EasyMock.expect(actionInvocation.invoke()).andReturn(""); + EasyMock.expect(bundleContext.getAllServiceReferences(Object.class.getName(), null)).andReturn(new ServiceReference[] {objectRef}); + EasyMock.expect(bundleContext.getService(objectRef)).andReturn(someObject); + + EasyMock.replay(bundleContext); + EasyMock.replay(servletContext); + EasyMock.replay(actionInvocation); + + OsgiInterceptor osgiInterceptor = new OsgiInterceptor(); + osgiInterceptor.setServletContext(servletContext); + osgiInterceptor.intercept(actionInvocation); + + List objects = serviceAction.getServices(); + assertNotNull(objects); + assertSame(someObject, objects.get(0)); + } }