/**
* 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.mule.expression;
import org.mule.api.MuleContext;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.annotations.ExpressionEnricher;
import org.mule.api.annotations.ExpressionLanguage;
import org.mule.api.annotations.param.CorrelationGroupSize;
import org.mule.api.annotations.param.CorrelationId;
import org.mule.api.annotations.param.CorrelationSequence;
import org.mule.api.annotations.param.ExceptionPayload;
import org.mule.api.annotations.param.InboundHeaders;
import org.mule.api.annotations.param.InvocationHeaders;
import org.mule.api.annotations.param.MessageRootId;
import org.mule.api.annotations.param.MessageUniqueId;
import org.mule.api.annotations.param.OutboundHeaders;
import org.mule.api.annotations.param.Payload;
import org.mule.api.annotations.param.SessionHeaders;
import org.mule.api.context.MuleContextAware;
import org.mule.api.lifecycle.Disposable;
import org.mule.api.lifecycle.Initialisable;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.api.lifecycle.Startable;
import org.mule.api.lifecycle.Stoppable;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.devkit.generation.AbstractMessageGenerator;
import org.mule.devkit.generation.DevKitTypeElement;
import org.mule.devkit.generation.NamingContants;
import org.mule.devkit.model.code.CatchBlock;
import org.mule.devkit.model.code.ClassAlreadyExistsException;
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.ForEach;
import org.mule.devkit.model.code.Invocation;
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.TryStatement;
import org.mule.devkit.model.code.TypeReference;
import org.mule.devkit.model.code.TypeVariable;
import org.mule.devkit.model.code.Variable;
import org.mule.expression.ExpressionUtils;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ExpressionEnricherGenerator extends AbstractMessageGenerator {
@Override
protected boolean shouldGenerate(DevKitTypeElement typeElement) {
return typeElement.hasAnnotation(ExpressionLanguage.class) && typeElement.getMethodsAnnotatedWith(ExpressionEnricher.class).size() > 0;
}
@Override
protected void doGenerate(DevKitTypeElement typeElement) {
String name = typeElement.getAnnotation(ExpressionLanguage.class).name();
ExecutableElement executableElement = typeElement.getMethodsAnnotatedWith(ExpressionEnricher.class).get(0);
TypeReference moduleObject = context.getClassForRole(context.getNameUtils().generateModuleObjectRoleKey(typeElement));
DefinedClass enricherClass = getEnricherClass(name, typeElement);
// build trackmap
DefinedClass trackMap = null;
try {
trackMap = enricherClass._class(Modifier.PRIVATE, "TrackMap");
} catch (ClassAlreadyExistsException e) {
trackMap = e.getExistingClass();
}
TypeVariable k = trackMap.generify("K");
TypeVariable v = trackMap.generify("V");
trackMap._implements(ref(Map.class).narrow(k).narrow(v));
FieldVariable trackedMap = trackMap.field(Modifier.PRIVATE, ref(Map.class).narrow(k).narrow(v), "trackedMap");
FieldVariable changedKeys = trackMap.field(Modifier.PRIVATE, ref(Set.class).narrow(k), "changedKeys");
generateTrackMapConstructor(trackMap, k, v, trackedMap, changedKeys);
generateTrackMapSize(trackMap, trackedMap);
generateTrackMapIsEmpty(trackMap, trackedMap);
generateTrackMapContainsKey(trackMap, trackedMap);
generateTrackMapContainsValue(trackMap, trackedMap);
generateTrackMapGet(trackMap, v, trackedMap);
generateTrackMapPut(trackMap, k, v, trackedMap, changedKeys);
generateTrackMapRemove(trackMap, v, trackedMap);
generateTrackMapPutAll(trackMap, k, v, trackedMap);
generateTrackMapClear(trackMap, trackedMap);
generateTrackMapKeySet(trackMap, k, trackedMap);
generateTrackMapChangedKeySet(trackMap, k, changedKeys);
generateTrackMapValues(trackMap, v, trackedMap);
generateTrackMapEntrySet(trackMap, k, v, trackedMap);
context.note("Generating message enricher " + enricherClass.fullName() + " for language at class " + typeElement.getSimpleName().toString());
FieldVariable module = generateModuleField(moduleObject, enricherClass);
Method setMuleContext = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "setMuleContext");
Variable muleContext = setMuleContext.param(ref(MuleContext.class), "muleContext");
Conditional ifModuleIsContextAware = setMuleContext.body()._if(Op._instanceof(module, ref(MuleContextAware.class)));
ifModuleIsContextAware._then().add(ExpressionFactory.cast(ref(MuleContextAware.class), module).invoke("setMuleContext").arg(muleContext));
Method start = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "start");
start._throws(ref(MuleException.class));
Conditional ifModuleIsStartable = start.body()._if(Op._instanceof(module, ref(Startable.class)));
ifModuleIsStartable._then().add(ExpressionFactory.cast(ref(Startable.class), module).invoke("start"));
Method stop = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "stop");
stop._throws(ref(MuleException.class));
Conditional ifModuleIsStoppable = stop.body()._if(Op._instanceof(module, ref(Stoppable.class)));
ifModuleIsStoppable._then().add(ExpressionFactory.cast(ref(Stoppable.class), module).invoke("stop"));
Method init = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "initialise");
init._throws(ref(InitialisationException.class));
Conditional ifModuleIsInitialisable = init.body()._if(Op._instanceof(module, ref(Initialisable.class)));
ifModuleIsInitialisable._then().add(ExpressionFactory.cast(ref(Initialisable.class), module).invoke("initialise"));
Method dispose = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "dispose");
Conditional ifModuleIsDisposable = dispose.body()._if(Op._instanceof(module, ref(Disposable.class)));
ifModuleIsDisposable._then().add(ExpressionFactory.cast(ref(Disposable.class), module).invoke("dispose"));
generateConstructor(moduleObject, enricherClass, module);
generateGetName(name, enricherClass);
generateSetName(enricherClass);
generateComputeClassHierarchyMethod(enricherClass);
generateIsListClassMethod(enricherClass);
generateIsMapClassMethod(enricherClass);
generateIsListMethod(enricherClass);
generateIsMapMethod(enricherClass);
generateIsAssignableFrom(enricherClass);
generateTransformMethod(enricherClass);
Method enrich = enricherClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "enrich");
Variable expression = enrich.param(ref(String.class), "expression");
Variable message = enrich.param(ref(MuleMessage.class), "message");
Variable object = enrich.param(ref(Object.class), "object");
TryStatement tryStatement = enrich.body()._try();
Invocation newArray = ExpressionFactory._new(ref(Class.class).array());
for (VariableElement parameter : executableElement.getParameters()) {
if( parameter.asType().getKind() == TypeKind.BOOLEAN ||
parameter.asType().getKind() == TypeKind.BYTE ||
parameter.asType().getKind() == TypeKind.SHORT ||
parameter.asType().getKind() == TypeKind.CHAR ||
parameter.asType().getKind() == TypeKind.INT ||
parameter.asType().getKind() == TypeKind.FLOAT ||
parameter.asType().getKind() == TypeKind.LONG ||
parameter.asType().getKind() == TypeKind.DOUBLE) {
newArray.arg(ref(parameter.asType()).boxify().staticRef("TYPE"));
} else {
newArray.arg(ref(parameter.asType()).boxify().dotclass());
}
}
Variable parameterClasses = tryStatement.body().decl(ref(Class.class).array(), "parameterClasses", newArray);
int argCount = 0;
Invocation getMethod = module.invoke("getClass").invoke("getMethod").arg(executableElement.getSimpleName().toString()).arg(parameterClasses);
Variable moduleEvaluate = tryStatement.body().decl(ref(java.lang.reflect.Method.class), "evaluateMethod", getMethod);
List<Variable> types = new ArrayList<Variable>();
for (VariableElement parameter : executableElement.getParameters()) {
Variable var = tryStatement.body().decl(ref(Type.class), parameter.getSimpleName().toString() + "Type", moduleEvaluate.invoke("getGenericParameterTypes").component(ExpressionFactory.lit(types.size())));
types.add(var);
}
argCount = 0;
Variable invocationHeadersVar = null;
Variable inboundHeadersVar = null;
Variable outboundHeadersVar = null;
Variable sessionHeadersVar = null;
Invocation evaluateInvoke = module.invoke(executableElement.getSimpleName().toString());
for (VariableElement parameter : executableElement.getParameters()) {
if (parameter.getAnnotation(Payload.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getPayload"))));
} else if (parameter.getAnnotation(ExceptionPayload.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getExceptionPayload"))));
} else if (parameter.getAnnotation(CorrelationId.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getCorrelationId"))));
} else if (parameter.getAnnotation(CorrelationSequence.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getCorrelationSequence"))));
} else if (parameter.getAnnotation(CorrelationGroupSize.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getCorrelationGroupSize"))));
} else if (parameter.getAnnotation(MessageUniqueId.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getUniqueId"))));
} else if (parameter.getAnnotation(MessageRootId.class) != null) {
evaluateInvoke.arg(ExpressionFactory.cast(ref(parameter.asType()).boxify(), ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(message.invoke("getMessageRootId"))));
} else if (parameter.asType().toString().startsWith(MuleMessage.class.getName())) {
evaluateInvoke.arg(message);
} else if (parameter.getAnnotation(InboundHeaders.class) != null) {
InboundHeaders inboundHeaders = parameter.getAnnotation(InboundHeaders.class);
inboundHeadersVar = tryStatement.body().decl(trackMap.narrow(ref(String.class)).narrow(Object.class), "inboundHeaders", ExpressionFactory._null());
if (context.getTypeMirrorUtils().isArrayOrList(parameter.asType())) {
tryStatement.body().assign(inboundHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INBOUND:" + inboundHeaders.value()).arg(message).arg(ref(List.class).dotclass())
))));
} else if (context.getTypeMirrorUtils().isMap(parameter.asType())) {
tryStatement.body().assign(inboundHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INBOUND:" + inboundHeaders.value()).arg(message).arg(ref(Map.class).dotclass())
))));
} else {
tryStatement.body().assign(inboundHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INBOUND:" + inboundHeaders.value()).arg(message)
))));
}
evaluateInvoke.arg(inboundHeadersVar);
} else if (parameter.getAnnotation(SessionHeaders.class) != null) {
SessionHeaders sessionHeaders = parameter.getAnnotation(SessionHeaders.class);
sessionHeadersVar = tryStatement.body().decl(trackMap.narrow(ref(String.class)).narrow(Object.class), "sessionHeaders", ExpressionFactory._null());
if (context.getTypeMirrorUtils().isArrayOrList(parameter.asType())) {
tryStatement.body().assign(sessionHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("SESSION:" + sessionHeaders.value()).arg(message).arg(ref(List.class).dotclass())
))));
} else if (context.getTypeMirrorUtils().isMap(parameter.asType())) {
tryStatement.body().assign(sessionHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("SESSION:" + sessionHeaders.value()).arg(message).arg(ref(Map.class).dotclass())
))));
} else {
tryStatement.body().assign(sessionHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("SESSION:" + sessionHeaders.value()).arg(message)
))));
}
evaluateInvoke.arg(sessionHeadersVar);
} else if (parameter.getAnnotation(OutboundHeaders.class) != null) {
outboundHeadersVar = tryStatement.body().decl(trackMap.narrow(ref(String.class)).narrow(Object.class), "outboundHeaders", ExpressionFactory._null());
tryStatement.body().assign(outboundHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("OUTBOUND:*").arg(message).arg(ref(Map.class).dotclass())
))));
evaluateInvoke.arg(outboundHeadersVar);
} else if (parameter.getAnnotation(InvocationHeaders.class) != null) {
InvocationHeaders invocationHeaders = parameter.getAnnotation(InvocationHeaders.class);
invocationHeadersVar = tryStatement.body().decl(trackMap.narrow(ref(String.class)).narrow(Object.class), "invocationHeaders", ExpressionFactory._null());
if (context.getTypeMirrorUtils().isArrayOrList(parameter.asType())) {
tryStatement.body().assign(invocationHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INVOCATION:" + invocationHeaders.value()).arg(message).arg(ref(List.class).dotclass())
))));
} else if (context.getTypeMirrorUtils().isMap(parameter.asType())) {
tryStatement.body().assign(invocationHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INVOCATION:" + invocationHeaders.value()).arg(message).arg(ref(Map.class).dotclass())
))));
} else {
tryStatement.body().assign(invocationHeadersVar, ExpressionFactory._new(trackMap.narrow(ref(String.class)).narrow(Object.class)).arg(ExpressionFactory.cast(ref(parameter.asType()),
ExpressionFactory.invoke("transform").arg(message).arg(types.get(argCount)).arg(
ref(ExpressionUtils.class).staticInvoke("getPropertyWithScope").arg("INVOCATION:" + invocationHeaders.value()).arg(message)
))));
}
evaluateInvoke.arg(invocationHeadersVar);
} else {
if (parameter.asType().toString().contains("String")) {
evaluateInvoke.arg(expression);
} else if (parameter.asType().toString().contains("Object")) {
evaluateInvoke.arg(object);
}
}
argCount++;
}
if (ref(executableElement.getReturnType()) != context.getCodeModel().VOID) {
Variable newPayload = tryStatement.body().decl(ref(Object.class), "newPayload", evaluateInvoke);
tryStatement.body().add(message.invoke("setPayload").arg(newPayload));
} else {
tryStatement.body().add(evaluateInvoke);
}
if (inboundHeadersVar != null) {
ForEach forEach = tryStatement.body().forEach(ref(String.class), "key", inboundHeadersVar.invoke("changedKeySet"));
forEach.body().add(message.invoke("setProperty").arg(forEach.var()).arg(inboundHeadersVar.invoke("get").arg(forEach.var())).arg(ref(PropertyScope.class).staticRef("INBOUND")));
}
if (outboundHeadersVar != null) {
ForEach forEach = tryStatement.body().forEach(ref(String.class), "key", outboundHeadersVar.invoke("changedKeySet"));
forEach.body().add(message.invoke("setProperty").arg(forEach.var()).arg(outboundHeadersVar.invoke("get").arg(forEach.var())).arg(ref(PropertyScope.class).staticRef("OUTBOUND")));
}
if (sessionHeadersVar != null) {
ForEach forEach = tryStatement.body().forEach(ref(String.class), "key", sessionHeadersVar.invoke("changedKeySet"));
forEach.body().add(message.invoke("setProperty").arg(forEach.var()).arg(sessionHeadersVar.invoke("get").arg(forEach.var())).arg(ref(PropertyScope.class).staticRef("SESSION")));
}
if (invocationHeadersVar != null) {
ForEach forEach = tryStatement.body().forEach(ref(String.class), "key", invocationHeadersVar.invoke("changedKeySet"));
forEach.body().add(message.invoke("setProperty").arg(forEach.var()).arg(invocationHeadersVar.invoke("get").arg(forEach.var())).arg(ref(PropertyScope.class).staticRef("INVOCATION")));
}
catchAndRethrowAsRuntimeException(tryStatement, NoSuchMethodException.class);
catchAndRethrowAsRuntimeException(tryStatement, TransformerException.class);
context.registerAtBoot(enricherClass);
}
private void generateTrackMapEntrySet(DefinedClass trackMap, TypeVariable k, TypeVariable v, FieldVariable trackedMap) {
Method entrySet = trackMap.method(Modifier.PUBLIC, ref(Set.class).narrow(ref(Map.Entry.class).narrow(k).narrow(v)), "entrySet");
entrySet.annotate(ref(Override.class));
entrySet.body()._return(trackedMap.invoke("entrySet"));
}
private void generateTrackMapValues(DefinedClass trackMap, TypeVariable v, FieldVariable trackedMap) {
Method values = trackMap.method(Modifier.PUBLIC, ref(Collection.class).narrow(v), "values");
values.annotate(ref(Override.class));
values.body()._return(trackedMap.invoke("values"));
}
private void generateTrackMapChangedKeySet(DefinedClass trackMap, TypeVariable k, FieldVariable changedKeys) {
Method changedkeySet = trackMap.method(Modifier.PUBLIC, ref(Set.class).narrow(k), "changedKeySet");
changedkeySet.body()._return(ExpressionFactory._this().ref(changedKeys));
}
private void generateTrackMapKeySet(DefinedClass trackMap, TypeVariable k, FieldVariable trackedMap) {
Method keySet = trackMap.method(Modifier.PUBLIC, ref(Set.class).narrow(k), "keySet");
keySet.annotate(ref(Override.class));
keySet.body()._return(trackedMap.invoke("keySet"));
}
private void generateTrackMapClear(DefinedClass trackMap, FieldVariable trackedMap) {
Method clear = trackMap.method(Modifier.PUBLIC, context.getCodeModel().VOID, "clear");
clear.annotate(ref(Override.class));
clear.body().add(trackedMap.invoke("clear"));
}
private void generateTrackMapPutAll(DefinedClass trackMap, TypeVariable k, TypeVariable v, FieldVariable trackedMap) {
Method putAll = trackMap.method(Modifier.PUBLIC, context.getCodeModel().VOID, "putAll");
putAll.annotate(ref(Override.class));
Variable map = putAll.param(ref(Map.class).narrow(k.wildcard()).narrow(v.wildcard()), "map");
putAll.body().add(trackedMap.invoke("putAll").arg(map));
}
private void generateTrackMapRemove(DefinedClass trackMap, TypeVariable v, FieldVariable trackedMap) {
Method remove = trackMap.method(Modifier.PUBLIC, v, "remove");
remove.annotate(ref(Override.class));
Variable o4 = remove.param(ref(Object.class), "o");
remove.body()._return(trackedMap.invoke("remove").arg(o4));
}
private void generateTrackMapPut(DefinedClass trackMap, TypeVariable k, TypeVariable v, FieldVariable trackedMap, FieldVariable changedKeys) {
Method put = trackMap.method(Modifier.PUBLIC, v, "put");
put.annotate(ref(Override.class));
Variable k2 = put.param(k, "k");
Variable v2 = put.param(v, "v");
put.body().add(changedKeys.invoke("add").arg(k2));
put.body()._return(trackedMap.invoke("put").arg(k2).arg(v2));
}
private void generateTrackMapGet(DefinedClass trackMap, TypeVariable v, FieldVariable trackedMap) {
Method get = trackMap.method(Modifier.PUBLIC, v, "get");
get.annotate(ref(Override.class));
Variable o3 = get.param(ref(Object.class), "o");
get.body()._return(trackedMap.invoke("get").arg(o3));
}
private void generateTrackMapConstructor(DefinedClass trackMap, TypeVariable k, TypeVariable v, FieldVariable trackedMap, FieldVariable changedKeys) {
Method constructor = trackMap.constructor(Modifier.PUBLIC);
Variable innerTrackedMap = constructor.param(ref(Map.class).narrow(k).narrow(v), "trackedMap");
constructor.body().assign(ExpressionFactory._this().ref(trackedMap), innerTrackedMap);
constructor.body().assign(ExpressionFactory._this().ref(changedKeys), ExpressionFactory._new(ref(HashSet.class).narrow(k)));
}
private void generateTrackMapContainsValue(DefinedClass trackMap, FieldVariable trackedMap) {
Method containsValue = trackMap.method(Modifier.PUBLIC, context.getCodeModel().BOOLEAN, "containsValue");
containsValue.annotate(ref(Override.class));
Variable o2 = containsValue.param(ref(Object.class), "o");
containsValue.body()._return(trackedMap.invoke("containsValue").arg(o2));
}
private void generateTrackMapContainsKey(DefinedClass trackMap, FieldVariable trackedMap) {
Method containsKey = trackMap.method(Modifier.PUBLIC, context.getCodeModel().BOOLEAN, "containsKey");
containsKey.annotate(ref(Override.class));
Variable o = containsKey.param(ref(Object.class), "o");
containsKey.body()._return(trackedMap.invoke("containsKey").arg(o));
}
private void generateTrackMapIsEmpty(DefinedClass trackMap, FieldVariable trackedMap) {
Method isEmpty = trackMap.method(Modifier.PUBLIC, context.getCodeModel().BOOLEAN, "isEmpty");
isEmpty.annotate(ref(Override.class));
isEmpty.body()._return(trackedMap.invoke("isEmpty"));
}
private void generateTrackMapSize(DefinedClass trackMap, FieldVariable trackedMap) {
Method size = trackMap.method(Modifier.PUBLIC, context.getCodeModel().INT, "size");
size.annotate(ref(Override.class));
size.body()._return(trackedMap.invoke("size"));
}
private void catchAndRethrowAsRuntimeException(TryStatement tryStatement, Class clazz) {
CatchBlock catchBlock = tryStatement._catch(ref(clazz));
Variable e = catchBlock.param("e");
catchBlock.body()._throw(ExpressionFactory._new(ref(RuntimeException.class)).arg(e));
}
private FieldVariable generateModuleField(TypeReference typeElement, DefinedClass evaluatorClass) {
return evaluatorClass.field(Modifier.PRIVATE, typeElement, "module", ExpressionFactory._null());
}
private void generateConstructor(TypeReference typeRef, DefinedClass evaluatorClass, FieldVariable module) {
Method constructor = evaluatorClass.constructor(Modifier.PUBLIC);
constructor.body().assign(module, ExpressionFactory._new(typeRef));
}
private void generateGetName(String name, DefinedClass evaluatorClass) {
Method getName = evaluatorClass.method(Modifier.PUBLIC, ref(String.class), "getName");
getName.body()._return(ExpressionFactory.lit(name));
}
private void generateSetName(DefinedClass evaluatorClass) {
Method setName = evaluatorClass.method(Modifier.PUBLIC, context.getCodeModel().VOID, "setName");
setName.param(ref(String.class), "name");
setName.body()._throw(ExpressionFactory._new(ref(UnsupportedOperationException.class)));
}
private DefinedClass getEnricherClass(String name, Element variableElement) {
String evaluatorClassName = context.getNameUtils().generateClassNameInPackage(variableElement, context.getNameUtils().camel(name) + NamingContants.EXPRESSION_ENRICHER_CLASS_NAME_SUFFIX);
org.mule.devkit.model.code.Package pkg = context.getCodeModel()._package(context.getNameUtils().getPackageName(evaluatorClassName) + NamingContants.EXPRESSIONS_NAMESPACE);
DefinedClass enricherClass = pkg._class(context.getNameUtils().getClassName(evaluatorClassName), new Class<?>[]{org.mule.api.expression.ExpressionEnricher.class});
enricherClass._implements(ref(MuleContextAware.class));
enricherClass._implements(ref(Startable.class));
enricherClass._implements(ref(Stoppable.class));
enricherClass._implements(ref(Initialisable.class));
enricherClass._implements(ref(Disposable.class));
//enricherClass._implements(ref(FlowConstructAware.class));
return enricherClass;
}
}