/**
* Mule Development Kit
* Copyright 2010-2011 (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mule.devkit.generation.callback;
import org.mule.MessageExchangePattern;
import org.mule.api.DefaultMuleException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.annotations.oauth.OAuth;
import org.mule.api.annotations.oauth.OAuth2;
import org.mule.api.callback.HttpCallback;
import org.mule.api.construct.FlowConstructInvalidException;
import org.mule.api.endpoint.EndpointFactory;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.processor.MessageProcessor;
import org.mule.api.registry.MuleRegistry;
import org.mule.api.transport.Connector;
import org.mule.config.spring.factories.AsyncMessageProcessorsFactoryBean;
import org.mule.construct.Flow;
import org.mule.devkit.generation.AbstractModuleGenerator;
import org.mule.devkit.generation.DevKitTypeElement;
import org.mule.devkit.generation.NamingContants;
import org.mule.devkit.model.code.Block;
import org.mule.devkit.model.code.CatchBlock;
import org.mule.devkit.model.code.Conditional;
import org.mule.devkit.model.code.DefinedClass;
import org.mule.devkit.model.code.ExpressionFactory;
import org.mule.devkit.model.code.FieldVariable;
import org.mule.devkit.model.code.Method;
import org.mule.devkit.model.code.Modifier;
import org.mule.devkit.model.code.Op;
import org.mule.devkit.model.code.Package;
import org.mule.devkit.model.code.TryStatement;
import org.mule.devkit.model.code.Variable;
import org.mule.devkit.model.code.builders.FieldBuilder;
import org.mule.endpoint.EndpointURIEndpointBuilder;
import org.mule.processor.strategy.AsynchronousProcessingStrategy;
import javax.lang.model.element.TypeElement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
public class DefaultHttpCallbackGenerator extends AbstractModuleGenerator {
public static final String HTTP_CALLBACK_ROLE = "HttpCallback";
public static final String LOCAL_PORT_FIELD_NAME = "localPort";
public static final String REMOTE_PORT_FIELD_NAME = "remotePort";
public static final String DOMAIN_FIELD_NAME = "domain";
public static final String ASYNC_FIELD_NAME = "async";
public static final String CONNECTOR_FIELD_NAME = "connector";
private static final String CLASS_NAME = "DefaultHttpCallback";
private static final String INBOUND_ENDPOINT_EXCHANGE_PATTERN = "REQUEST_RESPONSE";
private Method buildUrlMethod;
private FieldVariable muleContextField;
private FieldVariable flowConstructVariable;
private Method createHttpInboundEndpointMethod;
private FieldVariable urlField;
private Method createConnectorMethod;
private Method wrapMessageProcessorInAsyncChain;
private FieldVariable loggerField;
private FieldVariable callbackFlowField;
private FieldVariable localPortField;
private FieldVariable callbackMessageProcessorField;
private FieldVariable domainField;
private FieldVariable localUrlField;
private FieldVariable callbackPathField;
private FieldVariable remotePortField;
private FieldVariable async;
private FieldVariable connectorField;
@Override
protected boolean shouldGenerate(DevKitTypeElement typeElement) {
return typeElement.hasAnnotation(OAuth.class) ||
typeElement.hasAnnotation(OAuth2.class) ||
typeElement.hasProcessorMethodWithParameter(HttpCallback.class);
}
@Override
protected void doGenerate(DevKitTypeElement typeElement) {
DefinedClass callbackClass = getDefaultHttpCallbackClass(typeElement);
context.note("Generating HTTP callback implementation as " + callbackClass.fullName());
generateFields(callbackClass);
generateConstructorArgSimpleFlowConstruct(callbackClass);
generateConstructorArgMessageProcessor(callbackClass);
generateConstructorArgMessageProcessorAndCallbackPath(callbackClass);
generateConstructorArgSimpleFlowConstructAndConnectorRef(callbackClass);
generateConstructorArgMessageProcessorAndConnectorRef(callbackClass);
generateConstructorArgMessageProcessorAndCallbackPathAndConnectorRef(callbackClass);
generateBuildUrlMethod(callbackClass);
createMessageProcessorInnerClass(callbackClass);
generateWrapMessageProcessorInAsyncChain(callbackClass);
generateCreateConnectorMethod(callbackClass);
generateCreateHttpInboundEndpointMethod(callbackClass);
generateStartMethod(callbackClass);
generateStopMethod(callbackClass);
context.setClassRole(HTTP_CALLBACK_ROLE, callbackClass);
}
private void generateFields(DefinedClass callbackClass) {
loggerField = FieldBuilder.newLoggerField(callbackClass);
localPortField = new FieldBuilder(callbackClass).
privateVisibility().
type(Integer.class).
name(LOCAL_PORT_FIELD_NAME).
build();
remotePortField = new FieldBuilder(callbackClass).
privateVisibility().
type(Integer.class).
name(REMOTE_PORT_FIELD_NAME).
javadoc("The port number to be used in the dynamic http inbound endpoint that will receive the callback").
build();
domainField = new FieldBuilder(callbackClass).
type(String.class).
name(DOMAIN_FIELD_NAME).
javadoc("The domain to be used in the dynamic http inbound endpoint that will receive the callback").
build();
urlField = new FieldBuilder(callbackClass).
privateVisibility().
type(String.class).
name("url").
javadoc("The dynamically generated url to pass on to the cloud connector. When this url is called the callback flow will be executed").
getter().
build();
localUrlField = new FieldBuilder(callbackClass).
privateVisibility().
type(String.class).
name("localUrl").
build();
muleContextField = new FieldBuilder(callbackClass).
privateVisibility().
type(MuleContext.class).
name("muleContext").
javadoc("Mule Context").
setter().
build();
callbackFlowField = new FieldBuilder(callbackClass).
privateVisibility().
type(Flow.class).
name("callbackFlow").
javadoc("The flow to be called upon the http callback").
build();
flowConstructVariable = new FieldBuilder(callbackClass).
privateVisibility().
type(Flow.class).
name("flowConstruct").
javadoc("The dynamically created flow").
build();
callbackMessageProcessorField = new FieldBuilder(callbackClass).
type(MessageProcessor.class).
name("callbackMessageProcessor").
javadoc("The message processor to be called upon the http callback").
build();
callbackPathField = new FieldBuilder(callbackClass).
type(String.class).
name("callbackPath").
javadoc("Optional path to set up the endpoint").
build();
async = new FieldBuilder(callbackClass).
type(Boolean.class).
name(ASYNC_FIELD_NAME).
javadoc("Whether the the message processor that invokes the callback flow is asynchronous").
build();
connectorField = new FieldBuilder(callbackClass).
type(Connector.class).
name(CONNECTOR_FIELD_NAME).
javadoc("HTTP connector").
build();
}
private void generateConstructorArgSimpleFlowConstructAndConnectorRef(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable callbackFlowArg = constructor.param(ref(Flow.class), "callbackFlow");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
Variable connectorArg = constructor.param(ref(Connector.class), "connector");
constructor.body().assign(ExpressionFactory._this().ref(callbackFlowField), callbackFlowArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), connectorArg);
}
private void generateConstructorArgMessageProcessorAndConnectorRef(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable messageProcessorArg = constructor.param(ref(MessageProcessor.class), "callbackMessageProcessor");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
Variable connectorArg = constructor.param(ref(Connector.class), "connector");
constructor.body().assign(ExpressionFactory._this().ref(callbackMessageProcessorField), messageProcessorArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), connectorArg);
}
private void generateConstructorArgMessageProcessorAndCallbackPathAndConnectorRef(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable messageProcessorArg = constructor.param(ref(MessageProcessor.class), "callbackMessageProcessor");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable callbackPathArg = constructor.param(ref(String.class), "callbackPath");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
Variable connectorArg = constructor.param(ref(Connector.class), "connector");
constructor.body().assign(ExpressionFactory._this().ref(callbackMessageProcessorField), messageProcessorArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(callbackPathField), callbackPathArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), connectorArg);
}
private void generateConstructorArgSimpleFlowConstruct(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable callbackFlowArg = constructor.param(ref(Flow.class), "callbackFlow");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
constructor.body().assign(ExpressionFactory._this().ref(callbackFlowField), callbackFlowArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), ExpressionFactory._null());
}
private void generateConstructorArgMessageProcessor(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable messageProcessorArg = constructor.param(ref(MessageProcessor.class), "callbackMessageProcessor");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
constructor.body().assign(ExpressionFactory._this().ref(callbackMessageProcessorField), messageProcessorArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), ExpressionFactory._null());
}
private void generateConstructorArgMessageProcessorAndCallbackPath(DefinedClass callbackClass) {
Method constructor = callbackClass.constructor(Modifier.PUBLIC);
Variable messageProcessorArg = constructor.param(ref(MessageProcessor.class), "callbackMessageProcessor");
Variable muleContextArg = constructor.param(ref(MuleContext.class), "muleContext");
Variable callbackDomainArg = constructor.param(ref(String.class), "callbackDomain");
Variable localPortArg = constructor.param(ref(Integer.class), "localPort");
Variable remotePortArg = constructor.param(ref(Integer.class), "remotePort");
Variable callbackPathArg = constructor.param(ref(String.class), "callbackPath");
Variable asyncArg = constructor.param(ref(Boolean.class), "async");
constructor.body().assign(ExpressionFactory._this().ref(callbackMessageProcessorField), messageProcessorArg);
constructor.body().assign(ExpressionFactory._this().ref(muleContextField), muleContextArg);
constructor.body().assign(ExpressionFactory._this().ref(localPortField), localPortArg);
constructor.body().assign(ExpressionFactory._this().ref(domainField), callbackDomainArg);
constructor.body().assign(ExpressionFactory._this().ref(remotePortField), remotePortArg);
constructor.body().assign(ExpressionFactory._this().ref(callbackPathField), callbackPathArg);
constructor.body().assign(ExpressionFactory._this().ref(async), asyncArg);
constructor.body().assign(ExpressionFactory._this().ref(connectorField), ExpressionFactory._null());
}
private void generateBuildUrlMethod(DefinedClass callbackClass) {
buildUrlMethod = callbackClass.method(Modifier.PRIVATE, ref(String.class), "buildUrl");
Block body = buildUrlMethod.body();
Variable urlBuilder = body.decl(ref(StringBuilder.class), "urlBuilder", ExpressionFactory._new(ref(StringBuilder.class)));
Block ifDomainNotPrefixed = body._if(Op.not(domainField.invoke("contains").arg("://")))._then();
Conditional ifConnectorNotNull = ifDomainNotPrefixed._if(Op.ne(connectorField, ExpressionFactory._null()));
ifConnectorNotNull._then().invoke(urlBuilder, "append").arg(Op.plus(connectorField.invoke("getProtocol"), ExpressionFactory.lit("://")));
ifConnectorNotNull._else().invoke(urlBuilder, "append").arg("http://");
body.invoke(urlBuilder, "append").arg(domainField);
body.invoke(urlBuilder, "append").arg(":");
body.invoke(urlBuilder, "append").arg(remotePortField);
body.invoke(urlBuilder, "append").arg("/");
Conditional ifCallbackPathNotNull = body._if(Op.ne(callbackPathField, ExpressionFactory._null()));
ifCallbackPathNotNull._then().invoke(urlBuilder, "append").arg(callbackPathField);
ifCallbackPathNotNull._else().invoke(urlBuilder, "append").arg(ref(UUID.class).staticInvoke("randomUUID"));
body._return(urlBuilder.invoke("toString"));
}
private void generateWrapMessageProcessorInAsyncChain(DefinedClass callbackClass) {
wrapMessageProcessorInAsyncChain = callbackClass.method(Modifier.PRIVATE, ref(MessageProcessor.class), "wrapMessageProcessorInAsyncChain")._throws(ref(MuleException.class));
Variable messageProcessorParam = wrapMessageProcessorInAsyncChain.param(ref(MessageProcessor.class), "messageProcessor");
Block body = wrapMessageProcessorInAsyncChain.body();
Variable asyncMessageProcessorsFactoryBean = body.decl(ref(AsyncMessageProcessorsFactoryBean.class), "asyncMessageProcessorsFactoryBean", ExpressionFactory._new(ref(AsyncMessageProcessorsFactoryBean.class)));
body.invoke(asyncMessageProcessorsFactoryBean, "setMuleContext").arg(muleContextField);
body.invoke(asyncMessageProcessorsFactoryBean, "setMessageProcessors").arg(ref(Arrays.class).staticInvoke("asList").arg(messageProcessorParam));
body.invoke(asyncMessageProcessorsFactoryBean, "setProcessingStrategy").arg(ExpressionFactory._new(ref(AsynchronousProcessingStrategy.class)));
TryStatement tryStatement = body._try();
tryStatement.body()._return(ExpressionFactory.cast(ref(MessageProcessor.class), asyncMessageProcessorsFactoryBean.invoke("getObject")));
CatchBlock catchBlock = tryStatement._catch(ref(Exception.class));
catchBlock.body()._throw(ExpressionFactory._new(ref(FlowConstructInvalidException.class)).arg(catchBlock.param("e")));
}
private void generateCreateConnectorMethod(DefinedClass callbackClass) {
createConnectorMethod = callbackClass.method(Modifier.PRIVATE, ref(Connector.class), "createConnector")._throws(ref(MuleException.class));
Block body = createConnectorMethod.body();
Conditional ifConnectorNotNull = body._if(Op.ne(connectorField, ExpressionFactory._null()));
ifConnectorNotNull._then()._return(ExpressionFactory._this().ref(connectorField.name()));
Variable muleRegistryVariable = body.decl(ref(MuleRegistry.class), "muleRegistry", ExpressionFactory.invoke(muleContextField, "getRegistry"));
Variable httpConnectorVariable = body.decl(ref(Connector.class), "httpConnector", ExpressionFactory.invoke(muleRegistryVariable, "lookupConnector").arg("connector.http.mule.default"));
Conditional conditional = body._if(Op.ne(httpConnectorVariable, ExpressionFactory._null()));
conditional._then()._return(httpConnectorVariable);
conditional._else().block().invoke(loggerField, "error").arg("Could not find connector with name 'connector.http.mule.default'");
conditional._else().block()._throw(ExpressionFactory._new(ref(DefaultMuleException.class)).arg("Could not find connector with name 'connector.http.mule.default'"));
}
private void generateCreateHttpInboundEndpointMethod(DefinedClass callbackClass) {
createHttpInboundEndpointMethod = callbackClass.method(Modifier.PRIVATE, ref(InboundEndpoint.class), "createHttpInboundEndpoint")._throws(ref(MuleException.class));
Block body = createHttpInboundEndpointMethod.body();
Variable inBuilderVariable = body.decl(ref(EndpointURIEndpointBuilder.class), "inBuilder", ExpressionFactory._new(ref(EndpointURIEndpointBuilder.class)).arg(localUrlField).arg(muleContextField));
body.invoke(inBuilderVariable, "setConnector").arg(ExpressionFactory.invoke(createConnectorMethod));
body.invoke(inBuilderVariable, "setExchangePattern").arg(ref(MessageExchangePattern.class).staticRef(INBOUND_ENDPOINT_EXCHANGE_PATTERN));
Variable endpointFactoryVariable = body.decl(ref(EndpointFactory.class), "endpointFactory", ExpressionFactory.invoke(muleContextField, "getEndpointFactory"));
body._return(ExpressionFactory.invoke(endpointFactoryVariable, "getInboundEndpoint").arg(inBuilderVariable));
}
private void generateStartMethod(DefinedClass callbackClass) {
Method startMethod = callbackClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "start")._throws(ref(MuleException.class));
Block body = startMethod.body();
body.assign(ExpressionFactory._this().ref(urlField), ExpressionFactory.invoke(buildUrlMethod));
body.assign(ExpressionFactory._this().ref(localUrlField), urlField.invoke("replaceFirst").arg(domainField).arg("localhost"));
body.assign(ExpressionFactory._this().ref(localUrlField), localUrlField.invoke("replaceFirst").arg(ref(String.class).staticInvoke("valueOf").arg(remotePortField)).arg(ref(String.class).staticInvoke("valueOf").arg(localPortField)));
Variable dynamicFlowName = body.decl(ref(String.class), "dynamicFlowName", ref(String.class).staticInvoke("format").arg("DynamicFlow-%s").arg(localUrlField));
body.assign(flowConstructVariable, ExpressionFactory._new(ref(Flow.class)).arg(dynamicFlowName).arg(muleContextField));
body.invoke(flowConstructVariable, "setMessageSource").arg(ExpressionFactory.invoke(createHttpInboundEndpointMethod));
Variable messageProcessor = body.decl(ref(MessageProcessor.class), "messageProcessor");
Conditional ifCallbackFlowNotNull = body._if(Op.ne(callbackFlowField, ExpressionFactory._null()));
ifCallbackFlowNotNull._then().assign(messageProcessor, ExpressionFactory._new(callbackClass.listClasses()[0]));
ifCallbackFlowNotNull._else().assign(messageProcessor, callbackMessageProcessorField);
body._if(async)._then().assign(messageProcessor, ExpressionFactory.invoke(wrapMessageProcessorInAsyncChain).arg(messageProcessor));
Variable mps = body.decl(ref(List.class).narrow(ref(MessageProcessor.class)), "messageProcessors", ExpressionFactory._new(ref(ArrayList.class).narrow(MessageProcessor.class)));
body.invoke(mps, "add").arg(messageProcessor);
body.invoke(flowConstructVariable, "setMessageProcessors").arg(mps);
body.invoke(flowConstructVariable, "initialise");
body.invoke(flowConstructVariable, "start");
body.invoke(loggerField, "debug").arg(ref(String.class).staticInvoke("format").arg("Created flow with http inbound endpoint listening at: %s").arg(urlField));
}
private void generateStopMethod(DefinedClass callbackClass) {
Method stopMethod = callbackClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "stop")._throws(ref(MuleException.class));
Block body = stopMethod.body();
Block block = body._if(Op.ne(flowConstructVariable, ExpressionFactory._null()))._then();
block.invoke(flowConstructVariable, "stop");
block.invoke(flowConstructVariable, "dispose");
block.invoke(loggerField, "debug").arg("Http callback flow stopped");
}
private void createMessageProcessorInnerClass(DefinedClass callbackClass) {
DefinedClass messageProcessor = callbackClass._class("FlowRefMessageProcessor")._implements(ref(MessageProcessor.class));
Method processMethod = messageProcessor.method(Modifier.PUBLIC, ref(MuleEvent.class), "process")._throws(ref(MuleException.class));
processMethod.param(ref(MuleEvent.class), "event");
processMethod.body()._return(ExpressionFactory.invoke(callbackFlowField, "process").arg(processMethod.params().get(0)));
}
private DefinedClass getDefaultHttpCallbackClass(TypeElement type) {
String httpCallbackClassName = context.getNameUtils().generateClassNameInPackage(type, NamingContants.CONFIG_NAMESPACE, CLASS_NAME);
Package pkg = context.getCodeModel()._package(context.getNameUtils().getPackageName(httpCallbackClassName));
DefinedClass clazz = pkg._class(context.getNameUtils().getClassName(httpCallbackClassName), new Class[]{HttpCallback.class});
context.setClassRole(HTTP_CALLBACK_ROLE, clazz);
return clazz;
}
}