Method called by both synchronous and asynchronous build() to create a ProxyInvocationHandler
188379
private ProxyInvocationHandler createProxyInvocationHandler(final ProxyCreatedCallback<T> callback) {
        if (buildCalled) {
            throw new JoynrIllegalStateException("Proxy builder was already used to build a proxy. Please create a new proxy builder for each proxy.");
        }
        buildCalled = true;

        StatelessAsyncCallback statelessAsyncCallback = null;
        if (statelessAsyncCallbackUseCase != null) {
            statelessAsyncCallback = statelessAsyncCallbackDirectory.get(statelessAsyncCallbackUseCase);
            if (statelessAsyncCallback == null) {
                throw new JoynrIllegalStateException("No stateless async callback found registered for use case "
                        + statelessAsyncCallbackUseCase);
            }
        }

        final ProxyInvocationHandler proxyInvocationHandler = proxyInvocationHandlerFactory.create(domains,
                                                                                                   interfaceName,
                                                                                                   proxyParticipantId,
                                                                                                   discoveryQos,
                                                                                                   messagingQos,
                                                                                                   shutdownNotifier,
                                                                                                   statelessAsyncCallback);

        // This order is necessary because the Arbitrator might return early
        // But if the listener is set after the ProxyInvocationHandler the
        // Arbitrator cannot return early
        arbitrator.setArbitrationListener(new ArbitrationCallback() {
            @Override
            public void onSuccess(ArbitrationResult arbitrationResult) {
                logger.debug("DISCOVERY proxy created for:{}", arbitrationResult.getDiscoveryEntries());
                proxyInvocationHandler.createConnector(arbitrationResult);
                callback.onProxyCreationFinished(proxy);
            }

            @Override
            public void onError(Throwable throwable) {
                JoynrRuntimeException reason;
                if (throwable instanceof JoynrRuntimeException) {
                    reason = (JoynrRuntimeException) throwable;
                } else {
                    reason = new JoynrRuntimeException(throwable);
                }
                proxyInvocationHandler.abort(reason);
                callback.onProxyCreationError(reason);
            }
        });

        return proxyInvocationHandler;
    }
598911
@Override
    public java.util.concurrent.Future<DescribeReservedNodeOfferingsResult> describeReservedNodeOfferingsAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeReservedNodeOfferingsRequest, DescribeReservedNodeOfferingsResult> asyncHandler) {

        return describeReservedNodeOfferingsAsync(new DescribeReservedNodeOfferingsRequest(), asyncHandler);
    }
911539
public static <T> T create(final InterfaceDescriptor<T> descriptor, final Invoker invoker) {
		if (descriptor == null) throw new NullPointerException("descriptor");
		if (invoker == null) throw new NullPointerException("invocationHandler");

		InvocationProxy<T> invocationProxy = new InvocationProxy<T>(descriptor, invoker, null);
		return invocationProxy.toProxy();
	}
1270645
function javaClassConstructorProxy() {
    var args = [name];
    for (var i = 0; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    return java.newInstanceSync.apply(java, args);
  }
114792
@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (throwable != null) {
            throw throwable;
        }
        try {
            return invokeInternal(proxy, method, args);
        } catch (Exception e) {
            if (this.throwable != null) {
                logger.debug("exception caught: {} overridden by: {}", e.getMessage(), throwable.getMessage());
                throw throwable;
            } else {
                throw e;
            }
        }
    }
642390
public static <T> T newProxyInstance(InvocationHandler invocationHandler, Class<?>... interfaces) {
		return newProxyInstance(ClassUtil.getClassLoader(), invocationHandler, interfaces);
	}
788942
public static InvocationHandler getInvocationHandler(Object instance) {
        try {
            Field field = instance.getClass().getDeclaredField(FIELD_NAME_HANDLER);
            field.setAccessible(true);
            return (InvocationHandler) field.get(instance);
        } catch (NoSuchFieldException e) {
            throw new IllegalArgumentException("Not a valid proxy instance", e);
        } catch (IllegalAccessException e) {
            // Should not be thrown, we just set the field to accessible.
            throw new AssertionError(e);
        }
    }
