/**
* 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.adapter;
import org.apache.commons.lang.StringUtils;
import org.mule.api.Capabilities;
import org.mule.api.MuleException;
import org.mule.api.annotations.Configurable;
import org.mule.api.construct.FlowConstructAware;
import org.mule.api.context.MuleContextAware;
import org.mule.api.lifecycle.Startable;
import org.mule.api.lifecycle.Stoppable;
import org.mule.config.PoolingProfile;
import org.mule.devkit.generation.AbstractMessageGenerator;
import org.mule.devkit.generation.DevKitTypeElement;
import org.mule.devkit.generation.GenerationException;
import org.mule.devkit.generation.NamingContants;
import org.mule.devkit.model.code.Block;
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.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.Variable;
import org.mule.util.pool.DefaultLifecycleEnabledObjectPool;
import org.mule.util.pool.LifecyleEnabledObjectPool;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
public class PoolAdapterGenerator extends AbstractMessageGenerator {
@Override
protected boolean shouldGenerate(DevKitTypeElement typeElement) {
return typeElement.isPoolable();
}
@Override
protected void doGenerate(DevKitTypeElement typeElement) throws GenerationException {
DefinedClass poolAdapter = getPoolAdapterClass(typeElement);
poolAdapter.javadoc().add("A <code>" + poolAdapter.name() + "</code> is a wrapper around ");
poolAdapter.javadoc().add(ref(typeElement.asType()));
poolAdapter.javadoc().add(" that enables pooling on the POJO.");
for (VariableElement field : typeElement.getFieldsAnnotatedWith(Configurable.class)) {
FieldVariable configField = poolAdapter.field(Modifier.PRIVATE, ref(field.asType()), field.getSimpleName().toString());
generateSetter(poolAdapter, configField);
}
FieldVariable muleContext = generateFieldForMuleContext(poolAdapter);
FieldVariable flowConstruct = generateFieldForFlowConstruct(poolAdapter);
FieldVariable poolingProfile = poolAdapter.field(Modifier.PROTECTED, ref(PoolingProfile.class), "poolingProfile");
FieldVariable lifecyleEnabledObjectPool = poolAdapter.field(Modifier.PROTECTED, ref(LifecyleEnabledObjectPool.class), "lifecyleEnabledObjectPool");
generateSetter(poolAdapter, poolingProfile);
generateGetter(poolAdapter, poolingProfile);
generateSetter(poolAdapter, lifecyleEnabledObjectPool);
generateGetter(poolAdapter, lifecyleEnabledObjectPool);
generateSetFlowConstructMethod(poolAdapter, flowConstruct);
generateSetMuleContextMethod(poolAdapter, muleContext);
generateStartMethod(typeElement, poolAdapter, lifecyleEnabledObjectPool, muleContext, poolingProfile);
generateStopMethod(poolAdapter, lifecyleEnabledObjectPool);
generateIsCapableOf(typeElement, poolAdapter);
}
private void generateStopMethod(DefinedClass poolAdapter, FieldVariable lifecyleEnabledObjectPool) {
Method stopMethod = poolAdapter.method(Modifier.PUBLIC, context.getCodeModel().VOID, "stop");
stopMethod._throws(MuleException.class);
Block newBody = stopMethod.body()._if(Op.ne(lifecyleEnabledObjectPool, ExpressionFactory._null()))._then();
newBody.add(lifecyleEnabledObjectPool.invoke("stop"));
newBody.add(lifecyleEnabledObjectPool.invoke("close"));
newBody.assign(lifecyleEnabledObjectPool, ExpressionFactory._null());
}
private void generateStartMethod(DevKitTypeElement typeElement, DefinedClass poolAdapter, FieldVariable lifecyleEnabledObjectPool, FieldVariable muleContext, FieldVariable poolingProfile) {
DefinedClass objectFactory = context.getClassForRole(context.getNameUtils().generatePojoFactoryKey(typeElement));
Method startMethod = poolAdapter.method(Modifier.PUBLIC, context.getCodeModel().VOID, "start");
startMethod._throws(MuleException.class);
Variable objectFactoryField = startMethod.body().decl(objectFactory, "objectFactory", ExpressionFactory._new(objectFactory));
for (VariableElement field : typeElement.getFieldsAnnotatedWith(Configurable.class)) {
startMethod.body().add(objectFactoryField.invoke("set" + StringUtils.capitalize(field.getSimpleName().toString())).arg(ExpressionFactory._this().ref(field.getSimpleName().toString())));
}
Invocation defaultLifecycleEnabledObjectPool = ExpressionFactory._new(ref(DefaultLifecycleEnabledObjectPool.class));
defaultLifecycleEnabledObjectPool.arg(objectFactoryField);
defaultLifecycleEnabledObjectPool.arg(poolingProfile);
defaultLifecycleEnabledObjectPool.arg(muleContext);
startMethod.body().assign(lifecyleEnabledObjectPool, defaultLifecycleEnabledObjectPool);
startMethod.body().add(lifecyleEnabledObjectPool.invoke("initialise"));
startMethod.body().add(lifecyleEnabledObjectPool.invoke("start"));
}
private DefinedClass getPoolAdapterClass(TypeElement typeElement) {
String poolAdapterName = context.getNameUtils().generateClassName(typeElement, NamingContants.ADAPTERS_NAMESPACE, NamingContants.POOL_ADAPTER_CLASS_NAME_SUFFIX);
org.mule.devkit.model.code.Package pkg = context.getCodeModel()._package(context.getNameUtils().getPackageName(poolAdapterName));
DefinedClass clazz = pkg._class(context.getNameUtils().getClassName(poolAdapterName));
clazz._implements(Startable.class);
clazz._implements(Stoppable.class);
clazz._implements(MuleContextAware.class);
clazz._implements(FlowConstructAware.class);
clazz._implements(Capabilities.class);
context.setClassRole(context.getNameUtils().generateModuleObjectRoleKey(typeElement), clazz);
return clazz;
}
}