Beispiel #1
0
  @Override
  public Collection<MetaClass> provideTypesToExpose() {
    final Set<MetaClass> types = new HashSet<MetaClass>();
    for (final MetaClass metaClass : ClassScanner.getTypesAnnotatedWith(Remote.class)) {
      for (final MetaMethod method : metaClass.getDeclaredMethods()) {
        if (!method.getReturnType().isVoid()) {
          types.add(method.getReturnType().getErased());
        }
        for (final MetaParameter parameter : method.getParameters()) {
          final MetaClass type = parameter.getType();

          types.add(type.getErased());

          final MetaParameterizedType parameterizedType = type.getParameterizedType();
          if (parameterizedType != null) {
            for (final MetaType tp : parameterizedType.getTypeParameters()) {
              if (tp instanceof MetaClass) {
                types.add(((MetaClass) tp).getErased());
              }
            }
          }
        }
      }
    }
    return types;
  }
  /**
   * Returns all bindable types on the classpath.
   *
   * @param context the current generator context
   * @return a set of meta classes representing the all bindable types (both annotated and
   *     configured in ErraiApp.properties).
   */
  public static Set<MetaClass> getAllBindableTypes(final GeneratorContext context) {
    Collection<MetaClass> annotatedBindableTypes =
        ClassScanner.getTypesAnnotatedWith(
            Bindable.class, RebindUtils.findTranslatablePackages(context), context);

    Set<MetaClass> bindableTypes = new HashSet<MetaClass>(annotatedBindableTypes);
    bindableTypes.addAll(DataBindingUtil.getConfiguredBindableTypes());
    return bindableTypes;
  }
Beispiel #3
0
  private static EnvironmentConfig loadConfiguredPortableTypes() {
    final Map<String, String> frameworkProps = new HashMap<String, String>();
    final Map<String, String> mappingAliases = new HashMap<String, String>();
    final Set<MetaClass> exposedClasses = new HashSet<MetaClass>();
    final Set<MetaClass> nonportableClasses = new HashSet<MetaClass>();
    final Set<String> explicitTypes = new HashSet<String>();
    final Set<MetaClass> portableNonExposed = new HashSet<MetaClass>();

    final Set<MetaClass> exposedFromScanner =
        new HashSet<MetaClass>(ClassScanner.getTypesAnnotatedWith(Portable.class));
    nonportableClasses.addAll(ClassScanner.getTypesAnnotatedWith(NonPortable.class));

    for (final MetaClass cls : exposedFromScanner) {
      for (final MetaClass decl : cls.getDeclaredClasses()) {
        if (decl.isSynthetic()) {
          continue;
        }

        exposedClasses.add(decl);
      }
    }

    exposedClasses.addAll(exposedFromScanner);

    final Enumeration<URL> erraiAppProperties = getErraiAppProperties();
    while (erraiAppProperties.hasMoreElements()) {
      InputStream inputStream = null;
      try {
        final URL url = erraiAppProperties.nextElement();

        log.debug("checking " + url.getFile() + " for configured types ...");

        inputStream = url.openStream();

        final ResourceBundle props = new PropertyResourceBundle(inputStream);
        if (props != null) {

          for (final Object o : props.keySet()) {
            final String key = (String) o;

            frameworkProps.put(key, props.getString(key));

            if (key.equals(CONFIG_ERRAI_SERIALIZABLE_TYPE)) {
              for (final String s : props.getString(key).split(" ")) {
                try {
                  exposedClasses.add(MetaClassFactory.get(s.trim()));
                  explicitTypes.add(s.trim());
                } catch (Exception e) {
                  throw new RuntimeException(
                      "could not find class defined in ErraiApp.properties for serialization: "
                          + s);
                }
              }

              continue;
            }

            if (key.equals(CONFIG_ERRAI_NONSERIALIZABLE_TYPE)) {
              for (final String s : props.getString(key).split(" ")) {
                try {
                  nonportableClasses.add(MetaClassFactory.get(s.trim()));
                } catch (Exception e) {
                  throw new RuntimeException(
                      "could not find class defined in ErraiApp.properties as nonserializable: "
                          + s);
                }
              }

              continue;
            }

            if (key.equals(CONFIG_ERRAI_MAPPING_ALIASES)) {
              for (final String s : props.getString(key).split(" ")) {
                try {
                  final String[] mapping = s.split("->");

                  if (mapping.length != 2) {
                    throw new RuntimeException("syntax error: mapping for marshalling alias: " + s);
                  }

                  final Class<?> fromMapping = Class.forName(mapping[0].trim());
                  final Class<?> toMapping = Class.forName(mapping[1].trim());

                  mappingAliases.put(fromMapping.getName(), toMapping.getName());
                  explicitTypes.add(fromMapping.getName());
                  explicitTypes.add(toMapping.getName());
                } catch (Exception e) {
                  throw new RuntimeException(
                      "could not find class defined in ErraiApp.properties for mapping: " + s);
                }
              }
              continue;
            }
          }
        }
      } catch (IOException e) {
        throw new RuntimeException("error reading ErraiApp.properties", e);
      } finally {
        if (inputStream != null) {
          try {
            inputStream.close();
          } catch (IOException e) {
            //
          }
        }
      }
    }

    // must do this before filling in interfaces and supertypes!
    exposedClasses.removeAll(nonportableClasses);

    for (final MetaClass cls : exposedClasses) {
      fillInInterfacesAndSuperTypes(portableNonExposed, cls);
    }

    return new EnvironmentConfig(
        mappingAliases, exposedClasses, portableNonExposed, explicitTypes, frameworkProps);
  }
  @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();
  }