1033260
@SuppressWarnings({ "unchecked", "rawtypes" })
	private static <CT, I> Function<CT, I> createFunction(
		Class<CT> contextType,
		Class<I> typeToExtend,
		Map<Method, MethodInvocationHandler<CT>> invokers
	)
	{
		try
		{
			DynamicType.Builder builder = new ByteBuddy()
				.subclass(typeToExtend);

			// Add the context field
			builder = builder.defineField("context", contextType, Visibility.PRIVATE);

			// Add the constructor
			builder = builder.defineConstructor(Visibility.PUBLIC)
				.withParameter(contextType)
				.intercept(
					MethodCall.invoke(Object.class.getDeclaredConstructor())
						.onSuper()
						.andThen(FieldAccessor.ofField("context").setsArgumentAt(0))
				);

			// TODO: The constructor needs to support abstract base classes and injection via InstanceFactory

			for(Map.Entry<Method, MethodInvocationHandler<CT>> e : invokers.entrySet())
			{
				builder = builder.define(e.getKey())
					.intercept(
						MethodDelegation.to(new Runner(e.getValue()))
					);
			}

			Class createdClass = builder.make()
				.load(typeToExtend.getClassLoader())
				.getLoaded();

			return createFactory(createdClass, contextType);
		}
		catch(Throwable e)
		{
			if(e instanceof ProxyException) throw (ProxyException) e;
			throw new ProxyException(e);
		}
	}
