@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); }
/** * @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; }