@SuppressWarnings("unchecked") private <T> Invoker generateInvoker( final Class<T> proxyInterface, final Method method, final ArgumentHolderGenerator argumentHolderGenerator) { final StringBuilder invokerClassName = new StringBuilder("_invoker") .append(proxyInterface.getSimpleName()) .append(method.getName()) .append('_') .append(getUniqueIdentifier()); final Class<?>[] parameterTypes = method.getParameterTypes(); for (final Class<?> paramType : parameterTypes) { if (paramType.isArray()) { invokerClassName.append(paramType.getComponentType().getSimpleName()).append("Array"); } else { invokerClassName.append(paramType.getSimpleName()); } } final CtClass ctClass = makeClass(classPool, invokerClassName.toString()); addInterface(ctClass, Invoker.class, classPool); makePublicFinal(ctClass); final StringBuilder methodSrc = new StringBuilder("public void invokeWithArgumentHolder(") .append("Object") .append(" implementation, Object argumentHolder) {\n"); if (parameterTypes.length != 0) { methodSrc .append("final ") .append(argumentHolderGenerator.getGeneratedClassName()) .append(" holder = ") .append("(") .append(argumentHolderGenerator.getGeneratedClassName()) .append(") argumentHolder;\n"); } methodSrc .append("((") .append(proxyInterface.getName().replace('$', '.')) .append(")implementation).") .append(method.getName()) .append('('); appendParametersFromArgumentHolder(parameterTypes, methodSrc, argumentHolderGenerator); methodSrc.append(");\n}\n"); return generateInvoker(ctClass, methodSrc); }
private void createRingBufferPublisherMethod( final CtClass ctClass, final Method method, final Invoker invoker, final OverflowStrategy overflowStrategy, final ArgumentHolderGenerator argumentHolderGenerator) { final StringBuilder methodSrc = new StringBuilder("public void ").append(method.getName()).append("("); final Class<?>[] parameterTypes = method.getParameterTypes(); char paramId = 'a'; for (int i = 0, parameterTypesLength = parameterTypes.length; i < parameterTypesLength; i++) { final Class<?> parameterType = parameterTypes[i]; if (parameterType.isArray()) { methodSrc .append(parameterType.getComponentType().getName()) .append("[] ") .append(paramId++); } else { methodSrc.append(parameterType.getName()).append(' ').append(paramId++); } if (i < parameterTypesLength - 1) { methodSrc.append(", "); } } methodSrc.append(")\n{\n"); methodSrc.append("messagePublicationListener.onPrePublish();\n"); handleOverflowStrategy(overflowStrategy, methodSrc); methodSrc .append("final long sequence = ringBuffer.next();\n") .append("try\n") .append("{\n") .append( "final ProxyMethodInvocation proxyMethodInvocation = (ProxyMethodInvocation) ringBuffer.get(sequence);\n"); final String argumentHolderClass = argumentHolderGenerator.getGeneratedClassName(); methodSrc .append("final ") .append(argumentHolderClass) .append(" holder = (") .append(argumentHolderClass) .append(") proxyMethodInvocation.getArgumentHolder();\n"); argumentHolderGenerator.resetFieldNames(); for (int i = 0; i < parameterTypes.length; i++) { final Class<?> parameterType = parameterTypes[i]; final String holderField = argumentHolderGenerator.getNextFieldNameForType(parameterType); methodSrc .append("holder.") .append(holderField) .append(" = ") .append((char) ('a' + i)) .append(";"); } methodSrc .append("proxyMethodInvocation.setInvoker(_") .append(invoker.getClass().getName()) .append(");\n") .append("}\n") .append("catch(Throwable t){t.printStackTrace();}\n") .append("finally\n") .append("{\n") .append("ringBuffer.publish(sequence);\n") .append("messagePublicationListener.onPostPublish();\n") .append("}\n"); methodSrc.append("}\n"); createMethod(ctClass, methodSrc.toString()); }