Example #1
0
  @Override
  public String generate(TreeLogger logger, GeneratorContext genCtx, String fqInterfaceName)
      throws UnableToCompleteException {
    TypeOracle oracle = genCtx.getTypeOracle();
    ResourceOracle resourceOracle = genCtx.getResourcesOracle();

    JClassType interfaceType;
    try {
      interfaceType = oracle.getType(fqInterfaceName);
    } catch (NotFoundException e) {
      throw new RuntimeException(e);
    }

    DesignTimeUtils designTime;
    if (DesignTimeUtilsImpl.isDesignTime(fqInterfaceName)) {
      designTime = new DesignTimeUtilsImpl();
    } else {
      designTime = DesignTimeUtilsStub.EMPTY;
    }

    String implName = interfaceType.getName().replace('.', '_') + "Impl";
    implName = designTime.getImplName(implName);

    String packageName = interfaceType.getPackage().getName();
    PrintWriterManager writers = new PrintWriterManager(genCtx, logger, packageName);
    PrintWriter printWriter = writers.tryToMakePrintWriterFor(implName);

    if (printWriter != null) {
      generateOnce(
          interfaceType,
          implName,
          printWriter,
          logger,
          oracle,
          resourceOracle,
          genCtx.getPropertyOracle(),
          writers,
          designTime);
    }
    return packageName + "." + implName;
  }
  /**
   * Generate an implementation for the given type.
   *
   * @param logger error logger
   * @param context generator context
   * @param typeName target type name
   * @return generated class name
   * @throws UnableToCompleteException
   */
  @Override
  public final String generate(TreeLogger logger, GeneratorContext context, String typeName)
      throws UnableToCompleteException {
    assert CURRENCY_LIST.equals(typeName);
    TypeOracle typeOracle = context.getTypeOracle();

    PropertyOracle propertyOracle = context.getPropertyOracle();
    LocaleUtils localeUtils = LocaleUtils.getInstance(logger, propertyOracle, context);
    GwtLocale locale = localeUtils.getCompileLocale();
    Set<GwtLocale> runtimeLocales = localeUtils.getRuntimeLocales();

    JClassType targetClass;
    try {
      targetClass = typeOracle.getType(typeName);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "No such type", e);
      throw new UnableToCompleteException();
    }
    if (runtimeLocales.isEmpty()) {
      return generateLocaleTree(logger, context, targetClass, locale);
    }
    CachedGeneratorContext cachedContext = new CachedGeneratorContext(context);
    return generateRuntimeSelection(logger, cachedContext, targetClass, locale, runtimeLocales);
  }