1168759
async function mkProxyOrMockFile({dirPath, exclude, targetDir, proxyFolderName,
    mockFolderName, time, interval, isProxy, libPath}) {
//@formatter:on
    
    const relativePath = dirPath.replace(targetDir, '') || '/';
    const childList = await loadChildList(dirPath, exclude);

    const taskList = childList.map(child => {
        return ((async function handleFile() {
            const stat = await Fs.stat(Path.join(dirPath, child));
            if (stat.isFile()) {
                const fileRelativePath = relativePath + child;
                const isWs = _.endsWith(child, '-ws.js');

                const factory = {
                    'proxy_api'() {
                        return Render(PROXY_TPL,
                            {note: Common.NOTE, proxyFolderName, fileRelativePath});
                    },
                    'mock_api'() {
                        return Render(MOCK_API_TPL,
                            {note: Common.NOTE, mockFolderName, fileRelativePath, time});
                    },
                    'proxy_ws'() {
                        return Render(PROXY_TPL,
                            {note: Common.NOTE, proxyFolderName, fileRelativePath});
                    },
                    'mock_ws'() {
                        return Render(MOCK_WS_TPL, {
                            note: Common.NOTE,
                            mockFolderName,
                            fileRelativePath,
                            interval
                        });
                    }
                }[`${isProxy ? 'proxy' : 'mock'}_${isWs ? 'ws' : 'api'}`]();

                await Fs.writeFile(Path.join(libPath, child), factory);
                return;
            }

            if (stat.isDirectory()) {
                await mkProxyOrMockFile({
                    dirPath: Path.join(dirPath, child), exclude, targetDir, proxyFolderName,
                    mockFolderName, time, interval, isProxy, libPath
                });
            }
        })());
    });

    await Promise.all(taskList);
}
1246288
function Request (method, args, attempts, proxyCondition) {
    // constraint
    attempts = attempts || 0;
    if (attempts > 10)
        throw `Maximum number of request attempts exceeded (10 total) for "${args.url}"`;
    // workflow
    if (!args.url) throw 'URL undefined in smappi-cl/lib/request';
    args.data = args.data || {}; // for POST/PUT
    args.params = args.params || {}; // for GET
    args.headers = args.headers || {};
    args.options = args.options || {};
    if (!args.options.hasOwnProperty('followLocation')) {
        args.options.followLocation = true;
    }
    if (args.options.proxy == false) {
        args.proxy = null;
    } else {
        if (proxyCondition && !proxy.isActive()) {
            // if not disable proxy (for internal request, see proxy.js)
            // and there proxyCondition
            // and not active proxy
            proxy.next(); // then activate proxy if used withProxy!
        }
        args.proxy = proxy.currentHref();
    }
    args.method = method;
    if (!args.options.async) { // Synchronous
        var contentFile = ".smappi-request-content-" + process.pid;
        var syncFile = ".smappi-request-sync-" + process.pid;
        fs.writeFileSync(syncFile, "", "utf8");
        // The async request the other Node process executes
        // Start the other Node Process, executing this string
        // console.log(process.argv[0], __dirname + '/worker.js', process.pid, "'" + JSON.stringify(args) + "'");
        var syncProc = spawn(process.argv[0], [
            __dirname + '/worker.js',
            process.pid,
            JSON.stringify(args)
        ]);
        while (fs.existsSync(syncFile)) {
            // Wait while the sync file is empty
        }
        var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8'));
        // Kill the child process once the file has data
        syncProc.stdin.end();
        // Remove the temporary file
        fs.unlinkSync(contentFile);
        let retry = () => {
            // if use proxy and request is broken, then turn next
            if (args.options.proxy !== false) {
                proxy.skip(); // skip current
                proxy.next();
            }
            return new Request(method, args, attempts + 1, proxyCondition);
        }
        if (resp.err) {
            if (Object.keys(resp.err).length) {
                let errStr = JSON.stringify(resp.err);
                if (resp.err.options && resp.err.options.command == 'connect') {
                    let postScriptum = '';
                    if (resp.err.options.proxy)
                        postScriptum = ' (probably proxy is wrong)';
                    logger.error(`Problem while connect for "${args.url}"${postScriptum}. Request will be retry. ERR: ${errStr}`);
                    return retry();
                } else if (resp.err.code == 'ECONNRESET') {
                    logger.error(`Connection problems for "${args.url}". Request will be retry. ERR: ${errStr}`);
                    return retry();
                } else if (resp.err.code == 'ETIMEOUT' || resp.err.code == 'ETIMEDOUT') {
                    logger.error(`Connection timeout exceeded for "${args.url}". Request will be retry. ERR: ${errStr}`);
                    return retry();
                } else if (resp.err.code == 'ENOTFOUND' && resp.err.syscall == 'getaddrinfo') {
                    let msg = `Host "${resp.err.hostname}" not found. Please verify A-record for this domain.`;
                    logger.error(msg);
                    throw msg;
                } else {
                    throw errStr;
                }
            } else if (args.proxy && resp.ctx == 'request') {
                return retry(); // Otherwise retry again
            } else if (resp.message) {
                throw resp.message;
            } else {
                throw 'Problem with connection in smappi-cl/lib/request';
            }
        } else {
            if ([301, 302].indexOf(resp.status) != -1) {
                if (args.options.followLocation) {
                    let location = url.parse(resp.headers.location);
                    if (!location.protocol) {
                        let srcUrl = url.parse(args.url);
                        // add protocol for location without proto, example "//smappi.org/path/to" or relative path "/path/to"
                        location.protocol = srcUrl.protocol;
                        if (!location.href.startsWith('//')) { // relative, not shortcut proto
                            // relative path to current hostname, example "/path/to"
                            location.hostname = srcUrl.hostname;
                        }
                    }
                    args.url = location.format();
                    return new Request(method, args, attempts + 1, proxyCondition);
                }
            }
            let response = new Response(resp, args.url);
            // console.log('RequestResponse check condition', args.url, response.status, !proxyCondition || proxyCondition(response))
            if (!proxyCondition || proxyCondition(response)) {
                // If not proxyCondition or proxyCondition is success
                // return Response
                return response;
            } else {
                return retry(); // Otherwise retry again
            }
        }
    } else {
        throw 'Temporary! Not Implemented Smappi CL Async Requests';
    }
}
505901
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable
    {
        String mangleName;

        synchronized (_mangleMap) {
            mangleName = _mangleMap.get(method);
        }

        if (mangleName == null) {
            String methodName = method.getName();
            Class<?>[] params = method.getParameterTypes();

            // equals and hashCode are special cased
            if (methodName.equals("equals")
                && params.length == 1 && params[0].equals(Object.class)) {
                Object value = args[0];
                if (value == null || !Proxy.isProxyClass(value.getClass()))
                    return Boolean.FALSE;

                Object proxyHandler = Proxy.getInvocationHandler(value);

                if (!(proxyHandler instanceof HessianProxy))
                    return Boolean.FALSE;

                HessianProxy handler = (HessianProxy) proxyHandler;

                return new Boolean(_url.equals(handler.getURL()));
            }
            else if (methodName.equals("hashCode") && params.length == 0)
                return new Integer(_url.hashCode());
            else if (methodName.equals("getHessianType"))
                return proxy.getClass().getInterfaces()[0].getName();
            else if (methodName.equals("getHessianURL"))
                return _url.toString();
            else if (methodName.equals("toString") && params.length == 0)
                return "HessianProxy[" + _url + "]";

            if (!_factory.isOverloadEnabled())
                mangleName = method.getName();
            else
                mangleName = mangleName(method);

            synchronized (_mangleMap) {
                _mangleMap.put(method, mangleName);
            }
        }

        InputStream is = null;
        HessianConnection conn = null;

        try {
            if (log.isLoggable(Level.FINER))
                log.finer("Hessian[" + _url + "] calling " + mangleName);

            conn = sendRequest(mangleName, args);

            is = getInputStream(conn);

            if (log.isLoggable(Level.FINEST)) {
                PrintWriter dbg = new PrintWriter(new LogWriter(log));
                HessianDebugInputStream dIs = new HessianDebugInputStream(is, dbg);

                dIs.startTop2();

                is = dIs;
            }

            AbstractHessianInput in;

            int code = is.read();

            if (code == 'H') {
                int major = is.read();
                int minor = is.read();

                in = _factory.getHessian2Input(is);

                Object value = in.readReply(method.getReturnType());

                return value;
            }
            else if (code == 'r') {
                int major = is.read();
                int minor = is.read();

                in = _factory.getHessianInput(is);

                in.startReplyBody();

                Object value = in.readObject(method.getReturnType());

                if (value instanceof InputStream) {
                    value = new ResultInputStream(conn, is, in, (InputStream) value);
                    is = null;
                    conn = null;
                }
                else
                    in.completeReply();

                return value;
            }
            else
                throw new HessianProtocolException("'" + (char) code + "' is an unknown code");
        } catch (HessianProtocolException e) {
            throw new HessianRuntimeException(e);
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (Exception e) {
                log.log(Level.FINE, e.toString(), e);
            }

            try {
                if (conn != null)
                    conn.destroy();
            } catch (Exception e) {
                log.log(Level.FINE, e.toString(), e);
            }
        }
    }
