View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.guice;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.lifecycle.InitialisationException;
11  import org.mule.api.registry.RegistrationException;
12  import org.mule.config.i18n.MessageFactory;
13  import org.mule.registry.AbstractRegistry;
14  
15  import com.google.inject.Binding;
16  import com.google.inject.Injector;
17  import com.google.inject.Key;
18  import com.google.inject.TypeLiteral;
19  import com.google.inject.name.Named;
20  
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.guiceyfruit.Injectors;
27  import org.guiceyfruit.support.CloseFailedException;
28  
29  /**
30   * The internal Mule interface for retreiving objects from a Guice injector.  This registry is read-only since all
31   * objects should be configured by {@link com.google.inject.Module} objects.  The lifecycle of objects will be
32   * managed by Mule since Guice does not provide lifecycle support.
33   * <p/>
34   * To create modules extend the {@link org.mule.module.guice.AbstractMuleGuiceModule} since it provides hooks and helpers for
35   * working with Mule configuration.  Any modules independent of Mule can just extend the Guice {@link com.google.inject.AbstractModule}
36   * as normal.
37   * <p/>
38   * Mule will discover modules on the classpath, if you need to configure a module before passing it to the Guice injector you
39   * need to implement a {@link org.mule.module.guice.GuiceModuleFactory} for your module.
40   *
41   * @see org.mule.module.guice.AbstractMuleGuiceModule
42   * @see org.mule.module.guice.GuiceModuleFactory
43   */
44  public class GuiceRegistry extends AbstractRegistry
45  {
46      private Injector injector = null;
47  
48      public GuiceRegistry(MuleContext muleContext)
49      {
50          super("guice", muleContext);
51      }
52  
53  
54      GuiceRegistry(Injector injector, MuleContext muleContext)
55      {
56          this(muleContext);
57          this.injector = injector;
58      }
59  
60      protected void doInitialise() throws InitialisationException
61      {
62          //do nothing
63      }
64  
65      protected void doDispose()
66      {
67          try
68          {
69              Injectors.close(injector);
70          }
71          catch (CloseFailedException e)
72          {
73              logger.error("Failed to close the Guice registry cleanly", e);
74          }
75      }
76  
77      public <T> T lookupObject(String key)
78      {
79          //Guice isn't really supposed to work this way but in Mule we need to look up objects by name only sometimes
80          for (Map.Entry<Key<?>, Binding<?>> entry : injector.getBindings().entrySet())
81          {
82              if (entry.getKey().getAnnotation() instanceof Named)
83              {
84                  String name = ((Named) entry.getKey().getAnnotation()).value();
85                  if (name.equals(key))
86                  {
87                      Object o = entry.getValue().getProvider().get();
88                      return (T) o;
89                  }
90              }
91          }
92          return null;
93      }
94  
95      @Override
96      public <T> T lookupObject(Class<T> type) throws RegistrationException
97      {
98          //We have to loop through all objects since Guice will act as a factory and create a binding for the given class
99          //if one is not bound in the registry.
100         List<Binding<T>> bindings = injector.findBindingsByType(TypeLiteral.get(type));
101         if(bindings.size()==0)
102         {
103             return null;
104 
105         }
106         else if (bindings.size()==1)
107         {
108             return bindings.get(0).getProvider().get();
109         }
110         else
111         {
112             throw new RegistrationException(MessageFactory.createStaticMessage("More than one object of type: " + type + ", was found"));
113         }
114     }
115 
116     public <T> Map<String, T> lookupByType(Class<T> type)
117     {
118 
119 
120         return Collections.EMPTY_MAP;
121 //        try
122 //        {
123 //            List<Binding<T>> bindings = injector.findBindingsByType(TypeLiteral.get(type));
124 //            if(bindings!=null && bindings.size()>0)
125 //            {
126 //                Map<String, T> map = new HashMap<String, T>(bindings.size());
127 //                String name;
128 //                T object;
129 //                for (Binding<T> binding : bindings)
130 //                {
131 //                    object = binding.getProvider().get();
132 //
133 //                    if(binding.getKey().getAnnotation() instanceof Named)
134 //                    {
135 //                        name = ((Named)binding.getKey().getAnnotation()).value();
136 //                    }
137 //                    else if(object instanceof NamedObject)
138 //                    {
139 //                        name = ((NamedObject)object).getName();
140 //                    }
141 //                    else
142 //                    {
143 //                        name = "_" + object.hashCode();
144 //                    }
145 //                    map.put(name, object);
146 //                }
147 //                return map;
148 //            }
149 //            return Collections.emptyMap();
150 //        }
151 //        catch (ConfigurationException e)
152 //        {
153 //            return Collections.emptyMap();
154 //        }
155     }
156 
157     public <T> Collection<T> lookupObjects(Class<T> type)
158     {
159         return Collections.emptyList();
160 
161 //        try
162 //        {
163 //            List<Binding<T>> bindings = injector.findBindingsByType(TypeLiteral.get(type));
164 //            if(bindings!=null && bindings.size()>0)
165 //            {
166 //                List<T> list = new ArrayList<T>(bindings.size());
167 //                for (Binding<T> binding : bindings)
168 //                {
169 //                    list.add(binding.getProvider().get());
170 //                }
171 //                return list;
172 //            }
173 //            return Collections.emptyList();
174 //        }
175 //        catch (ConfigurationException e)
176 //        {
177 //            return Collections.emptyList();
178 //        }
179     }
180 
181     public void registerObject(String key, Object value) throws RegistrationException
182     {
183         throw new UnsupportedOperationException("registerObject");
184     }
185 
186     public void registerObject(String key, Object value, Object metadata) throws RegistrationException
187     {
188         throw new UnsupportedOperationException("registerObject");
189     }
190 
191     public void registerObjects(Map objects) throws RegistrationException
192     {
193         throw new UnsupportedOperationException("registerObjects");
194     }
195 
196     public void unregisterObject(String key) throws RegistrationException
197     {
198         throw new UnsupportedOperationException("unregisterObject");
199     }
200 
201     public void unregisterObject(String key, Object metadata) throws RegistrationException
202     {
203         throw new UnsupportedOperationException("unregisterObject");
204     }
205 
206     public boolean isReadOnly()
207     {
208         return true;
209     }
210 
211     public boolean isRemote()
212     {
213         return false;
214     }
215 }