103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit/**
203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * Copyright (C) 2009 Google Inc.
303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit *
403b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * Licensed under the Apache License, Version 2.0 (the "License");
503b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * you may not use this file except in compliance with the License.
603b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * You may obtain a copy of the License at
703b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit *
803b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * http://www.apache.org/licenses/LICENSE-2.0
903b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit *
1003b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * Unless required by applicable law or agreed to in writing, software
1103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * distributed under the License is distributed on an "AS IS" BASIS,
1203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * See the License for the specific language governing permissions and
1403b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * limitations under the License.
1503b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit */
1603b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
175ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitpackage com.google.inject.internal;
1803b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
19d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.collect.Iterables.concat;
20b7a02b02d81c830d148355c90bc309bcd66fb592sberlin
21b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.ImmutableList;
2203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkitimport com.google.inject.spi.InjectionPoint;
2303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
2403b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit/**
2503b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * Constructor injectors by type.
2603b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit *
2703b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit * @author jessewilson@google.com (Jesse Wilson)
2803b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit */
295ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitfinal class ConstructorInjectorStore {
3003b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit  private final InjectorImpl injector;
3103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
3244475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit  private final FailableCache<InjectionPoint, ConstructorInjector<?>>  cache
3344475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit      = new FailableCache<InjectionPoint, ConstructorInjector<?>> () {
34efa4e9f24a309c38c1356fd43eb76fcbca8d975aguice.mirrorbot@gmail.com    @Override
3544475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit    protected ConstructorInjector<?> create(InjectionPoint constructorInjector, Errors errors)
367cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit        throws ErrorsException {
3744475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit      return createConstructor(constructorInjector, errors);
387cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit    }
397cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit  };
407cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit
41a843a95d620de9c8046e67a8f51619b3fedf77d3limpbizkit  ConstructorInjectorStore(InjectorImpl injector) {
4203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit    this.injector = injector;
4303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit  }
4403b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
457cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit  /**
467cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit   * Returns a new complete constructor injector with injection listeners registered.
477cef5b0e4c19df48b7eafea8a8d7c2afc5a15fa0limpbizkit   */
4844475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit  public ConstructorInjector<?> get(InjectionPoint constructorInjector, Errors errors)
4944475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit      throws ErrorsException {
5044475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit    return cache.get(constructorInjector, errors);
5103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit  }
527df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin
537df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin  /**
547df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * Purges an injection point from the cache. Use this only if the cache is not actually valid and
557df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * needs to be purged. (See issue 319 and
567df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * ImplicitBindingTest#testCircularJitBindingsLeaveNoResidue and
577df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * #testInstancesRequestingProvidersForThemselvesWithChildInjectors for examples of when this is
587df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * necessary.)
597df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   *
607df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   * Returns true if the injector for that point was stored in the cache, false otherwise.
617df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin   */
627df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin  boolean remove(InjectionPoint ip) {
637df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin    return cache.remove(ip);
647df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin  }
6503b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
6644475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit  private <T> ConstructorInjector<T> createConstructor(InjectionPoint injectionPoint, Errors errors)
6703b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit      throws ErrorsException {
68516e2ab11feba3634edf380c65df98fadc56a231limpbizkit    int numErrorsBefore = errors.size();
69516e2ab11feba3634edf380c65df98fadc56a231limpbizkit
70e89c49ec2c6c1034ce15e5c7d1a0d4856677eecclimpbizkit    SingleParameterInjector<?>[] constructorParameterInjectors
7103b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit        = injector.getParametersInjectors(injectionPoint.getDependencies(), errors);
7244475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit
7344475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit    @SuppressWarnings("unchecked") // the injector type agrees with the injection point type
7444475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit    MembersInjectorImpl<T> membersInjector = (MembersInjectorImpl<T>) injector.membersInjectorStore
7544475647fc7ca0595e543a7f72efdd4c6862273elimpbizkit        .get(injectionPoint.getDeclaringType(), errors);
7603b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
77eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    /*if[AOP]*/
78eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    ImmutableList<MethodAspect> injectorAspects = injector.state.getMethodAspects();
79a843a95d620de9c8046e67a8f51619b3fedf77d3limpbizkit    ImmutableList<MethodAspect> methodAspects = membersInjector.getAddedAspects().isEmpty()
80eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit        ? injectorAspects
81eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit        : ImmutableList.copyOf(concat(injectorAspects, membersInjector.getAddedAspects()));
82eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    ConstructionProxyFactory<T> factory = new ProxyFactory<T>(injectionPoint, methodAspects);
83eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    /*end[AOP]*/
84eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    /*if[NO_AOP]
85eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    ConstructionProxyFactory<T> factory = new DefaultConstructionProxyFactory<T>(injectionPoint);
86eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    end[NO_AOP]*/
8703b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit
88516e2ab11feba3634edf380c65df98fadc56a231limpbizkit    errors.throwIfNewErrors(numErrorsBefore);
89516e2ab11feba3634edf380c65df98fadc56a231limpbizkit
90eb4051392fe903931d4a799685a01c87ca1c007blimpbizkit    return new ConstructorInjector<T>(membersInjector.getInjectionPoints(), factory.create(),
91a843a95d620de9c8046e67a8f51619b3fedf77d3limpbizkit        constructorParameterInjectors, membersInjector);
9203b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit  }
9303b81a6b931a06c7697e422b218e3734a7f262cclimpbizkit}
94