971405
private void createProxyHandler() throws MessageStoreException {
        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.entry(tc, "createProxyHandler");

        _multiMEProxyHandler = new MultiMEProxyHandler(this, _txManager);
        _persistentStore.addItemStream(_multiMEProxyHandler, _txManager
                        .createAutoCommitTransaction());

        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.exit(tc, "createProxyHandler");
    }
696185
EntityManager build(EntityManagerContext entityManagerContext) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        return (EntityManager) Proxy.newProxyInstance(
                classLoader,
                new Class[]{EntityManager.class},
                new SharedEntityManagerInvocationHandler(entityManagerContext));
    }
1242724
public static MethodInvokeProxy proxyByName(Object target,String methodName,Object ...args)
	{
		Method m=findMethodByName(target, methodName);
		if(m!=null)
		{
			return new MethodInvokeProxy(target, m, args);
		}
		return null;
	}
751537
public HttpHandler createProxyHandler() {
        return ProxyHandler.builder()
                .setProxyClient(container.getProxyClient())
                .setMaxRequestTime(maxRequestTime)
                .setMaxConnectionRetries(maxRetries)
                .setReuseXForwarded(reuseXForwarded)
                .build();
    }
243539
def _generate_request_handler_proxy(handler_class, handler_args, name):
    """"""

    @scope.inject
    def request_handler_wrapper(app, handler, **kwargs):
        handler = handler_class(app, handler.request, **handler_args)
        handler._execute([], **kwargs)
    request_handler_wrapper.__name__ = name
    request_handler_wrapper.handler_class = handler_class
    request_handler_wrapper.handler_args = handler_args

    return request_handler_wrapper
