protected void injectDomainHandler( ClassNode classNode, String implementation, String datasource) { classNode.addMethod( new MethodNode( DOMAIN_HANDLER_METHOD_NAME, Modifier.PUBLIC | Modifier.STATIC, GRIFFON_DOMAIN_HANDLER_CLASS, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returns(domainHandlerInstance()))); classNode.addMethod( new MethodNode( MAPPING, Modifier.PUBLIC | Modifier.STATIC, ClassHelper.STRING_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returns(constx(implementation)))); classNode.addMethod( new MethodNode( DATASOURCE, Modifier.PUBLIC | Modifier.STATIC, ClassHelper.STRING_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returns(constx(datasource)))); }
protected void injectMethodMissing(ClassNode classNode) { FieldNode methodMissingInterceptor = classNode.addField( "this$methodMissingInterceptor", Modifier.FINAL | Modifier.STATIC | Modifier.PRIVATE | ACC_SYNTHETIC, METHOD_MISSING_INTERCEPTOR_CLASS, ctor( METHOD_MISSING_INTERCEPTOR_CLASS, args(classx(classNode), domainHandlerInstance()))); classNode.addMethod( new MethodNode( "$static_methodMissing", Modifier.PUBLIC | Modifier.STATIC, ClassHelper.OBJECT_TYPE, params( param(ClassHelper.STRING_TYPE, "methodName"), param(ClassHelper.makeWithoutCaching(Object[].class), "arguments")), ClassNode.EMPTY_ARRAY, returns( call( field(methodMissingInterceptor), "handleMethodMissing", args(var("methodName"), var("arguments")))))); }
/** * Snoops through the declaring class and all parents looking for methods * * <ul> * <li><code>public String getMessage(java.lang.String)</code> * <li><code>public String getMessage(java.lang.String, java.util.Locale)</code> * <li><code>public String getMessage(java.lang.String, java.lang.Object[])</code> * <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.util.Locale) * </code> * <li><code>public String getMessage(java.lang.String, java.util.List)</code> * <li><code>public String getMessage(java.lang.String, java.util.List, java.util.Locale)</code> * <li><code>public String getMessage(java.lang.String, java.util.Map)</code> * <li><code>public String getMessage(java.lang.String, java.util.Map, java.util.Locale)</code> * <li><code>public String getMessage(java.lang.String, java.lang.String)</code> * <li><code>public String getMessage(java.lang.String, java.lang.String, java.util.Locale) * </code> * <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.lang.String) * </code> * <li><code> * public String getMessage(java.lang.String, java.lang.Object[], java.lang.String, java.util.Locale) * </code> * <li><code>public String getMessage(java.lang.String, java.util.List, java.lang.String)</code> * <li><code> * public String getMessage(java.lang.String, java.util.List, java.lang.String, java.util.Locale) * </code> * <li><code>public String getMessage(java.lang.String, java.util.Map, java.lang.String)</code> * <li><code> * public String getMessage(java.lang.String, java.util.Map, java.lang.String, java.util.Locale) * </code> * </ul> * * If any are defined all must be defined or a compilation error results. * * @param declaringClass the class to search * @param sourceUnit the source unit, for error reporting. {@code @NotNull}. * @return true if property change support should be added */ protected static boolean needsMessageSource(ClassNode declaringClass, SourceUnit sourceUnit) { boolean found = false; ClassNode consideredClass = declaringClass; while (consideredClass != null) { for (MethodNode method : consideredClass.getMethods()) { // just check length, MOP will match it up found = method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 1; found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 2; found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 3; found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 4; if (found) return false; } consideredClass = consideredClass.getSuperClass(); } if (found) { sourceUnit .getErrorCollector() .addErrorAndContinue( new SimpleMessage( "@MessageSourceAware cannot be processed on " + declaringClass.getName() + " because some but not all of variants of getMessage() were declared in the current class or super classes.", sourceUnit)); return false; } return true; }
/** * Convenience method to see if an annotated node is {@code @MybatisAware}. * * @param node the node to check * @return true if the node is an event publisher */ public static boolean hasMybatisAwareAnnotation(AnnotatedNode node) { for (AnnotationNode annotation : node.getAnnotations()) { if (MYBATIS_AWARE_CNODE.equals(annotation.getClassNode())) { return true; } } return false; }
public static void addResourceLocatorIfNeeded(SourceUnit source, ClassNode classNode) { if (needsMessageSource(classNode, source)) { if (LOG.isDebugEnabled()) { LOG.debug("Injecting " + ResourceLocator.class.getName() + " into " + classNode.getName()); } apply(classNode); } }
/** * Convenience method to see if an annotated node is {@code @MessageSourceAware}. * * @param node the node to check * @return true if the node is an event publisher */ public static boolean hasMessageSourceAwareAnnotation(AnnotatedNode node) { for (AnnotationNode annotation : node.getAnnotations()) { if (MESSAGE_SOURCE_AWARE_TYPE.equals(annotation.getClassNode())) { return true; } } return false; }
public static void addMybatisContributionIfNeeded(SourceUnit source, ClassNode classNode) { if (needsMybatisContribution(classNode, source)) { if (LOG.isDebugEnabled()) { LOG.debug( "Injecting " + MybatisContributionHandler.class.getName() + " into " + classNode.getName()); } apply(classNode); } }
protected static boolean needsMybatisContribution( ClassNode declaringClass, SourceUnit sourceUnit) { boolean found1 = false, found2 = false, found3 = false, found4 = false; ClassNode consideredClass = declaringClass; while (consideredClass != null) { for (MethodNode method : consideredClass.getMethods()) { // just check length, MOP will match it up found1 = method.getName().equals(METHOD_WITH_SQL_SESSION) && method.getParameters().length == 1; found2 = method.getName().equals(METHOD_WITH_SQL_SESSION) && method.getParameters().length == 2; found3 = method.getName().equals(METHOD_SET_MYBATIS_PROVIDER) && method.getParameters().length == 1; found4 = method.getName().equals(METHOD_GET_MYBATIS_PROVIDER) && method.getParameters().length == 0; if (found1 && found2 && found3 && found4) { return false; } } consideredClass = consideredClass.getSuperClass(); } if (found1 || found2 || found3 || found4) { sourceUnit .getErrorCollector() .addErrorAndContinue( new SimpleMessage( "@MybatisAware cannot be processed on " + declaringClass.getName() + " because some but not all of methods from " + MybatisContributionHandler.class.getName() + " were declared in the current class or super classes.", sourceUnit)); return false; } return true; }
protected void injectMethod(ClassNode classNode, MethodSignature methodSignature) { Parameter[] parameters = makeParameters(methodSignature.getParameterTypes()); int modifiers = Modifier.PUBLIC; if (methodSignature.isStatic()) modifiers |= Modifier.STATIC; String returnTypeClassName = methodSignature.getReturnType().getName(); ClassNode returnType = GRIFFON_DOMAIN_CLASSNAME.equals(returnTypeClassName) ? classNode : ClassHelper.makeWithoutCaching(methodSignature.getReturnType()); classNode.addMethod( new MethodNode( methodSignature.getMethodName(), modifiers, returnType, parameters, ClassNode.EMPTY_ARRAY, makeMethodBody(classNode, methodSignature, parameters))); }
public static void apply(ClassNode declaringClass) { injectInterface(declaringClass, MYBATIS_CONTRIBUTION_HANDLER_CNODE); // add field: // protected MybatisProvider this$MybatisProvider = DefaultMybatisProvider.instance FieldNode providerField = declaringClass.addField( MYBATIS_PROVIDER_FIELD_NAME, ACC_PRIVATE | ACC_SYNTHETIC, MYBATIS_PROVIDER_CNODE, defaultMybatisProviderInstance()); // add method: // MybatisProvider getMybatisProvider() { // return this$MybatisProvider // } injectMethod( declaringClass, new MethodNode( METHOD_GET_MYBATIS_PROVIDER, ACC_PUBLIC, MYBATIS_PROVIDER_CNODE, Parameter.EMPTY_ARRAY, NO_EXCEPTIONS, returns(field(providerField)))); // add method: // void setMybatisProvider(MybatisProvider provider) { // this$MybatisProvider = provider ?: DefaultMybatisProvider.instance // } injectMethod( declaringClass, new MethodNode( METHOD_SET_MYBATIS_PROVIDER, ACC_PUBLIC, ClassHelper.VOID_TYPE, params(param(MYBATIS_PROVIDER_CNODE, PROVIDER)), NO_EXCEPTIONS, block( ifs_no_return( cmp(var(PROVIDER), ConstantExpression.NULL), assigns(field(providerField), defaultMybatisProviderInstance()), assigns(field(providerField), var(PROVIDER)))))); for (MethodNode method : MYBATIS_CONTRIBUTION_HANDLER_CNODE.getMethods()) { if (Arrays.binarySearch(DELEGATING_METHODS, method.getName()) < 0) continue; List<Expression> variables = new ArrayList<Expression>(); Parameter[] parameters = new Parameter[method.getParameters().length]; for (int i = 0; i < method.getParameters().length; i++) { Parameter p = method.getParameters()[i]; parameters[i] = new Parameter(makeClassSafe(p.getType()), p.getName()); parameters[i].getType().setGenericsTypes(p.getType().getGenericsTypes()); variables.add(var(p.getName())); } ClassNode returnType = makeClassSafe(method.getReturnType()); returnType.setGenericsTypes(method.getReturnType().getGenericsTypes()); returnType.setGenericsPlaceHolder(method.getReturnType().isGenericsPlaceHolder()); MethodNode newMethod = new MethodNode( method.getName(), ACC_PUBLIC, returnType, parameters, NO_EXCEPTIONS, returns(call(field(providerField), method.getName(), args(variables)))); newMethod.setGenericsTypes(method.getGenericsTypes()); injectMethod(declaringClass, newMethod); } }