View Javadoc
1   /**
2    * This file Copyright (c) 2011-2016 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.objectfactory.guice;
35  
36  import info.magnolia.objectfactory.ComponentFactory;
37  import info.magnolia.objectfactory.ComponentFactoryUtil;
38  import info.magnolia.objectfactory.ComponentProvider;
39  
40  import java.lang.reflect.InvocationTargetException;
41  import java.util.Set;
42  
43  import javax.inject.Inject;
44  import javax.inject.Provider;
45  
46  import com.google.common.collect.ImmutableSet;
47  import com.google.common.collect.Sets;
48  import com.google.inject.Injector;
49  import com.google.inject.Key;
50  import com.google.inject.spi.Dependency;
51  import com.google.inject.spi.InjectionPoint;
52  import com.google.inject.spi.ProviderWithDependencies;
53  
54  /**
55   * Utilities for guice.
56   */
57  public class GuiceUtils {
58  
59      public static <T> Provider<T> providerForInstance(final T instance) {
60          return new Provider<T>() {
61              @Override
62              public T get() {
63                  return instance;
64              }
65  
66              @Override
67              public String toString() {
68                  return "Provider for: " + instance.toString();
69              }
70          };
71      }
72  
73      public static <T> Provider<T> providerForComponentFactory(final Class<? extends ComponentFactory<T>> componentFactoryClass) {
74          return new Provider<T>() {
75  
76              @Inject
77              private ComponentProvider componentProvider;
78  
79              @Override
80              public T get() {
81                  try {
82                      ComponentFactory<T> componentFactory = ComponentFactoryUtil.createFactory(componentFactoryClass, componentProvider);
83                      ((GuiceComponentProvider) componentProvider).injectMembers(componentFactory);
84                      T instance = componentFactory.newInstance();
85                      return instance;
86                  } catch (InstantiationException e) {
87                      throw new IllegalStateException("Failed to create ComponentFactory [" + componentFactoryClass + "]", e);
88                  } catch (IllegalAccessException e) {
89                      throw new IllegalStateException("Failed to create ComponentFactory [" + componentFactoryClass + "]", e);
90                  } catch (InvocationTargetException e) {
91                      throw new IllegalStateException("Failed to create ComponentFactory [" + componentFactoryClass + "]", e);
92                  }
93              }
94  
95              @Override
96              public String toString() {
97                  return "ComponentFactory: " + componentFactoryClass.toString();
98              }
99          };
100     }
101 
102     public static <T> Provider<T> providerForComponentFactory(final ComponentFactory<T> componentFactory) {
103 
104         // This method does exactly the same as com.google.inject.util.Providers#guicify
105 
106         // Ensure that we inject all injection points from the delegate provider.
107         Set<InjectionPoint> injectionPoints =
108                 InjectionPoint.forInstanceMethodsAndFields(componentFactory.getClass());
109         if (injectionPoints.isEmpty()) {
110             return new com.google.inject.Provider<T>() {
111                 @Override
112                 public T get() {
113                     return componentFactory.newInstance();
114                 }
115 
116                 @Override
117                 public String toString() {
118                     return "ComponentFactory: " + componentFactory.toString();
119                 }
120             };
121         } else {
122             Set<Dependency<?>> mutableDeps = Sets.newHashSet();
123             for (InjectionPoint ip : injectionPoints) {
124                 mutableDeps.addAll(ip.getDependencies());
125             }
126             final Set<Dependency<?>> dependencies = ImmutableSet.copyOf(mutableDeps);
127             return new ProviderWithDependencies<T>() {
128                 @com.google.inject.Inject
129                 void initialize(Injector injector) {
130                     injector.injectMembers(componentFactory);
131                 }
132 
133                 @Override
134                 public Set<Dependency<?>> getDependencies() {
135                     return dependencies;
136                 }
137 
138                 @Override
139                 public T get() {
140                     return componentFactory.newInstance();
141                 }
142 
143                 @Override
144                 public String toString() {
145                     return "ComponentFactory: " + componentFactory.toString();
146                 }
147             };
148         }
149     }
150 
151     public static boolean hasExplicitBindingFor(Injector injector, Class<?> type) {
152         return hasExplicitBindingFor(injector, Key.get(type));
153     }
154 
155     public static boolean hasExplicitBindingFor(Injector injector, Key<?> key) {
156         Injector target = injector;
157         do {
158             if (target.getBindings().containsKey(key)) {
159                 return true;
160             }
161             target = target.getParent();
162         } while (target != null);
163         return false;
164     }
165 }