/*******************************************************************************
* Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package de.gebit.integrity.classloading;
import java.lang.reflect.Method;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.common.types.JvmType;
import com.google.inject.Inject;
import de.gebit.integrity.dsl.JavaClassReference;
import de.gebit.integrity.dsl.JavaConstantReference;
import de.gebit.integrity.dsl.MethodReference;
import de.gebit.integrity.dsl.OperationDefinition;
import de.gebit.integrity.exceptions.MethodNotFoundException;
import de.gebit.integrity.exceptions.ModelRuntimeLinkException;
import de.gebit.integrity.fixtures.FixtureMethod;
import de.gebit.integrity.modelsource.ModelSourceExplorer;
/**
* Basic implementation of {@link IntegrityClassLoader}. Uses the injected Java classloader internally.
*
* @author Rene Schneider - initial API and implementation
*
*/
public class DefaultIntegrityClassLoader implements IntegrityClassLoader {
/**
* The actual classloader used internally.
*/
@Inject
protected ClassLoader classLoader;
/**
* The model source explorer.
*/
@Inject
protected ModelSourceExplorer modelSourceExplorer;
@Override
public Class<?> loadClass(JvmType aType) throws ClassNotFoundException {
if (aType == null) {
return null;
}
String tempFullyQualifiedName = aType.getQualifiedName();
return classLoader.loadClass(tempFullyQualifiedName);
}
private Class<?> loadClassGuarded(JvmType aType, EObject aSourceObject) throws ClassNotFoundException {
if (aType == null) {
throw new ModelRuntimeLinkException("Reference to JVM Type missing", aSourceObject,
modelSourceExplorer.determineSourceInformation(aSourceObject));
}
return loadClass(aType);
}
@Override
public Class<?> loadClass(OperationDefinition anOperationDefinition) throws ClassNotFoundException {
if (anOperationDefinition == null || anOperationDefinition.getOperationType() == null) {
return null;
}
return loadClassGuarded(anOperationDefinition.getOperationType().getType(), anOperationDefinition);
}
@Override
public Class<?> loadClass(MethodReference aMethodReference) throws ClassNotFoundException {
if (aMethodReference == null) {
return null;
}
JvmType tempType = aMethodReference.getType();
return loadClassGuarded(tempType, aMethodReference);
}
@Override
public Class<?> loadClass(JavaConstantReference aConstantReference) throws ClassNotFoundException {
if (aConstantReference == null) {
return null;
}
JvmType tempType = aConstantReference.getType();
return loadClassGuarded(tempType, aConstantReference);
}
@Override
public Class<?> loadClass(JavaClassReference aClassReference) throws ClassNotFoundException {
if (aClassReference == null) {
return null;
}
JvmType tempType = aClassReference.getType();
return loadClassGuarded(tempType, aClassReference);
}
@Override
public Method loadMethod(MethodReference aMethodReference) throws ClassNotFoundException, MethodNotFoundException {
if (aMethodReference == null) {
return null;
}
Class<?> tempClassInFocus = loadClass(aMethodReference);
if (aMethodReference.getMethod() == null) {
throw new ModelRuntimeLinkException("Method reference missing", aMethodReference,
modelSourceExplorer.determineSourceInformation(aMethodReference));
}
String tempMethodName = aMethodReference.getMethod().getSimpleName();
if (tempMethodName != null) {
while (tempClassInFocus != null) {
for (Method tempMethod : tempClassInFocus.getMethods()) {
FixtureMethod tempMethodAnnotation = tempMethod.getAnnotation(FixtureMethod.class);
if (tempMethodAnnotation != null) {
String tempCandidateMethodName = tempMethod.getName();
if (tempCandidateMethodName.equals(tempMethodName)) {
return tempMethod;
}
}
}
tempClassInFocus = tempClassInFocus.getSuperclass();
}
}
throw new MethodNotFoundException(modelSourceExplorer.determineSourceSnippet(aMethodReference).trim());
}
}