Example #3
0
  /**
   * @param logger
   * @param context
   * @param typeName
   * @param gr
   * @return
   */
  public boolean isGenerate(
      TreeLogger logger, GeneratorContext context, String typeName, GenPredicGroup gr) {
    boolean result = false;
    if ((gr.getMyGroups() != null) && (gr.getMyGroups().size() > 0)) {
      for (GenPredicGroup group : gr.getMyGroups()) {
        switch (gr.getOperator()) {
          case ANY:
            result = result || isGenerate(logger, context, typeName, group);
            break;
          case NONE:
            result = !isGenerate(logger, context, typeName, group);
            if (!result) return false;
            break;
          case ALL:
            result = isGenerate(logger, context, typeName, group);
            if (!result) return false;
          default:
            break;
        }
      }
    }
    if ((gr.getGeneratorPredicts() != null) && (gr.getGeneratorPredicts().size() > 0)) {
      for (GeneratorPredicate entry : gr.getGeneratorPredicts()) {
        String value = null;
        try {
          switch (entry.getEPredict()) {
            case ASSIGNABLE:
              if (context
                  .getTypeOracle()
                  .findType(typeName)
                  .isAssignableTo(context.getTypeOracle().getType(entry.getValue()))) {
                value = entry.getValue();
              } else {
                value = typeName;
              }
              break;
            case TYPEIS:
              value = typeName;
              break;
            case PROPERTY:
              // ???he
              value =
                  context
                      .getPropertyOracle()
                      .getSelectionProperty(logger, entry.getName())
                      .getCurrentValue();
              break;
            default:
              value = null;
              break;
          }
        } catch (Exception e) {
          value = null;
          result = false;
        }

        if (value != null) {
          switch (gr.getOperator()) {
            case ANY:
              result = result || entry.getValue().equals(value);
              break;
            case NONE:
              result = !entry.getValue().equals(value);
              if (!result) return false;
              break;
            case ALL:
              result = entry.getValue().equals(value);
              if (!result) return false;
            default:
              break;
          }
        }
      }
    }
    return result;
  }
  protected void tryWriteMetaInf(
      TreeLogger logger, Class<?> cls, JClassType impl, GeneratorContext context) {
    String serviceInterface = cls.getName();
    String serviceImplementation = impl.getQualifiedBinaryName();
    ArrayList<File> outputDirs = new ArrayList<File>();
    PropertyOracle properties = context.getPropertyOracle();
    try {
      File root = new File("");
      if (root.getAbsolutePath().endsWith("war"))
        root = new File(root.getAbsolutePath().replace(separator + "war", "") + separator);
      else root = new File(root.getAbsolutePath());
      ConfigurationProperty output = properties.getConfigurationProperty("xinject.output.dir");
      for (String dir : output.getValues()) {
        File f = new File(root, dir);
        if (f.isDirectory()) {
          outputDirs.add(f);
          f = new File(f, "META-INF" + separator + "services");
          if (!f.exists()) {
            if (!f.mkdirs()) {
              logger.log(
                  Type.WARN,
                  "Unable to create META-INF"
                      + separator
                      + "services "
                      + " in "
                      + f.getAbsolutePath()
                      + " "
                      + "Please ensure this directory exists, and is writable.");
            }
          }
        } else {
          logger.log(
              Type.WARN,
              "Missing xinject output directory: "
                  + f.getAbsolutePath()
                  + ". "
                  + "Please set xinject.output.dir to existing source directories; current value: "
                  + output.getValues());
        }
      }
    } catch (BadPropertyValueException e1) {
      logger.log(Type.WARN, "Unexpected propery exception for xinject.output.dir", e1);
    }
    try {
      String prefix =
          ".."
              + separator
              + "WEB-INF"
              + separator
              + "classes"
              + separator
              + "META-INF"
              + separator
              + "singletons"
              + separator;
      // TODO use a typed artifact to let the linker have a peak if it needs to
      OutputStream res = context.tryCreateResource(logger, prefix + serviceInterface);
      res.write(serviceImplementation.getBytes());
      context.commitResource(logger, res).setVisibility(Visibility.Public);
    } catch (UnableToCompleteException e) {
      logger.log(Type.ERROR, "Couldn't write java services to META-INF/singeltons", e);
    } catch (IOException e) {
      logger.log(
          Type.ERROR,
          "Couldn't write java services to META-INF/singletons; please ensure the war folder has full write access and the disk is not full.",
          e);
      e.printStackTrace();
    }

    logger.log(
        Type.TRACE,
        "Saving META-INF/singletons for " + serviceInterface + " -> " + serviceImplementation);
    exports:
    for (File output : outputDirs) {
      String knownContent = null;
      // check for existing META-INF/singletons entries, so we don't clobber anything
      File existing =
          new File(output, "META-INF" + separator + "services" + separator + serviceInterface);
      logger.log(Type.TRACE, "Saving ServiceLoader descriptor to " + existing.getAbsolutePath());
      if (existing.isFile()) {
        // need to read in existing manifest, and skip if service already exists
        BufferedReader reader = null;
        FileInputStream in = null;
        try {
          in = new FileInputStream(existing);
          reader = new BufferedReader(new InputStreamReader(in));

          String line;
          StringBuilder b = new StringBuilder();
          while ((line = reader.readLine()) != null) {
            if (line.equals(serviceImplementation)) {
              // the service impl already exists; skip to next output dir
              // TODO put in a flag to override top permission.
              try {
                ConfigurationProperty prop =
                    context
                        .getPropertyOracle()
                        .getConfigurationProperty("xinject.overwrite.existing");
                List<String> values = prop.getValues();
                if (values.size() > 0)
                  if (values.get(0).matches("true")) {
                    // if we're supposed to overwrite the value, but it's already on top
                    if (b.length() == 0) {
                      continue exports; // skip the file write
                    }
                    continue; // this erases the existing value so we can put it back over top.
                    // it also skips the breaking-continue below.
                  }
              } catch (BadPropertyValueException e) {
                logger.log(Type.TRACE, "", e);
              }
              // if we've found the service, and are not allowed to move it to top,
              continue exports; // carry on in the loop above.
            }
            b.append(line + "\n");
          }
          knownContent = b.toString().substring(0, b.length() - 1);
        } catch (IOException e) {
          logger.log(
              Type.WARN,
              "Received io exception writing META-INF/service for " + existing.getAbsolutePath());
        } finally {
          try {

            if (in != null) in.close();
            if (reader != null) reader.close();
          } catch (IOException e) {
          }
        }
      }
      // save a new java service descriptor
      FileWriter writer = null;
      try {
        try {
          boolean exists = existing.isFile();
          if (!exists) {
            if (!existing.createNewFile()) {
              logger.log(Type.WARN, "Could not create output file for " + existing);
              continue exports;
            }
          }
          writer = new FileWriter(existing, false);
          if (knownContent == null) {
            writer.append(serviceImplementation);
          } else {
            writer.append(serviceImplementation);
            writer.append('\n');
            writer.append(knownContent);
          }
        } finally {
          if (writer != null) {
            writer.close();
          }
        }
      } catch (IOException e) {
        logger.log(
            Type.WARN,
            "File write exception trying to save META-INF/singletons for " + existing,
            e);
      }
    }
  }
 private PropertyOracle mockPropertyOracle() {
   when(context.getPropertyOracle()).thenReturn(propertyOracle);
   return propertyOracle;
 }