public void testFactoryMethodsMismatch() {
   try {
     FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class);
     fail();
   } catch (ConfigurationException e) {
     assertContains(e.getMessage(), "Constructor mismatch");
   }
 }
 public void testFactoryMethodMustDeclareAllConstructorExceptions() {
   try {
     FactoryProvider.newFactory(DefectiveCarFactoryWithNoExceptions.class, DefectiveCar.class);
     fail();
   } catch (ConfigurationException expected) {
     assertContains(expected.getMessage(), "no compatible exception is thrown");
   }
 }
 void validate() {
   Errors errorsForMember = errors.withSource(source);
   Set<InjectionPoint> injectionPoints;
   try {
     injectionPoints = request.getInjectionPoints();
   } catch (ConfigurationException e) {
     errors.merge(e.getErrorMessages());
     injectionPoints = e.getPartialValue();
   }
   memberInjectors =
       injector.membersInjectorStore.getInjectors(injectionPoints, errorsForMember);
 }
  @Override
  public Boolean visit(InjectionRequest<?> request) {
    Set<InjectionPoint> injectionPoints;
    try {
      injectionPoints = request.getInjectionPoints();
    } catch (ConfigurationException e) {
      errors.merge(e.getErrorMessages());
      injectionPoints = e.getPartialValue();
    }

    initializer.requestInjection(
        injector, request.getInstance(), request.getSource(), injectionPoints);
    return true;
  }
  InjectionPoint(TypeLiteral<?> declaringType, Field field, boolean optional) {
    this.member = field;
    this.declaringType = declaringType;
    this.optional = optional;

    Annotation[] annotations = field.getAnnotations();

    Errors errors = new Errors(field);
    Key<?> key = null;
    try {
      key = Annotations.getKey(declaringType.getFieldType(field), field, annotations, errors);
    } catch (ConfigurationException e) {
      errors.merge(e.getErrorMessages());
    } catch (ErrorsException e) {
      errors.merge(e.getErrors());
    }
    errors.throwConfigurationExceptionIfErrorsExist();

    this.dependencies =
        ImmutableList.<Dependency<?>>of(
            newDependency(key, Nullability.allowsNull(annotations), -1));
  }
  private ImmutableList<Dependency<?>> forMember(
      Member member, TypeLiteral<?> type, Annotation[][] paramterAnnotations) {
    Errors errors = new Errors(member);

    List<Dependency<?>> dependencies = Lists.newArrayList();
    int index = 0;

    for (TypeLiteral<?> parameterType : type.getParameterTypes(member)) {
      try {
        Annotation[] parameterAnnotations = paramterAnnotations[index];
        Key<?> key = Annotations.getKey(parameterType, member, parameterAnnotations, errors);
        dependencies.add(newDependency(key, Nullability.allowsNull(parameterAnnotations), index));
        index++;
      } catch (ConfigurationException e) {
        errors.merge(e.getErrorMessages());
      } catch (ErrorsException e) {
        errors.merge(e.getErrors());
      }
    }

    errors.throwConfigurationExceptionIfErrorsExist();
    return ImmutableList.copyOf(dependencies);
  }
 private void addMessageIfInformative(LinkedList<String> messages, Throwable cause) {
   if (cause
       instanceof
       ProvisionException) { // This technical exception is hidden. Only its causes should be
                             // shown.
     return;
   }
   if (cause
       instanceof
       ConfigurationException) { // A missing setting in settings.properties can cause this
                                 // exception.
     ConfigurationException configurationException = (ConfigurationException) cause;
     addClearifiedErrorMessages(messages, configurationException.getErrorMessages());
     return;
   }
   if (cause
       instanceof
       CreationException) { // A missing setting in settings.properties can cause this exception.
     CreationException creationException = (CreationException) cause;
     addClearifiedErrorMessages(messages, creationException.getErrorMessages());
     return;
   }
   messages.add(cause.getMessage());
 }
  /**
   * Returns an ordered, immutable set of injection points for the given type. Members in
   * superclasses come before members in subclasses. Within a class, fields come before methods.
   * Overridden methods are filtered out.
   *
   * @param statics true is this method should return static members, false for instance members
   * @param errors used to record errors
   */
  private static Set<InjectionPoint> getInjectionPoints(
      final TypeLiteral<?> type, boolean statics, Errors errors) {
    InjectableMembers injectableMembers = new InjectableMembers();
    OverrideIndex overrideIndex = null;

    List<TypeLiteral<?>> hierarchy = hierarchyFor(type);
    int topIndex = hierarchy.size() - 1;
    for (int i = topIndex; i >= 0; i--) {
      if (overrideIndex != null && i < topIndex) {
        // Knowing the position within the hierarchy helps us make optimizations.
        if (i == 0) {
          overrideIndex.position = Position.BOTTOM;
        } else {
          overrideIndex.position = Position.MIDDLE;
        }
      }

      TypeLiteral<?> current = hierarchy.get(i);

      for (Field field : current.getRawType().getDeclaredFields()) {
        if (Modifier.isStatic(field.getModifiers()) == statics) {
          Annotation atInject = getAtInject(field);
          if (atInject != null) {
            InjectableField injectableField = new InjectableField(current, field, atInject);
            if (injectableField.jsr330 && Modifier.isFinal(field.getModifiers())) {
              errors.cannotInjectFinalField(field);
            }
            injectableMembers.add(injectableField);
          }
        }
      }

      for (Method method : current.getRawType().getDeclaredMethods()) {
        if (isEligibleForInjection(method, statics)) {
          Annotation atInject = getAtInject(method);
          if (atInject != null) {
            InjectableMethod injectableMethod = new InjectableMethod(current, method, atInject);
            if (checkForMisplacedBindingAnnotations(method, errors)
                || !isValidMethod(injectableMethod, errors)) {
              if (overrideIndex != null) {
                boolean removed =
                    overrideIndex.removeIfOverriddenBy(method, false, injectableMethod);
                if (removed) {
                  logger.log(
                      Level.WARNING,
                      "Method: {0} is not a valid injectable method ("
                          + "because it either has misplaced binding annotations "
                          + "or specifies type parameters) but is overriding a method that is valid. "
                          + "Because it is not valid, the method will not be injected. "
                          + "To fix this, make the method a valid injectable method.",
                      method);
                }
              }
              continue;
            }
            if (statics) {
              injectableMembers.add(injectableMethod);
            } else {
              if (overrideIndex == null) {
                /*
                 * Creating the override index lazily means that the first type in the hierarchy
                 * with injectable methods (not necessarily the top most type) will be treated as
                 * the TOP position and will enjoy the same optimizations (no checks for overridden
                 * methods, etc.).
                 */
                overrideIndex = new OverrideIndex(injectableMembers);
              } else {
                // Forcibly remove the overriden method, otherwise we'll inject
                // it twice.
                overrideIndex.removeIfOverriddenBy(method, true, injectableMethod);
              }
              overrideIndex.add(injectableMethod);
            }
          } else {
            if (overrideIndex != null) {
              boolean removed = overrideIndex.removeIfOverriddenBy(method, false, null);
              if (removed) {
                logger.log(
                    Level.WARNING,
                    "Method: {0} is not annotated with @Inject but "
                        + "is overriding a method that is annotated with @javax.inject.Inject.  Because "
                        + "it is not annotated with @Inject, the method will not be injected. "
                        + "To fix this, annotate the method with @Inject.",
                    method);
              }
            }
          }
        }
      }
    }

    if (injectableMembers.isEmpty()) {
      return Collections.emptySet();
    }

    ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
    for (InjectableMember im = injectableMembers.head; im != null; im = im.next) {
      try {
        builder.add(im.toInjectionPoint());
      } catch (ConfigurationException ignorable) {
        if (!im.optional) {
          errors.merge(ignorable.getErrorMessages());
        }
      }
    }
    return builder.build();
  }