View Javadoc

1   /*
2    * $Id$
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts2.osgi.interceptor;
22  
23  import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
24  import com.opensymphony.xwork2.ActionInvocation;
25  import com.opensymphony.xwork2.util.logging.Logger;
26  import com.opensymphony.xwork2.util.logging.LoggerFactory;
27  import com.opensymphony.xwork2.inject.Inject;
28  
29  import javax.servlet.ServletContext;
30  
31  import org.apache.struts2.osgi.OsgiHost;
32  import org.osgi.framework.BundleContext;
33  import org.osgi.framework.ServiceReference;
34  
35  import java.lang.reflect.Type;
36  import java.lang.reflect.ParameterizedType;
37  import java.util.List;
38  import java.util.ArrayList;
39  
40  /***
41   * If a class implements BundleContextAware, this interceptor will call the setBundleContext(BundleContext)
42   * method on it. If a class implements ServiceAware<T>, this interceptor will call setService(List<T>)
43   */
44  public class OsgiInterceptor extends AbstractInterceptor {
45      private static final Logger LOG = LoggerFactory.getLogger(OsgiInterceptor.class);
46  
47      private BundleContext bundleContext;
48  
49      public String intercept(ActionInvocation invocation) throws Exception {
50          if (bundleContext != null) {
51              Object action = invocation.getAction();
52  
53              //inject BundleContext
54              if (action instanceof BundleContextAware)
55                  ((BundleContextAware)action).setBundleContext(bundleContext);
56  
57              //inject service implementations
58              if (action instanceof ServiceAware) {
59                  Type[] types = action.getClass().getGenericInterfaces();
60                  if (types != null) {
61                      for (Type type : types) {
62                          if (type instanceof ParameterizedType) {
63                              ParameterizedType parameterizedType = (ParameterizedType) type;
64                              if (parameterizedType.getRawType() instanceof Class) {
65                                  Class clazz = (Class) parameterizedType.getRawType();
66                                  if (ServiceAware.class.equals(clazz)) {
67                                      Class serviceClass = (Class) parameterizedType.getActualTypeArguments()[0];
68                                      ServiceReference[] refs = bundleContext.getAllServiceReferences(serviceClass.getName(), null);
69                                      //get the services
70                                      if (refs != null) {
71                                          List services = new ArrayList(refs.length);
72                                          for (ServiceReference ref : refs) {
73                                              Object service = bundleContext.getService(ref);
74                                              //wow, that's a lot of nested ifs
75                                              if (service != null)
76                                                  services.add(service);
77                                          }
78  
79                                          if (!services.isEmpty())
80                                              ((ServiceAware)action).setServices(services);
81                                      }
82                                  }
83                              }
84                          }
85                      }
86                  }
87              }
88          } else if (LOG.isWarnEnabled()){
89              LOG.warn("The OSGi interceptor was not able to find the BundleContext in the ServletContext");          
90          }
91  
92          return invocation.invoke();
93      }
94  
95      @Inject
96      public void setServletContext(ServletContext servletContext) {
97          this.bundleContext = (BundleContext) servletContext.getAttribute(OsgiHost.OSGI_BUNDLE_CONTEXT);
98      }
99  }