Ejemplo n.º 1
0
    public Decorator build() {
      String implementationName =
          implName.replace(Mapper.CLASS_NAME_PLACEHOLDER, mapperElement.getSimpleName());

      Type decoratorType = typeFactory.getType(decoratorPrism.value());
      DecoratorConstructor decoratorConstructor =
          new DecoratorConstructor(
              implementationName, implementationName + "_", hasDelegateConstructor);

      String elementPackage =
          elementUtils.getPackageOf(mapperElement).getQualifiedName().toString();
      String packageName = implPackage.replace(Mapper.PACKAGE_NAME_PLACEHOLDER, elementPackage);

      return new Decorator(
          typeFactory,
          packageName,
          implementationName,
          decoratorType,
          elementPackage,
          mapperElement.getKind() == ElementKind.INTERFACE
              ? mapperElement.getSimpleName().toString()
              : null,
          methods,
          Arrays.asList(new Field(typeFactory.getType(mapperElement), "delegate", true)),
          options,
          versionInformation,
          Accessibility.fromModifiers(mapperElement.getModifiers()),
          extraImportedTypes,
          decoratorConstructor);
    }
  private Decorator getDecorator(
      TypeElement element, List<SourceMethod> methods, String implName, String implPackage) {
    DecoratedWithPrism decoratorPrism = DecoratedWithPrism.getInstanceOn(element);

    if (decoratorPrism == null) {
      return null;
    }

    TypeElement decoratorElement = (TypeElement) typeUtils.asElement(decoratorPrism.value());

    if (!typeUtils.isAssignable(decoratorElement.asType(), element.asType())) {
      messager.printMessage(element, decoratorPrism.mirror, Message.DECORATOR_NO_SUBTYPE);
    }

    List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>(methods.size());

    for (SourceMethod mappingMethod : methods) {
      boolean implementationRequired = true;
      for (ExecutableElement method :
          ElementFilter.methodsIn(decoratorElement.getEnclosedElements())) {
        if (elementUtils.overrides(method, mappingMethod.getExecutable(), decoratorElement)) {
          implementationRequired = false;
          break;
        }
      }
      Type declaringMapper = mappingMethod.getDeclaringMapper();
      if (implementationRequired && !(mappingMethod.isDefault() || mappingMethod.isStatic())) {
        if ((declaringMapper == null) || declaringMapper.equals(typeFactory.getType(element))) {
          mappingMethods.add(new DelegatingMethod(mappingMethod));
        }
      }
    }

    boolean hasDelegateConstructor = false;
    boolean hasDefaultConstructor = false;
    for (ExecutableElement constructor :
        ElementFilter.constructorsIn(decoratorElement.getEnclosedElements())) {
      if (constructor.getParameters().isEmpty()) {
        hasDefaultConstructor = true;
      } else if (constructor.getParameters().size() == 1) {
        if (typeUtils.isAssignable(element.asType(), first(constructor.getParameters()).asType())) {
          hasDelegateConstructor = true;
        }
      }
    }

    if (!hasDelegateConstructor && !hasDefaultConstructor) {
      messager.printMessage(element, decoratorPrism.mirror, Message.DECORATOR_CONSTRUCTOR);
    }

    Decorator decorator =
        new Decorator.Builder()
            .elementUtils(elementUtils)
            .typeFactory(typeFactory)
            .mapperElement(element)
            .decoratorPrism(decoratorPrism)
            .methods(mappingMethods)
            .hasDelegateConstructor(hasDelegateConstructor)
            .options(options)
            .versionInformation(versionInformation)
            .implName(implName)
            .implPackage(implPackage)
            .extraImports(getExtraImports(element))
            .build();

    return decorator;
  }