/** * Checks type and its supertypes for {@link ExtraTypes} annotations. * * @param type the type to examine * @param addModelExtraTypes if {@code true} the contents of the {@link #extraTypes} field will be * added to the returned list. */ private List<EntityProxyModel> checkExtraTypes(JClassType type, boolean addModelExtraTypes) throws UnableToCompleteException { Set<EntityProxyModel> toReturn = new LinkedHashSet<EntityProxyModel>(); if (addModelExtraTypes && extraTypes != null) { toReturn.addAll(extraTypes); } for (JClassType toExamine : type.getFlattenedSupertypeHierarchy()) { ExtraTypes proxyExtraTypes = toExamine.getAnnotation(ExtraTypes.class); if (proxyExtraTypes != null) { for (Class<? extends BaseProxy> clazz : proxyExtraTypes.value()) { JClassType proxy = oracle.findType(clazz.getCanonicalName()); if (proxy == null) { poison( "Unknown class %s in @%s", clazz.getCanonicalName(), ExtraTypes.class.getSimpleName()); } else { toReturn.add(getEntityProxyType(proxy)); } } } } if (toReturn.isEmpty()) { return Collections.emptyList(); } return new ArrayList<EntityProxyModel>(toReturn); }
@Override public MetaMethod[] getMethods() { final Set<MetaMethod> meths = new LinkedHashSet<MetaMethod>(); meths.addAll(getSpecialTypeMethods()); JClassType type = getEnclosedMetaObject().isClassOrInterface(); if (type == null) { return null; } do { for (final JMethod jMethod : type.getMethods()) { if (!jMethod.isPrivate()) { meths.add(new GWTMethod(oracle, jMethod)); } } for (final JClassType interfaceType : type.getImplementedInterfaces()) { meths.addAll(Arrays.asList(GWTClass.newInstance(oracle, interfaceType).getMethods())); } } while ((type = type.getSuperclass()) != null && !type.getQualifiedSourceName().equals("java.lang.Object")); meths.addAll(overrideMethods); return meths.toArray(new MetaMethod[meths.size()]); }
/** * Given a UiBinder interface, return the path to its ui.xml file, suitable for any classloader to * find it as a resource. */ private static String deduceTemplateFile(MortalLogger logger, JClassType interfaceType) throws UnableToCompleteException { String templateName = null; UiTemplate annotation = interfaceType.getAnnotation(UiTemplate.class); if (annotation == null) { // if the interface is defined as a nested class, use the name of the // enclosing type if (interfaceType.getEnclosingType() != null) { interfaceType = interfaceType.getEnclosingType(); } return slashify(interfaceType.getQualifiedBinaryName()) + TEMPLATE_SUFFIX; } else { templateName = annotation.value(); if (!templateName.endsWith(TEMPLATE_SUFFIX)) { logger.die("Template file name must end with " + TEMPLATE_SUFFIX); } /* * If the template file name (minus suffix) has no dots, make it relative * to the binder's package, otherwise slashify the dots */ String unsuffixed = templateName.substring(0, templateName.lastIndexOf(TEMPLATE_SUFFIX)); if (!unsuffixed.contains(".")) { templateName = slashify(interfaceType.getPackage().getName()) + "/" + templateName; } else { templateName = slashify(unsuffixed) + TEMPLATE_SUFFIX; } } return templateName; }
Annotation[] extractAnnotations( TreeLogger logger, JClassType type, JMethod ifaceMethod, JMethod classMethod, GeneratorContext ctx) { Map<Class<?>, Annotation> unique = new LinkedHashMap<Class<?>, Annotation>(); // Prefer annotation on classes before interfaces. for (Annotation classAnno : classMethod.getAnnotations()) { unique.put(classAnno.annotationType(), classAnno); } // Transverse supertypes JClassType next = type.getSuperclass(); while (next != null) { JMethod method = next.findMethod(ifaceMethod.getName(), ifaceMethod.getParameterTypes()); if (method != null) for (Annotation classAnno : method.getAnnotations()) { unique.put(classAnno.annotationType(), classAnno); } next = next.getSuperclass(); } for (Annotation ifaceAnno : ifaceMethod.getAnnotations()) { unique.put(ifaceAnno.annotationType(), ifaceAnno); } return unique.values().toArray(new Annotation[unique.size()]); }
/** Examine a RequestContext subtype to populate a ContextMethod. */ private void buildContextMethod(ContextMethod.Builder contextBuilder, JClassType contextType) throws UnableToCompleteException { Service serviceAnnotation = contextType.getAnnotation(Service.class); ServiceName serviceNameAnnotation = contextType.getAnnotation(ServiceName.class); JsonRpcService jsonRpcAnnotation = contextType.getAnnotation(JsonRpcService.class); if (serviceAnnotation == null && serviceNameAnnotation == null && jsonRpcAnnotation == null) { poison( "RequestContext subtype %s is missing a @%s or @%s annotation", contextType.getQualifiedSourceName(), Service.class.getSimpleName(), JsonRpcService.class.getSimpleName()); return; } List<RequestMethod> requestMethods = new ArrayList<RequestMethod>(); for (JMethod method : contextType.getInheritableMethods()) { if (method.getEnclosingType().equals(requestContextInterface)) { // Ignore methods declared in RequestContext continue; } RequestMethod.Builder methodBuilder = new RequestMethod.Builder(); methodBuilder.setDeclarationMethod(contextType, method); if (!validateContextMethodAndSetDataType(methodBuilder, method, jsonRpcAnnotation != null)) { continue; } requestMethods.add(methodBuilder.build()); } contextBuilder .setExtraTypes(checkExtraTypes(contextType, true)) .setRequestMethods(requestMethods); }
protected void generateCheckRpcTokenTypeOverride( SourceWriter srcWriter, TypeOracle typeOracle, SerializableTypeOracle typesSentFromBrowser) { JClassType rpcTokenType = typeOracle.findType(RpcToken.class.getName()); JClassType[] rpcTokenSubtypes = rpcTokenType.getSubtypes(); String rpcTokenImplementation = ""; for (JClassType rpcTokenSubtype : rpcTokenSubtypes) { if (typesSentFromBrowser.isSerializable(rpcTokenSubtype)) { if (rpcTokenImplementation.length() > 0) { // >1 implematation of RpcToken, bail rpcTokenImplementation = ""; break; } else { rpcTokenImplementation = rpcTokenSubtype.getQualifiedSourceName(); } } } if (rpcTokenImplementation.length() > 0) { srcWriter.println("@Override"); srcWriter.println("protected void checkRpcTokenType(RpcToken token) {"); srcWriter.indent(); srcWriter.println("if (!(token instanceof " + rpcTokenImplementation + ")) {"); srcWriter.indent(); srcWriter.println( "throw new RpcTokenException(\"Invalid RpcToken type: " + "expected '" + rpcTokenImplementation + "' but got '\" + " + "token.getClass() + \"'\");"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.outdent(); srcWriter.println("}"); } }
@Override void toJS(FragmentGeneratorContext context) throws UnableToCompleteException { TreeLogger logger = context.parentLogger.branch( TreeLogger.DEBUG, "Writing function() wrapper for JSFunction", null); SourceWriter sw = context.sw; TypeOracle typeOracle = context.typeOracle; JClassType functionClass = context.returnType.isClassOrInterface(); if (functionClass.equals(typeOracle.findType(JSFunction.class.getName()))) { logger.log( TreeLogger.ERROR, "You must use a subinterface of JSFunction" + " so that the generator can extract a method signature.", null); throw new UnableToCompleteException(); } // This is to support the JSFunction having the same lifetime as the // JSFunction object without having to use GWT.create on every JSFunction // object as that would discourage anonymous classes. sw.print("("); sw.print(context.parameterName); // sw.print("[email protected]::exportedFunction || ("); sw.print(".@" + JSFunction.class.getName() + "::exportedFunction || ("); sw.print(context.parameterName); // sw.print("[email protected]::exportedFunction = "); sw.print(".@" + JSFunction.class.getName() + "::exportedFunction = "); writeFunctionForMethod(context, findExportedMethod(logger, functionClass)); sw.print("))"); }
/** @return the simple name of the proxy object. */ @Override public String getProxySimpleName() { JClassType enclosingType = baseIntf.getEnclosingType(); String enclosingTypeName = (enclosingType == null ? "" : enclosingType.getSimpleSourceName() + "_"); return enclosingTypeName + baseIntf.getSimpleSourceName() + "_SQL_Impl"; }
/** * A restricted version of areClassTypesAssignable that is used for comparing the type arguments * of parameterized types, where the lhsTypeArg is the container. */ private static boolean doesTypeArgumentContain(JClassType lhsTypeArg, JClassType rhsTypeArg) { if (lhsTypeArg == rhsTypeArg) { return true; } // Check for wildcard types JWildcardType lhsWildcard = lhsTypeArg.isWildcard(); JWildcardType rhsWildcard = rhsTypeArg.isWildcard(); if (lhsWildcard != null) { if (rhsWildcard != null) { return areWildcardsAssignable(lhsWildcard, rhsWildcard); } else { // LHS is a wildcard but the RHS is not. if (lhsWildcard.getLowerBounds().length > 0) { return areClassTypesAssignable(rhsTypeArg, lhsWildcard.getFirstBound()); } else { return areClassTypesAssignable(lhsWildcard.getFirstBound(), rhsTypeArg); } } } /* * At this point the arguments are not the same and they are not wildcards * so, they cannot be assignable, Eh. */ return false; }
// BEGIN MODIFICATION private FieldManager getFieldManager( TypeOracle oracle, MortalLogger logger, PropertyOracle propertyOracle, boolean useLazyWidgetBuilder) throws UnableToCompleteException { // Find ginjector FieldManager fieldManager; try { String ginjectorClassName = propertyOracle.getConfigurationProperty("gin.ginjector").getValues().get(0); JClassType ginjectorClass = oracle.findType(ginjectorClassName); if (ginjectorClass == null || !ginjectorClass.isAssignableTo(oracle.findType(Ginjector.class.getCanonicalName()))) { logger.die( "The configuration property 'gin.ginjector' is '%s' " + " which doesn't identify a type inheriting from 'Ginjector'.", ginjectorClassName); } fieldManager = new GinFieldManager(oracle, logger, ginjectorClass, useLazyWidgetBuilder); } catch (BadPropertyValueException e) { logger.warn( "The configuration property 'gin.ginjector' was not found, it is required to use " + "gin injection for UiBinder fields. If you don't need this consider using " + "UiBinder.gwt.xml instead of GinUiBinder.gwt.xml in your module."); fieldManager = new FieldManager(oracle, logger, useLazyWidgetBuilder); } return fieldManager; }
private static Map<JType, JClassType> findCustomSerializers(TypeOracle oracle) throws NotFoundException { Map<JType, JClassType> serializers = new HashMap<JType, JClassType>(); JClassType serializerInterface = oracle.findType(JSONSerializer.class.getName()); JType[] deserializeParamTypes = new JType[] { oracle.findType(com.vaadin.client.metadata.Type.class.getName()), oracle.findType(JSONValue.class.getName()), oracle.findType(ApplicationConnection.class.getName()) }; String deserializeMethodName = "deserialize"; // Just test that the method exists serializerInterface.getMethod(deserializeMethodName, deserializeParamTypes); for (JClassType serializer : serializerInterface.getSubtypes()) { JMethod deserializeMethod = serializer.findMethod(deserializeMethodName, deserializeParamTypes); if (deserializeMethod == null) { continue; } JType returnType = deserializeMethod.getReturnType(); serializers.put(returnType, serializer); } return serializers; }
private static void checkTooMany(String methodName, JClassType serializer, List<String> reasons) { JMethod[] overloads = serializer.getOverloads(methodName); if (overloads.length > 1) { reasons.add( MessageFormat.format(TOO_MANY_METHODS, serializer.getQualifiedSourceName(), methodName)); } }
@Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { this.logger = logger; typeOracle = context.getTypeOracle(); try { // find XulEventSource implementors implementingTypes = new ArrayList<JClassType>(); JClassType eventSourceType = typeOracle.getType("org.pentaho.ui.xul.XulEventSource"); for (JClassType type : typeOracle.getTypes()) { if (type.isAssignableTo(eventSourceType)) { implementingTypes.add(type); } } // get classType and save instance variables JClassType classType = typeOracle.getType(typeName); packageName = classType.getPackage().getName(); className = classType.getSimpleSourceName() + "Impl"; // Generate class source code generateClass(logger, context); } catch (Exception e) { // record to logger that Map generation threw an exception logger.log(TreeLogger.ERROR, "Error generating BindingContext!!!", e); } // return the fully qualifed name of the class generated return packageName + "." + className; }
private boolean isIntrospectable(TreeLogger logger, JType type) { if (type == null) { return false; } JClassType ct = type.isClassOrInterface(); if (ct != null) { if (ct.getAnnotation(Introspectable.class) != null) { return true; } for (JClassType iface : ct.getImplementedInterfaces()) { if (isIntrospectable(logger, iface)) { return true; } } if (isIntrospectable(logger, ct.getSuperclass())) { return true; } } return false; }
/** * Writes a method to produce a map of class name to type string for Java. * * <pre> * private static Map<String<?>, String> loadSignaturesJava() { * Map<String<?>, String> result = new HashMap<String<?>, String>(); * result.put( * com.google.gwt.user.client.rpc.core.java.lang.String_FieldSerializer.concreteType(), * "java.lang.String/2004016611"); * ... * return result; * } * </pre> */ private void writeLoadSignaturesJava() { srcWriter.println("@SuppressWarnings(\"deprecation\")"); srcWriter.println("private static Map<String, String> loadSignaturesJava() {"); srcWriter.indent(); srcWriter.println("Map<String, String> result = new HashMap<String, String>();"); for (JType type : getSerializableTypes()) { String typeString = typeStrings.get(type); if (!serializationOracle.maybeInstantiated(type) && !deserializationOracle.maybeInstantiated(type)) { continue; } String typeRef; JClassType customSerializer = SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type); if (customSerializer != null && CustomFieldSerializerValidator.getConcreteTypeMethod(customSerializer) != null) { typeRef = customSerializer.getQualifiedSourceName() + ".concreteType()"; } else { typeRef = '"' + SerializationUtils.getRpcTypeName(type) + '"'; } srcWriter.println("result.put(" + typeRef + ", \"" + typeString + "\");"); } srcWriter.println("return result;"); srcWriter.outdent(); srcWriter.println("}"); srcWriter.println(); }
protected void initializeDataObjects() { if (!initialized) { dataObjects = new HashMap<String, String>(); dataObjectIdentifiers = new HashMap<String, String[]>(); JClassType[] dataObjectTypes; try { initializeDefaultDataObjects(); dataObjectTypes = jClassScanner.searchClassesByAnnotation(DataObject.class); } catch (Exception e) { throw new CruxGeneratorException("Error initializing DataObjects scanner.", e); } if (dataObjectTypes != null) { for (JClassType dataClass : dataObjectTypes) { DataObject annot = dataClass.getAnnotation(DataObject.class); if (dataObjects.containsKey(annot.value())) { throw new CruxGeneratorException( "Duplicated alias for DataObject found: [" + annot.value() + "]."); } dataObjects.put(annot.value(), dataClass.getQualifiedSourceName()); dataObjectIdentifiers.put(annot.value(), extractIdentifiers(dataClass)); } } initialized = true; } }
private SourceWriter getSourceWriter( TreeLogger logger, GeneratorContextExt ctx, JClassType serviceAsync) { JPackage serviceIntfPkg = serviceAsync.getPackage(); String packageName = serviceIntfPkg == null ? "" : serviceIntfPkg.getName(); PrintWriter printWriter = ctx.tryCreate(logger, packageName, getProxySimpleName()); if (printWriter == null) { return null; } ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(packageName, getProxySimpleName()); String[] imports = new String[] { getProxySupertype().getCanonicalName(), getStreamWriterClass().getCanonicalName(), SerializationStreamWriter.class.getCanonicalName(), GWT.class.getCanonicalName(), ResponseReader.class.getCanonicalName(), SerializationException.class.getCanonicalName(), RpcToken.class.getCanonicalName(), RpcTokenException.class.getCanonicalName(), Impl.class.getCanonicalName(), RpcStatsContext.class.getCanonicalName() }; for (String imp : imports) { composerFactory.addImport(imp); } composerFactory.setSuperclass(getProxySupertype().getSimpleName()); composerFactory.addImplementedInterface(serviceAsync.getErasedType().getQualifiedSourceName()); return composerFactory.createSourceWriter(ctx, printWriter); }
protected void generateProxyMethods( SourceWriter w, SerializableTypeOracle serializableTypeOracle, TypeOracle typeOracle, Map<JMethod, JMethod> syncMethToAsyncMethMap) { JMethod[] syncMethods = serviceIntf.getOverridableMethods(); for (JMethod syncMethod : syncMethods) { JMethod asyncMethod = syncMethToAsyncMethMap.get(syncMethod); assert (asyncMethod != null); JClassType enclosingType = syncMethod.getEnclosingType(); JParameterizedType isParameterizedType = enclosingType.isParameterized(); if (isParameterizedType != null) { JMethod[] methods = isParameterizedType.getMethods(); for (int i = 0; i < methods.length; ++i) { if (methods[i] == syncMethod) { /* * Use the generic version of the method to ensure that the server * can find the method using the erasure of the generic signature. */ syncMethod = isParameterizedType.getBaseType().getMethods()[i]; } } } generateProxyMethod(w, serializableTypeOracle, typeOracle, syncMethod, asyncMethod); } }
@Override public MetaField[] getFields() { final JClassType type = getEnclosedMetaObject().isClassOrInterface(); if (type == null) { return null; } return fromFieldArray(oracle, type.getFields()); }
static String badContextReturnType( JMethod method, JClassType requestInterface, JClassType instanceRequestInterface) { return String.format( "Return type %s in method %s must be an interface assignable" + " to %s or %s", method.getReturnType(), method.getName(), requestInterface.getSimpleSourceName(), instanceRequestInterface.getSimpleSourceName()); }
@Override public MetaConstructor[] getConstructors() { final JClassType type = getEnclosedMetaObject().isClassOrInterface(); if (type == null) { return null; } return fromMethodArray(oracle, type.getConstructors()); }
private boolean isQueryParamListType(JClassType type) { if (type.isParameterized() == null) { return false; } for (JClassType listType : QUERY_PARAM_LIST_TYPES) { if (type.isAssignableTo(listType)) { return true; } } return false; }
/** * @param className * @return */ private String getInstantiationClass(String className) { if (className.endsWith("Async")) { String serviceInterface = className.substring(0, className.length() - 5); JClassType type = context.getGeneratorContext().getTypeOracle().findType(serviceInterface); if (type != null && type.isAssignableTo(remoteServiceType)) { return type.getQualifiedSourceName(); } } return className; }
/** * Erases the {@link MetaClassFactory} cache, then populates it with types discovered via GWT's * TypeOracle. The reason for the initial flush of the MetaClassFactory is to support hot redeploy * in Dev Mode. The reason for doing this operation at all is so that the overridden class * definitions (super-source classes) are used in preference to the Java reflection based class * definitions. * * @param context The GeneratorContext supplied by the GWT compiler. Not null. * @param logger The TreeLogger supplied by the GWT compiler. Not null. */ public static void populateMetaClassFactoryFromTypeOracle( final GeneratorContext context, final TreeLogger logger) { // if we're in production mode -- it means we're compiling, and we do not need to accommodate // dynamically // changing classes. Therefore, do a NOOP after the first successful call. if (typeOraclePopulated && (context.equals(populatedFrom.get()) || EnvUtil.isProdMode())) { return; } final TypeOracle typeOracle = context.getTypeOracle(); MetaClassFactory.emptyCache(); if (typeOracle != null) { final Set<String> translatable = new HashSet<String>(RebindUtils.findTranslatablePackages(context)); translatable.remove("java.lang"); translatable.remove("java.lang.annotation"); for (final JClassType type : typeOracle.getTypes()) { if (!translatable.contains(type.getPackage().getName())) { logger.log( com.google.gwt.core.ext.TreeLogger.Type.DEBUG, "Skipping non-translatable " + type.getQualifiedSourceName()); continue; } if (type.isAnnotation() != null || type.getQualifiedSourceName().equals("java.lang.annotation.Annotation")) { logger.log( com.google.gwt.core.ext.TreeLogger.Type.DEBUG, "Caching annotation type " + type.getQualifiedSourceName()); if (!MetaClassFactory.canLoadClass(type.getQualifiedBinaryName())) { throw new RuntimeException( "a new annotation has been introduced (" + type.getQualifiedSourceName() + "); " + "you cannot currently introduce new annotations in devmode. Please restart."); } MetaClassFactory.pushCache( JavaReflectionClass.newUncachedInstance( MetaClassFactory.loadClass(type.getQualifiedBinaryName()))); } else { logger.log( com.google.gwt.core.ext.TreeLogger.Type.DEBUG, "Caching translatable type " + type.getQualifiedSourceName()); MetaClassFactory.pushCache(GWTClass.newInstance(typeOracle, type)); } } } typeOraclePopulated = true; populatedFrom = new SoftReference<GeneratorContext>(context); }
/** * Returns {@code true} if the type is assignable to EntityProxy or ValueProxy and has a mapping * to a domain type. * * @see * com.google.web.bindery.requestfactory.server.RequestFactoryInterfaceValidator#shouldAttemptProxyValidation() */ private boolean shouldAttemptProxyValidation(JClassType maybeProxy) { if (!entityProxyInterface.isAssignableFrom(maybeProxy) && !valueProxyInterface.isAssignableFrom(maybeProxy)) { return false; } if (maybeProxy.getAnnotation(ProxyFor.class) == null && maybeProxy.getAnnotation(ProxyForName.class) == null) { return false; } return true; }
public static void checkGenericType(TreeLogger logger, JClassType type) throws UnableToCompleteException { if (type.isGenericType() != null) { logger.log( Type.ERROR, "Type " + type.getParameterizedQualifiedSourceName() + "is parameterizied generic. RPC proxy " + "for parameterizied types is not supported."); throw new UnableToCompleteException(); } }
private void addSerializeSupport(TreeLogger logger, JType type) throws UnableToCompleteException { hasSerializeSupport.add(type); JParameterizedType parametrized = type.isParameterized(); if (parametrized != null) { for (JClassType parameterType : parametrized.getTypeArgs()) { setNeedsSerialize(parameterType); } } if (serializationHandledByFramework(type)) { return; } JClassType customSerializer = customSerializers.get(type); JClassType typeAsClass = type.isClass(); JEnumType enumType = type.isEnum(); JArrayType arrayType = type.isArray(); if (customSerializer != null) { logger.log(Type.INFO, "Will serialize " + type + " using " + customSerializer.getName()); setSerializer(type, new CustomSerializer(customSerializer)); } else if (arrayType != null) { logger.log(Type.INFO, "Will serialize " + type + " as an array"); setSerializer(type, new ArraySerializer(arrayType)); setNeedsSerialize(arrayType.getComponentType()); } else if (enumType != null) { logger.log(Type.INFO, "Will serialize " + type + " as an enum"); setSerializer(type, new EnumSerializer(enumType)); } else if (typeAsClass != null) { // Bean checkSerializable(logger, typeAsClass); logger.log(Type.INFO, "Will serialize " + type + " as a bean"); JClassType needsSuperClass = typeAsClass; while (needsSuperClass != null) { if (needsSuperClass.isPublic()) { setNeedsSuperclass(needsSuperClass); } needsSuperClass = needsSuperClass.getSuperclass(); } setNeedsGwtConstructor(typeAsClass); for (Property property : getProperties(typeAsClass)) { setNeedsProperty(property); JType propertyType = property.getPropertyType(); setNeedsSerialize(propertyType); } } }
@Override protected ServiceBinding getServiceBinding() { if (serviceBinding == null) { String implName = service.getName() + SUFFIX; serviceBinding = new ServiceBinding(path, getPackage(), implName, service.getName()); serviceBinding.setSuperTypeName(service.getName()); serviceBinding.setSecured(!service.isAnnotationPresent(NoXsrfHeader.class)); } return serviceBinding; }
@Override public MetaClass[] getInterfaces() { final JClassType jClassType = getEnclosedMetaObject().isClassOrInterface(); if (jClassType == null) return new MetaClass[0]; final List<MetaClass> metaClassList = new ArrayList<MetaClass>(); for (final JClassType type : jClassType.getImplementedInterfaces()) { metaClassList.add(new GWTClass(oracle, type, false)); } return metaClassList.toArray(new MetaClass[metaClassList.size()]); }
/** * @param srcWriter * @param type * @param parentVariable * @param added * @param iocContainerVariable * @param configurations */ private static void injectMethods( SourcePrinter srcWriter, JClassType type, String parentVariable, Set<String> added, String iocContainerVariable, Map<String, IocConfig<?>> configurations) { for (JMethod method : type.getMethods()) { Inject inject = method.getAnnotation(Inject.class); if (inject != null && !method.isStatic()) { String methodName = method.getName(); if (!added.contains(methodName + "()")) { added.add(methodName + "()"); JParameter[] parameters = method.getParameters(); List<String> params = new ArrayList<String>(); for (JParameter parameter : parameters) { JType parameterType = parameter.getType(); if ((parameterType.isPrimitive() != null)) { throw new IoCException( "IoC Error Method [" + methodName + "] from class [" + type.getQualifiedSourceName() + "] declares an invalid parameter. Primitive types are not allowed here"); } String variableName = "parameter_" + methodName + "_" + parameter.getName(); params.add(variableName); String injectionExpression = getParameterInjectionExpression(parameter, iocContainerVariable, configurations); srcWriter.println( parameterType.getQualifiedSourceName() + " " + variableName + " = " + injectionExpression + ";"); } srcWriter.print(parentVariable + "." + methodName + "("); boolean first = true; for (String param : params) { if (!first) { srcWriter.print(", "); } first = false; srcWriter.print(param); } srcWriter.println(");"); } } } }