256097
private String createHandler(TypeElement type, ExecutableElement execute, String[] paths, boolean isRest) {
        FieldSpec hostField = FieldSpec.builder(Object.class, "mHost").addModifiers(Modifier.PRIVATE).build();

        MethodSpec rootMethod = MethodSpec.constructorBuilder()
            .addModifiers(Modifier.PUBLIC)
            .addParameter(Object.class, "host")
            .addParameter(mMapping, "mapping")
            .addParameter(mAddition, "addition")
            .addParameter(boolean.class, "isRest")
            .addStatement("super(host, mapping, addition, isRest)")
            .addStatement("this.mHost = host")
            .build();

        CodeBlock.Builder handleCode = CodeBlock.builder()
            .addStatement("$T context = $T.getContext()", mContext, mAndServer)
            .addStatement("String httpPath = request.getPath()")
            .addStatement("$T httpMethod = request.getMethod()", mHttpMethod)
            .add("\n")
            .addStatement("Object converterObj = request.getAttribute($T.HTTP_MESSAGE_CONVERTER)", mRequest)
            .addStatement("$T converter = null", mConverter)
            .beginControlFlow("if (converterObj != null && converterObj instanceof $T)", mConverter)
            .addStatement("converter = ($T)converterObj", mConverter)
            .endControlFlow()
            .add("\n")
            .addStatement("$T multiRequest = null", mRequestMultipart)
            .beginControlFlow("if (request instanceof $T)", mRequestMultipart)
            .addStatement("multiRequest = ($T) request", mRequestMultipart)
            .endControlFlow()
            .add("\n")
            .addStatement("$T requestBody = null", mRequestBody)
            .beginControlFlow("if (httpMethod.allowBody())")
            .addStatement("requestBody = request.getBody()")
            .endControlFlow()
            .add("\n")
            .addStatement("$T<String, String> pathMap = getPathVariable(httpPath)", Map.class)
            .add("\n")
            .add("/** ---------- Building Parameters ---------- **/ ")
            .add("\n");

        String host = type.getQualifiedName().toString() + "#" + execute.getSimpleName().toString() + "()";
        StringBuilder paramBuild = new StringBuilder();
        List<? extends VariableElement> parameters = execute.getParameters();
        if (!parameters.isEmpty()) {
            for (int i = 0; i < parameters.size(); i++) {
                VariableElement parameter = parameters.get(i);

                TypeName typeName = TypeName.get(parameter.asType());
                if (mContext.equals(typeName)) {
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append("context");
                    continue;
                }

                if (mRequest.equals(typeName)) {
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append("request");
                    continue;
                }

                if (mResponse.equals(typeName)) {
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append("response");
                    continue;
                }

                if (mSession.equals(typeName)) {
                    handleCode.add("\n").addStatement("$T session$L = request.getValidSession()", mSession, i);
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format("session%s", i));
                    continue;
                }

                if (mRequestBody.equals(typeName)) {
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append("requestBody");
                    continue;
                }

                RequestHeader requestHeader = parameter.getAnnotation(RequestHeader.class);
                if (requestHeader != null) {
                    Validate.isTrue(isBasicType(typeName),
                        "The RequestHeader annotation only supports [String, int, long, float, double, boolean] on %s.",
                        host);

                    String name = requestHeader.name();
                    if (StringUtils.isEmpty(name)) name = requestHeader.value();
                    Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host);

                    handleCode.add("\n").addStatement("String header$LStr = request.getHeader($S)", i, name);
                    if (requestHeader.required()) {
                        handleCode.beginControlFlow("if ($T.isEmpty(header$LStr))", mStringUtils, i)
                            .addStatement("throw new $T($S)", mHeaderMissing, name)
                            .endControlFlow();
                    } else {
                        handleCode.beginControlFlow("if ($T.isEmpty(header$LStr))", mStringUtils, i)
                            .addStatement("header$LStr = $S", i, requestHeader.defaultValue())
                            .endControlFlow();
                    }

                    createParameter(handleCode, typeName, "header", i);
                    assignmentParameter(handleCode, typeName, "header", i, "header", i);

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "header%d", i));
                    continue;
                }

                CookieValue cookieValue = parameter.getAnnotation(CookieValue.class);
                if (cookieValue != null) {
                    Validate.isTrue(mString.equals(typeName), "CookieValue can only be used with [String] on %s.",
                        host);

                    String name = cookieValue.name();
                    if (StringUtils.isEmpty(name)) name = cookieValue.value();
                    Validate.notEmpty(name, "The name of cookie is null on %s.", host);

                    handleCode.add("\n").addStatement("String cookie$L = request.getCookieValue($S)", i, name);
                    if (cookieValue.required()) {
                        handleCode.beginControlFlow("if ($T.isEmpty(cookie$L))", mStringUtils, i)
                            .addStatement("throw new $T($S)", mCookieMissing, name)
                            .endControlFlow();
                    }

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "cookie%d", i));
                    continue;
                }

                PathVariable pathVariable = parameter.getAnnotation(PathVariable.class);
                if (pathVariable != null) {
                    Validate.isTrue(isBasicType(typeName),
                        "The PathVariable annotation only supports [String, int, long, float, double, boolean] on %s.",
                        host);

                    String name = pathVariable.name();
                    if (StringUtils.isEmpty(name)) name = pathVariable.value();
                    Validate.isTrue(!StringUtils.isEmpty(name), "The name of path is null on %s.", host);

                    boolean isBlurred = false;
                    for (String path : paths) {
                        if (path.matches(PATH_BLURRED) && !path.matches(PATH)) {
                            isBlurred = true;
                        }
                    }
                    Validate.isTrue(isBlurred,
                        "The PathVariable annotation must have a blurred path, for example [/project/{name}]. The " +
                            "error occurred on %s.", host);

                    handleCode.add("\n").addStatement("String path$LStr = pathMap.get($S)", i, name);

                    if (pathVariable.required()) {
                        handleCode.beginControlFlow("if ($T.isEmpty(path$LStr))", mStringUtils, i)
                            .addStatement("throw new $T($S)", mPathMissing, name)
                            .endControlFlow();
                    } else {
                        handleCode.beginControlFlow("if ($T.isEmpty(path$LStr))", mStringUtils, i)
                            .addStatement("path$LStr = $S;", i, pathVariable.defaultValue())
                            .endControlFlow();
                    }

                    createParameter(handleCode, typeName, "path", i);
                    assignmentParameter(handleCode, typeName, "path", i, "path", i);

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "path%d", i));
                    continue;
                }

                QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
                if (queryParam != null) {
                    Validate.isTrue(isBasicType(typeName),
                        "The QueryParam annotation only supports [String, int, long, float, double, " +
                            "boolean] on %s.", host);

                    String name = queryParam.name();
                    if (StringUtils.isEmpty(name)) name = queryParam.value();
                    Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host);

                    handleCode.add("\n").addStatement("String param$LStr = request.getQuery($S)", i, name);
                    if (queryParam.required()) {
                        handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mStringUtils, i)
                            .addStatement("throw new $T($S)", mParamMissing, name)
                            .endControlFlow();
                    } else {
                        handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mStringUtils, i)
                            .addStatement("param$LStr = $S", i, queryParam.defaultValue())
                            .endControlFlow();
                    }

                    createParameter(handleCode, typeName, "param", i);
                    assignmentParameter(handleCode, typeName, "param", i, "param", i);

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "param%d", i));
                    continue;
                }

                RequestParam requestParam = parameter.getAnnotation(RequestParam.class);
                if (requestParam != null) {
                    boolean valid = mMultipart.equals(typeName) || isBasicType(typeName);
                    Validate.isTrue(valid,
                        "The RequestParam annotation only supports [MultipartFile, String, int, long, float, double, " +
                            "boolean] on %s.", host);

                    String name = requestParam.name();
                    if (StringUtils.isEmpty(name)) name = requestParam.value();
                    Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host);

                    handleCode.add("\n");
                    if (mMultipart.equals(typeName)) {
                        handleCode.addStatement("$T param$L = null", mMultipart, i)
                            .beginControlFlow("if (multiRequest != null)")
                            .addStatement("param$L = multiRequest.getFile($S)", i, name)
                            .endControlFlow();
                        if (requestParam.required()) {
                            handleCode.beginControlFlow("if (param$L == null)", i)
                                .addStatement("throw new $T($S)", mParamMissing, name)
                                .endControlFlow();
                        }
                    } else {
                        handleCode.addStatement("String param$LStr = request.getParameter($S)", i, name);

                        if (requestParam.required()) {
                            handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mStringUtils, i)
                                .addStatement("throw new $T($S)", mParamMissing, name)
                                .endControlFlow();
                        } else {
                            handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mStringUtils, i)
                                .addStatement("param$LStr = $S", i, requestParam.defaultValue())
                                .endControlFlow();
                        }

                        createParameter(handleCode, typeName, "param", i);
                        assignmentParameter(handleCode, typeName, "param", i, "param", i);
                    }

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "param%d", i));
                    continue;
                }

                FormPart formPart = parameter.getAnnotation(FormPart.class);
                if (formPart != null) {
                    String name = formPart.name();
                    if (StringUtils.isEmpty(name)) name = formPart.value();
                    Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host);

                    handleCode.add("\n");
                    if (mMultipart.equals(typeName)) {
                        handleCode.addStatement("$T param$L = null", mMultipart, i)
                            .beginControlFlow("if (multiRequest != null)")
                            .addStatement("param$L = multiRequest.getFile($S)", i, name)
                            .endControlFlow();
                        if (formPart.required()) {
                            handleCode.beginControlFlow("if (param$L == null)", i)
                                .addStatement("throw new $T($S)", mParamMissing, name)
                                .endControlFlow();
                        }
                    } else {
                        TypeName wrapperType = ParameterizedTypeName.get(mTypeWrapper, typeName);
                        handleCode.addStatement("$T param$L = null", typeName, i)
                            .addStatement("$T param$LType = new $T(){}.getType()", Type.class, i, wrapperType)
                            .beginControlFlow("if (converter != null && multiRequest != null)")
                            .addStatement("$T param$LFile = multiRequest.getFile($S)", mMultipart, i, name)
                            .beginControlFlow("if (param$LFile != null)", i)
                            .addStatement("$T stream = param$LFile.getStream()", InputStream.class, i)
                            .addStatement("$T mimeType = param$LFile.getContentType()", mMediaType, i)
                            .addStatement("param$L = converter.convert(stream, mimeType, param$LType)", i, i)
                            .endControlFlow()
                            .beginControlFlow("if (param$L == null)", i)
                            .addStatement("String param$LStr = multiRequest.getParameter($S)", i, name)
                            .beginControlFlow("if (!$T.isEmpty(param$LStr))", mStringUtils, i)
                            .addStatement("$T stream = new $T(param$LStr.getBytes())", InputStream.class,
                                ByteArrayInputStream.class, i)
                            .addStatement("$T mimeType = $T.TEXT_PLAIN", mMediaType, mMediaType)
                            .addStatement("param$L = converter.convert(stream, mimeType, param$LType)", i, i)
                            .endControlFlow()
                            .endControlFlow()
                            .endControlFlow();

                        if (formPart.required()) {
                            handleCode.beginControlFlow("if (param$L == null)", i)
                                .addStatement("throw new $T($S)", mParamMissing, name)
                                .endControlFlow();
                        }
                    }
                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "param%d", i));
                    continue;
                }

                RequestBody requestBody = parameter.getAnnotation(RequestBody.class);
                if (requestBody != null) {
                    handleCode.add("\n");

                    if (mString.equals(typeName)) {
                        handleCode.addStatement("String body$L = requestBody.string()", i);
                    } else {
                        TypeName wrapperType = ParameterizedTypeName.get(mTypeWrapper, typeName);
                        handleCode.addStatement("$T body$L = null", typeName, i)
                            .beginControlFlow("if (converter != null && requestBody != null)")
                            .addStatement("$T body$LType = new $T(){}.getType()", Type.class, i, wrapperType)
                            .addStatement("$T stream = requestBody.stream()", InputStream.class)
                            .addStatement("$T mimeType = requestBody.contentType()", mMediaType)
                            .addStatement("body$L = converter.convert(stream, mimeType, body$LType)", i, i)
                            .endControlFlow();
                    }

                    if (requestBody.required()) {
                        handleCode.beginControlFlow("if (body$L == null)", i)
                            .addStatement("throw new $T()", mBodyMissing)
                            .endControlFlow();
                    }

                    if (paramBuild.length() > 0) paramBuild.append(", ");
                    paramBuild.append(String.format(Locale.getDefault(), "body%d", i));
                    continue;
                }

                throw new IllegalStateException(
                    String.format("The parameter type [%s] is not supported on %s.", typeName, host));
            }
        }

        String executeName = execute.getSimpleName().toString();
        TypeMirror returnMirror = execute.getReturnType();
        handleCode.add("\n").addStatement("Object o = null", type, executeName).beginControlFlow("try");
        if (!TypeKind.VOID.equals(returnMirror.getKind())) {
            handleCode.addStatement("o = (($T)mHost).$L($L)", type, executeName, paramBuild.toString());
        } else {
            handleCode.addStatement("(($T)mHost).$L($L)", type, executeName, paramBuild.toString());
        }
        handleCode.endControlFlow().beginControlFlow("catch (Throwable e)").addStatement("throw e").endControlFlow();
        handleCode.addStatement("return new $T($L, o)", mViewObject, isRest);

        MethodSpec handleMethod = MethodSpec.methodBuilder("handle")
            .addAnnotation(Override.class)
            .addModifiers(Modifier.PUBLIC)
            .returns(mView)
            .addParameter(mRequest, "request")
            .addParameter(mResponse, "response")
            .addException(IOException.class)
            .addCode(handleCode.build())
            .build();


        String packageName = MoreElements.getPackage(type).getQualifiedName().toString();
        executeName = StringUtils.capitalize(executeName);
        String className = String.format("%s%sHandler%s", type.getSimpleName(), executeName, "");
        int i = 0;
        while (mHashCodes.contains(className.hashCode())) {
            i++;
            className = String.format("%s%sHandler%s", type.getSimpleName(), executeName, i);
        }
        mHashCodes.add(className.hashCode());

        TypeSpec handlerClass = TypeSpec.classBuilder(className)
            .addJavadoc(Constants.DOC_EDIT_WARN)
            .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
            .superclass(mMappingHandler)
            .addField(hostField)
            .addMethod(rootMethod)
            .addMethod(handleMethod)
            .build();

        JavaFile javaFile = JavaFile.builder(packageName, handlerClass).build();
        try {
            javaFile.writeTo(mFiler);
            return className;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }