Пример #1
0
  /**
   * 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();
  }
Пример #2
0
 public static Collection<Statement> createAllPropertyBindings(final Statement proxyRef,
                                                               final Map<String, ProxyProperty> proxyProperties) {
   final List<Statement> statementList = new ArrayList<Statement>();
   for (final Map.Entry<String, ProxyProperty> entry : proxyProperties.entrySet()) {
     statementList.add(Stmt.nestedCall(proxyRef).invoke("$set_" + entry.getKey(), entry.getValue().getOriginalValueReference()));
   }
   return statementList;
 }
Пример #3
0
 public static Statement closeProxy(final Statement proxyReference, final Statement beanInstance) {
   return Stmt.nestedCall(proxyReference).invoke(PROXY_BIND_METHOD, beanInstance);
 }
Пример #4
0
  @Override
  protected String generate(TreeLogger logger, GeneratorContext context) {
    final ClassStructureBuilder<?> classBuilder =
        Implementations.extend(NavigationGraph.class, GENERATED_CLASS_NAME);

    // accumulation of (name, pageclass) mappings for dupe detection and dot file generation
    BiMap<String, MetaClass> pageNames = HashBiMap.create();

    // accumulation UniquePageRoles for ensuring there is exactly one.
    Multimap<Class<?>, MetaClass> pageRoles = ArrayListMultimap.create();

    ConstructorBlockBuilder<?> ctor = classBuilder.publicConstructor();
    final Collection<MetaClass> pages = ClassScanner.getTypesAnnotatedWith(Page.class, context);
    for (MetaClass pageClass : pages) {
      if (!pageClass.isAssignableTo(IsWidget.class)) {
        throw new GenerationException(
            "Class "
                + pageClass.getFullyQualifiedName()
                + " is annotated with @Page, so it must implement IsWidget");
      }
      Page annotation = pageClass.getAnnotation(Page.class);
      String pageName = getPageName(pageClass);
      List<Class<? extends PageRole>> annotatedPageRoles = Arrays.asList(annotation.role());

      MetaClass prevPageWithThisName = pageNames.put(pageName, pageClass);
      if (prevPageWithThisName != null) {
        throw new GenerationException(
            "Page names must be unique, but "
                + prevPageWithThisName
                + " and "
                + pageClass
                + " are both named ["
                + pageName
                + "]");
      }
      Statement pageImplStmt = generateNewInstanceOfPageImpl(pageClass, pageName);
      if (annotatedPageRoles.contains(DefaultPage.class)) {
        // need to assign the page impl to a variable and add it to the map twice
        ctor.append(Stmt.declareFinalVariable("defaultPage", PageNode.class, pageImplStmt));
        pageImplStmt = Variable.get("defaultPage");
        ctor.append(Stmt.nestedCall(Refs.get("pagesByName")).invoke("put", "", pageImplStmt));
        ctor.append(
            Stmt.nestedCall(Refs.get("pagesByRole"))
                .invoke("put", DefaultPage.class, pageImplStmt));
      } else if (pageName.equals("")) {
        throw new GenerationException(
            "Page "
                + pageClass.getFullyQualifiedName()
                + " has an empty path. Only the"
                + " page with startingPage=true is permitted to have an empty path.");
      }

      final String fieldName = StringUtils.uncapitalize(pageClass.getName());
      ctor.append(Stmt.declareFinalVariable(fieldName, PageNode.class, pageImplStmt));
      ctor.append(
          Stmt.nestedCall(Refs.get("pagesByName")).invoke("put", pageName, Refs.get(fieldName)));

      for (Class<? extends PageRole> annotatedPageRole : annotatedPageRoles) {
        pageRoles.put(annotatedPageRole, pageClass);
        // DefaultPage is already added above.
        if (!annotatedPageRole.equals(DefaultPage.class))
          ctor.append(
              Stmt.nestedCall(Refs.get("pagesByRole"))
                  .invoke("put", annotatedPageRole, Refs.get(fieldName)));
      }
    }
    ctor.finish();

    renderNavigationToDotFile(pageNames);

    validateDefaultPagePresent(pages, pageRoles);
    validateUnique(pageRoles);

    return classBuilder.toJavaString();
  }