13d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit/**
23d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * Copyright (C) 2008 Google Inc.
33d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit *
43d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * Licensed under the Apache License, Version 2.0 (the "License");
53d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * you may not use this file except in compliance with the License.
63d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * You may obtain a copy of the License at
73d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit *
83d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * http://www.apache.org/licenses/LICENSE-2.0
93d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit *
103d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * Unless required by applicable law or agreed to in writing, software
113d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * distributed under the License is distributed on an "AS IS" BASIS,
123d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * See the License for the specific language governing permissions and
143d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit * limitations under the License.
153d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit */
163d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
175ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitpackage com.google.inject.internal;
183d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
19d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport com.google.common.base.Objects;
205ae41eb77073b47e75c2dcf3766137f2352fbaf9limpbizkitimport com.google.inject.Key;
21888a264bdee08c82cccd9dcc94a8a4ac98912badsberlinimport com.google.inject.internal.InjectorImpl.JitLimitation;
22a98bc7a649ffad237fc64c21220766fe24b96890limpbizkitimport com.google.inject.spi.Dependency;
233d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
243d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit/**
25fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit * A placeholder which enables us to swap in the real factory once the injector is created.
26888a264bdee08c82cccd9dcc94a8a4ac98912badsberlin * Used for a linked binding, so that getting the linked binding returns the link's factory.
273d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit */
2807170cc3f59f08954c97e19f2d3cf165d3a8601asberlinfinal class FactoryProxy<T> implements InternalFactory<T>, CreationListener {
293d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
30fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit  private final InjectorImpl injector;
313d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  private final Key<T> key;
323d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  private final Key<? extends T> targetKey;
333d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  private final Object source;
343d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
35e4647a6dd1f38eb3f042ca22716d7a182cabcbe2limpbizkit  private InternalFactory<? extends T> targetFactory;
363d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
37fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit  FactoryProxy(InjectorImpl injector, Key<T> key, Key<? extends T> targetKey, Object source) {
38fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit    this.injector = injector;
393d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit    this.key = key;
403d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit    this.targetKey = targetKey;
413d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit    this.source = source;
423d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  }
433d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
44c3f928404a91cf837d809dcc465ba43442bc1198limpbizkit  public void notify(final Errors errors) {
459dc32d4b6df8725f009a93f51e410564a362ccf0limpbizkit    try {
46888a264bdee08c82cccd9dcc94a8a4ac98912badsberlin      targetFactory = injector.getInternalFactory(targetKey, errors.withSource(source), JitLimitation.NEW_OR_EXISTING_JIT);
47163c48aafee02f9e918a6e7385f5b3312e8edfb6limpbizkit    } catch (ErrorsException e) {
489dc32d4b6df8725f009a93f51e410564a362ccf0limpbizkit      errors.merge(e.getErrors());
499dc32d4b6df8725f009a93f51e410564a362ccf0limpbizkit    }
503d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  }
513d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
52888a264bdee08c82cccd9dcc94a8a4ac98912badsberlin  public T get(Errors errors, InternalContext context, Dependency<?> dependency, boolean linked)
53163c48aafee02f9e918a6e7385f5b3312e8edfb6limpbizkit      throws ErrorsException {
54ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin    context.pushState(targetKey, source);
55ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin    try {
56ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin      return targetFactory.get(errors.withSource(targetKey), context, dependency, true);
57ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin    } finally {
58ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin      context.popState();
59ba75f3563a179ddd3de14cfed6ba663e9e298032sberlin    }
603d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  }
613d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit
62477f9f9ce3e1077866b579e99cd33ab824f1ee69limpbizkit  @Override public String toString() {
63d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlin    return Objects.toStringHelper(FactoryProxy.class)
643d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit        .add("key", key)
653d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit        .add("provider", targetFactory)
663d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit        .toString();
673d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit  }
683d58d6b7c1235722366a641759a02bd9c6625c21limpbizkit}
69