View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  package org.apache.james.container.spring.adaptor;
20  
21  import org.apache.avalon.framework.service.ServiceException;
22  import org.apache.avalon.framework.service.ServiceManager;
23  import org.apache.james.container.spring.beanfactory.AvalonBeanDefinition;
24  import org.apache.james.container.spring.beanfactory.AvalonServiceReference;
25  import org.springframework.beans.BeansException;
26  import org.springframework.beans.factory.config.BeanDefinition;
27  import org.springframework.context.ApplicationContext;
28  import org.springframework.context.ApplicationContextAware;
29  
30  import java.util.List;
31  import java.util.Map;
32  import java.util.HashMap;
33  import java.util.Iterator;
34  
35  /**
36   * provides a Avalon-style service manager to all components
37   */
38  public class DefaultServiceManagerFactory implements ApplicationContextAware, ServiceManagerFactory {
39  
40      private ApplicationContext applicationContext;
41      private final Map replacements = new HashMap();
42  
43      private class ServiceManagerBridge implements ServiceManager {
44  
45          private final Map avalonServices = new HashMap();
46          
47          public ServiceManagerBridge(List avalonServiceReferences) {
48              populateServiceMap(avalonServiceReferences);
49          }
50  
51          private void populateServiceMap(List avalonServiceReferences) {
52              Iterator iterator = avalonServiceReferences.iterator();
53              while (iterator.hasNext()) {
54                  AvalonServiceReference serviceReference = (AvalonServiceReference) iterator.next();
55                  String name = serviceReference.getName();
56                  String rolename = serviceReference.getRolename();
57                  
58                  // the interface to be injected 
59                  Class roleClass = null;
60                  try {
61                      roleClass = Class.forName(rolename);
62                  } catch (ClassNotFoundException e) {
63                      throw new RuntimeException("cannot load class for role " + rolename, e);
64                  }
65  
66                  // if the service should be replaced by a bean, update the name here.
67                  if (replacements.containsKey(name)) {
68                      name = (String)replacements.get(name);
69                  }
70                  
71                  // the object to be injected (reduced to roleClass)
72                  Object injectionCandidate = applicationContext.getBean(name);
73                  if (!roleClass.isInstance(injectionCandidate)) {
74                      
75                      throw new RuntimeException("cannot assign bean '" + name + "' as role '" + rolename + "'");
76                  }
77  
78                  if (avalonServices.containsKey(rolename)) {
79                      throw new IllegalStateException("avalon service references role name not unique: " + rolename);
80                  }
81                  avalonServices.put(rolename, injectionCandidate);
82              }
83          }
84  
85          public Object lookup(String componentIdentifier)
86                  throws ServiceException {
87              Object service = avalonServices.get(componentIdentifier);
88              return service;
89          }
90  
91          public boolean hasService(String componentIdentifier) {
92              try {
93                  return null != lookup(componentIdentifier);
94              } catch (ServiceException e) {
95                  return false;
96              }
97          }
98  
99          public void release(Object object) {
100           throw new IllegalStateException("not yet implemented");
101       }
102       
103   }
104   
105   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
106       this.applicationContext = applicationContext;
107   }
108 
109     public ServiceManager getInstanceFor(String beanName, BeanDefinition beanDefinition) {
110         if (beanDefinition == null || !(beanDefinition instanceof AvalonBeanDefinition)) return null;
111 
112         AvalonBeanDefinition avalonBeanDefinition = (AvalonBeanDefinition) beanDefinition;
113         
114         return new DefaultServiceManagerFactory.ServiceManagerBridge(avalonBeanDefinition.getServiceReferences());
115   }
116 
117     /**
118      * for replacing services without changing vanilla Avalon/Phoenix assembly.xml
119      * @param replacements - Map<String, String>, the key indicating the service reference to be replaced, the value
120      * indicating the replacement bean
121      */
122     public void setReplacements(Map replacements) {
123         this.replacements.putAll(replacements);
124     }
125 
126 }