blob: 48e8dd8232e90822ad469043b3cbc8d7a5fc40c8 [file] [log] [blame]
package org.eclipse.gmf.codegen.xtend.ui.handlers;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gmf.common.UnexpectedBehaviourException;
import org.eclipse.gmf.internal.common.codegen.TextEmitter;
import com.google.inject.Injector;
public class Xtend2Emitter implements TextEmitter {
private final Class<?> myXtendGenerator;
private final String myMethodName;
private final Injector myInjector;
public Xtend2Emitter(Injector injector, Class<?> clazz, String methodName) {
myInjector = injector;
myXtendGenerator = clazz;
myMethodName = methodName;
}
@Override
public String generate(IProgressMonitor monitor, Object[] arguments) throws InterruptedException, InvocationTargetException, UnexpectedBehaviourException {
return generate(monitor, myMethodName, arguments);
}
protected String generate(IProgressMonitor monitor, String methodName, Object[] arguments) throws InterruptedException, InvocationTargetException, UnexpectedBehaviourException {
if (monitor != null && monitor.isCanceled()) {
throw new InterruptedException();
}
if (arguments.length > 1) {
List<Object> fixedArgs = new LinkedList<Object>();
fixedArgs.add(arguments[0]);
for (int i = 1; i < arguments.length; i++) {
fixedArgs.add(arguments[i]);
}
arguments = fixedArgs.toArray();
}
Object generator = instantiateGenerator();
Method method = getGeneratorMethod(arguments.length, methodName);
Object result;
try {
result = method.invoke(generator, arguments);
} catch (IllegalArgumentException e) {
throw new UnexpectedBehaviourException("Invocation failed for: " + this, e);
} catch (IllegalAccessException e) {
throw new UnexpectedBehaviourException("Invocation failed for: " + this, e);
}
if (result == null) {
throw new UnexpectedBehaviourException("Xtend generator returned null for " + this);
}
return String.valueOf(result);
}
private Object instantiateGenerator() throws UnexpectedBehaviourException {
Object instance = myInjector.getInstance(myXtendGenerator);
if (instance == null) {
throw new UnexpectedBehaviourException("Can't instantiate Xtend generator object " + this);
}
return instance;
}
private Method getGeneratorMethod(int paramsCount, String methodName) throws UnexpectedBehaviourException {
Method[] allMethods;
try {
allMethods = myXtendGenerator.getDeclaredMethods();
} catch (SecurityException e) {
throw new UnexpectedBehaviourException("For : " + this, e);
}
Method candidate = null;
for (Method next : allMethods) {
if (methodName.equals(next.getName()) && next.getParameterTypes().length == paramsCount) {
if (candidate != null) {
throw new UnexpectedBehaviourException("More than 1 method found for " + this + ", " + candidate + " vs " + next);
}
candidate = next;
}
}
if (candidate == null) {
throw new UnexpectedBehaviourException("No such method (with params count = " + paramsCount + ") for : " + this);
}
return candidate;
}
@Override
public String toString() {
return "xtend2:[" + myXtendGenerator.getSimpleName() + "#" + myMethodName + "]";
}
protected Object extractTarget(Object[] arguments) {
assert arguments != null && arguments.length > 0;
return arguments[0];
}
protected Injector getInjector() {
return myInjector;
}
protected Class<?> getTemplateClass() {
return myXtendGenerator;
}
}