/**
   * Appends the method that calls the {@code @PageHiding} method of the widget.
   *
   * @param pageImplBuilder The class builder for the implementation of PageNode we are adding the
   *     method to.
   * @param pageClass The "content type" (Widget subclass) of the page. This is the type the user
   *     annotated with {@code @Page}.
   */
  private void appendPageHidingMethod(
      AnonymousClassStructureBuilder pageImplBuilder, MetaClass pageClass) {
    BlockBuilder<?> method =
        pageImplBuilder
            .publicMethod(
                void.class,
                createMethodNameFromAnnotation(PageHiding.class),
                Parameter.of(pageClass, "widget"),
                Parameter.of(NavigationControl.class, "control"))
            .body();
    final MetaMethod pageHidingMethod =
        checkMethodAndAddPrivateAccessors(
            pageImplBuilder,
            method,
            pageClass,
            PageHiding.class,
            NavigationControl.class,
            "control");

    /*
     * If the user did not provide a control parameter, we must proceed for them after the method is invoked.
     */
    if (pageHidingMethod == null || pageHidingMethod.getParameters().length != 1) {
      method.append(Stmt.loadVariable("control").invoke("proceed"));
    }

    method.finish();
  }
Example #2
0
  @Override
  public Statement getBeanInstance(final InjectableInstance injectableInstance) {
    final IOCProcessingContext pCtx = injectableInstance.getInjectionContext().getProcessingContext();

    pCtx.append(Stmt.declareFinalVariable(varName, proxyClass, newObject(proxyClass)));

    final MetaClass proxyResolverRef = parameterizedAs(ProxyResolver.class, typeParametersOf(proxiedType));

    final BlockBuilder<AnonymousClassStructureBuilder> proxyResolverBody = newObject(proxyResolverRef)
            .extend().publicOverridesMethod("resolve", Parameter.of(proxiedType, "obj"));

    final Statement proxyResolver = proxyResolverBody._(
        ProxyMaker.closeProxy(Refs.get(varName), Refs.get("obj"))

    ).finish().finish();

    proxyResolverBody._(Stmt.loadVariable("context").invoke("addProxyReference", Refs.get(varName), Refs.get("obj")));

    pCtx.append(loadVariable("context").invoke("addUnresolvedProxy", proxyResolver,
            proxiedType, qualifyingMetadata.getQualifiers()));

    for (final Statement statement : closeStatements) {
      proxyResolverBody.append(statement);
    }

    setRendered(true);
    return loadVariable(varName);
  }
  /**
   * Generates a new instance of an anonymous inner class that implements the PageNode interface.
   *
   * @param pageClass The class providing the widget content for the page.
   * @param pageName The name of the page (to be used in the URL history fragment).
   */
  private ObjectBuilder generateNewInstanceOfPageImpl(MetaClass pageClass, String pageName) {
    AnonymousClassStructureBuilder pageImplBuilder =
        ObjectBuilder.newInstanceOf(
                MetaClassFactory.parameterizedAs(
                    PageNode.class, MetaClassFactory.typeParametersOf(pageClass)))
            .extend();

    pageImplBuilder
        .publicMethod(String.class, "name")
        .append(Stmt.loadLiteral(pageName).returnValue())
        .finish()
        .publicMethod(Class.class, "contentType")
        .append(Stmt.loadLiteral(pageClass).returnValue())
        .finish()
        .publicMethod(
            void.class, "produceContent", Parameter.of(CreationalCallback.class, "callback"))
        .append(
            Stmt.nestedCall(Refs.get("bm"))
                .invoke("lookupBean", Stmt.loadLiteral(pageClass))
                .invoke("getInstance", Stmt.loadVariable("callback")))
        .finish();

    appendPageHidingMethod(pageImplBuilder, pageClass);
    appendPageHiddenMethod(pageImplBuilder, pageClass);

    appendPageShowingMethod(pageImplBuilder, pageClass);
    appendPageShownMethod(pageImplBuilder, pageClass);

    return pageImplBuilder.finish();
  }
  /**
   * Appends the method that calls the {@code @PageHidden} method of the widget.
   *
   * @param pageImplBuilder The class builder for the implementation of PageNode we are adding the
   *     method to.
   * @param pageClass The "content type" (Widget subclass) of the page. This is the type the user
   *     annotated with {@code @Page}.
   */
  private void appendPageHiddenMethod(
      AnonymousClassStructureBuilder pageImplBuilder, MetaClass pageClass) {
    BlockBuilder<?> method =
        pageImplBuilder
            .publicMethod(
                void.class,
                createMethodNameFromAnnotation(PageHidden.class),
                Parameter.of(pageClass, "widget"))
            .body();
    checkMethodAndAddPrivateAccessors(
        pageImplBuilder, method, pageClass, PageHidden.class, HistoryToken.class, "state");

    if (pageClass.getAnnotation(Singleton.class) == null
        && pageClass.getAnnotation(ApplicationScoped.class) == null
        && pageClass.getAnnotation(EntryPoint.class) == null) {
      method.append(Stmt.loadVariable("bm").invoke("destroyBean", Stmt.loadVariable("widget")));
    }
    method.finish();
  }
Example #5
0
  private List<MetaMethod> getSpecialTypeMethods() {
    final List<MetaMethod> meths = new ArrayList<MetaMethod>();
    final JEnumType type = getEnclosedMetaObject().isEnum();

    if (type != null) {
      meths.add(
          new GWTSpecialMethod(this, DefModifiers.none(), Scope.Public, String.class, "name"));
      meths.add(
          new GWTSpecialMethod(
              this,
              DefModifiers.none(),
              Scope.Public,
              Enum.class,
              "valueOf",
              Parameter.of(String.class, "p").getMetaParameter()));
      meths.add(
          new GWTSpecialMethod(this, DefModifiers.none(), Scope.Public, Enum[].class, "values"));
    }

    return meths;
  }
  @Override
  public Statement getBeanInstance(final InjectableInstance injectableInstance) {
    final MetaClass type;
    final MetaParameterizedType pType;

    switch (injectableInstance.getTaskType()) {
      case Type:
        return null;
      case PrivateField:
      case Field:
        final MetaField field = injectableInstance.getField();
        type = field.getType();

        pType = type.getParameterizedType();
        break;

      case Parameter:
        final MetaParameter parm = injectableInstance.getParm();
        type = parm.getType();

        pType = type.getParameterizedType();
        break;

      default:
        throw new RuntimeException("illegal task type: " + injectableInstance.getEnclosingType());
    }

    final MetaType[] typeArgs = pType.getTypeParameters();
    final MetaClass[] typeArgsClasses = new MetaClass[typeArgs.length];

    for (int i = 0; i < typeArgs.length; i++) {
      final MetaType argType = typeArgs[i];

      if (argType instanceof MetaClass) {
        typeArgsClasses[i] = (MetaClass) argType;
      } else if (argType instanceof MetaParameterizedType) {
        typeArgsClasses[i] = (MetaClass) ((MetaParameterizedType) argType).getRawType();
      }
    }

    final Annotation[] qualifiers = injectableInstance.getQualifiers();

    final BlockBuilder<?> block =
        injectableInstance.getInjectionContext().getProcessingContext().getBlockBuilder();
    final MetaClass providerCreationalCallback =
        MetaClassFactory.parameterizedAs(
            CreationalCallback.class,
            MetaClassFactory.typeParametersOf(providerInjector.getInjectedType()));

    final String varName =
        InjectUtil.getVarNameFromType(
            providerInjector.getConcreteInjectedType(), injectableInstance);

    final Statement valueRef;

    if (providerInjector.isSingleton() && providerInjector.isRendered()) {
      valueRef =
          Stmt.loadVariable("beanInstance")
              .invoke("provide", typeArgsClasses, qualifiers.length != 0 ? qualifiers : null);
    } else {

      valueRef = Stmt.load(null);
    }

    block.append(
        Stmt.declareFinalVariable(
            varName,
            providerCreationalCallback,
            Stmt.newObject(providerCreationalCallback)
                .extend()
                .publicOverridesMethod(
                    "callback", Parameter.of(providerInjector.getInjectedType(), "beanInstance"))
                .append(
                    Stmt.loadVariable(InjectUtil.getVarNameFromType(type, injectableInstance))
                        .invoke("callback", valueRef))
                .append(Stmt.loadVariable("async").invoke("finish", Refs.get("this")))
                .finish()
                .publicOverridesMethod("toString")
                .append(
                    Stmt.load(providerInjector.getInjectedType()).invoke("getName").returnValue())
                .finish()
                .finish()));

    block.append(Stmt.loadVariable("async").invoke("wait", Refs.get(varName)));

    block.append(
        Stmt.loadVariable(providerInjector.getCreationalCallbackVarName())
            .invoke("getInstance", Refs.get(varName), Refs.get("context")));

    return null;
  }
  private void appendPageShowMethod(
      AnonymousClassStructureBuilder pageImplBuilder,
      MetaClass pageClass,
      Class<? extends Annotation> annotation,
      boolean addPrivateAccessors) {
    BlockBuilder<?> method =
        pageImplBuilder
            .publicMethod(
                void.class,
                createMethodNameFromAnnotation(annotation),
                Parameter.of(pageClass, "widget"),
                Parameter.of(HistoryToken.class, "state"))
            .body();

    int idx = 0;

    method.append(Stmt.declareFinalVariable("pageState", Map.class, new HashMap<String, Object>()));
    for (MetaField field : pageClass.getFieldsAnnotatedWith(PageState.class)) {
      PageState psAnno = field.getAnnotation(PageState.class);
      String fieldName = field.getName();
      String queryParamName = psAnno.value();
      if (queryParamName == null || queryParamName.trim().isEmpty()) {
        queryParamName = fieldName;
      }

      if (addPrivateAccessors) {
        PrivateAccessUtil.addPrivateAccessStubs(
            PrivateAccessType.Write, "jsni", pageImplBuilder, field, new Modifier[] {});
      }

      String injectorName = PrivateAccessUtil.getPrivateFieldInjectorName(field);

      MetaClass erasedFieldType = field.getType().getErased();
      if (erasedFieldType.isAssignableTo(Collection.class)) {
        MetaClass elementType =
            MarshallingGenUtil.getConcreteCollectionElementType(field.getType());
        if (elementType == null) {
          throw new UnsupportedOperationException(
              "Found a @PageState field with a Collection type but without a concrete type parameter. "
                  + "Collection-typed @PageState fields must specify a concrete type parameter.");
        }
        if (erasedFieldType.equals(MetaClassFactory.get(Set.class))) {
          method.append(Stmt.declareVariable(fieldName, Stmt.newObject(HashSet.class)));
        } else if (erasedFieldType.equals(MetaClassFactory.get(List.class))
            || erasedFieldType.equals(MetaClassFactory.get(Collection.class))) {
          method.append(Stmt.declareVariable(fieldName, Stmt.newObject(ArrayList.class)));
        } else {
          throw new UnsupportedOperationException(
              "Found a @PageState field which is a collection of type "
                  + erasedFieldType.getFullyQualifiedName()
                  + ". For collection-valued fields, only the exact types java.util.Collection, java.util.Set, and "
                  + "java.util.List are supported at this time.");
        }

        // for (String fv{idx} : state.get({fieldName}))
        method.append(
            Stmt.loadVariable("state")
                .invoke("getState")
                .invoke("get", queryParamName)
                .foreach("elem", Object.class)
                .append(
                    Stmt.declareVariable(
                        "fv" + idx, Stmt.castTo(String.class, Stmt.loadVariable("elem"))))
                .append(
                    Stmt.loadVariable(fieldName)
                        .invoke(
                            "add",
                            paramFromStringStatement(elementType, Stmt.loadVariable("fv" + idx))))
                .append(
                    Stmt.loadVariable("pageState")
                        .invoke("put", fieldName, Stmt.loadVariable(fieldName)))
                .finish());
        method.append(
            Stmt.loadVariable("this")
                .invoke(injectorName, Stmt.loadVariable("widget"), Stmt.loadVariable(fieldName)));
      } else {
        method.append(
            Stmt.declareFinalVariable(
                "fv" + idx,
                Collection.class,
                Stmt.loadVariable("state").invoke("getState").invoke("get", queryParamName)));
        method.append(
            If.cond(
                    Bool.or(
                        Bool.isNull(Stmt.loadVariable("fv" + idx)),
                        Stmt.loadVariable("fv" + idx).invoke("isEmpty")))
                .append(
                    Stmt.loadVariable("this")
                        .invoke(
                            injectorName,
                            Stmt.loadVariable("widget"),
                            defaultValueStatement(erasedFieldType)))
                .finish()
                .else_()
                .append(
                    Stmt.loadVariable("this")
                        .invoke(
                            injectorName,
                            Stmt.loadVariable("widget"),
                            paramFromStringStatement(
                                erasedFieldType,
                                Stmt.loadVariable("fv" + idx).invoke("iterator").invoke("next"))))
                .append(
                    Stmt.loadVariable("pageState")
                        .invoke(
                            "put",
                            fieldName,
                            Stmt.loadVariable("fv" + idx).invoke("iterator").invoke("next")))
                .finish());
      }
      idx++;
    }

    if (addPrivateAccessors) {
      method.append(
          Stmt.invokeStatic(
              CDI.class,
              "fireEvent",
              Stmt.newObject(NavigationEvent.class)
                  .withParameters(
                      Stmt.newObject(PageRequest.class)
                          .withParameters(
                              getPageName(pageClass), Stmt.loadVariable("pageState")))));
    }

    checkMethodAndAddPrivateAccessors(
        pageImplBuilder, method, pageClass, annotation, HistoryToken.class, "state");

    method.finish();
  }