All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ecfeed.core.implementation.JavaImplementationStatusResolver Maven / Gradle / Ivy

/*******************************************************************************
 *
 * Copyright (c) 2016 ecFeed AS.                                                
 * 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 com.ecfeed.core.implementation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ecfeed.core.model.AbstractNode;
import com.ecfeed.core.model.ChoiceNode;
import com.ecfeed.core.model.ClassNode;
import com.ecfeed.core.model.ClassNodeHelper;
import com.ecfeed.core.model.ConstraintNode;
import com.ecfeed.core.model.GlobalParameterNode;
import com.ecfeed.core.model.IModelVisitor;
import com.ecfeed.core.model.MethodNode;
import com.ecfeed.core.model.MethodParameterNode;
import com.ecfeed.core.model.RootNode;
import com.ecfeed.core.model.TestCaseNode;
import com.ecfeed.core.type.adapter.JavaPrimitiveTypePredicate;
import com.ecfeed.core.utils.JavaTypeHelper;
import com.ecfeed.core.utils.SystemLogger;

public class JavaImplementationStatusResolver extends AbstractImplementationStatusResolver{
	private ModelClassLoader fLoader;
	private Map> fLoadedClasses;
	private InternalStatusResolver fStatusVisitor;

	private class InternalStatusResolver implements IModelVisitor{

		@Override
		public Object visit(RootNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(ClassNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(MethodNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(MethodParameterNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(GlobalParameterNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(TestCaseNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(ConstraintNode node) throws Exception {
			return implementationStatus(node);
		}

		@Override
		public Object visit(ChoiceNode node) throws Exception {
			return implementationStatus(node);
		}
	}

	public JavaImplementationStatusResolver(ILoaderProvider loaderProvider){
		super(new JavaPrimitiveTypePredicate());
		fLoader = loaderProvider.getLoader(true, null);
		fStatusVisitor = new InternalStatusResolver();
		fLoadedClasses = new HashMap<>();
	}

	@Override
	public EImplementationStatus getImplementationStatus(AbstractNode node){
		fLoadedClasses.clear();
		return super.getImplementationStatus(node);
	}

	@Override
	protected EImplementationStatus childrenStatus(List children){
		int size = children.size();
		int implementedChildren = 0;
		int notImplementedChildren = 0;
		for(AbstractNode child : children){
			// do not use the public getImplementationStatus() function to avoid flushing cache
			EImplementationStatus status = implementationStatus(child);
			if(status == EImplementationStatus.IMPLEMENTED) ++implementedChildren;
			if(status == EImplementationStatus.NOT_IMPLEMENTED) ++notImplementedChildren;
		}
		if(implementedChildren == size){
			return EImplementationStatus.IMPLEMENTED;
		}
		else if(notImplementedChildren == size){
			return EImplementationStatus.NOT_IMPLEMENTED;
		}
		return EImplementationStatus.PARTIALLY_IMPLEMENTED;
	}

	@Override
	protected boolean classDefinitionImplemented(String qualifiedName) {
		Class classDefinition = loadClass(qualifiedName);
		return classDefinition != null && classDefinition.isInterface() == false && classDefinition.isEnum() == false && classDefinition.isAnnotation() == false;
	}

	@Override
	protected boolean methodDefinitionImplemented(MethodNode methodModel){
		Class parentClass = loadClass(ClassNodeHelper.getQualifiedName(methodModel.getClassNode()));
		if(parentClass == null){
			return false;
		}
		for(Method m : parentClass.getMethods()){
			if(m.getReturnType().equals(Void.TYPE) == false){
				continue;
			}
			if(Modifier.isPublic(m.getModifiers()) == false){
				continue;
			}
			if(m.getName().equals(methodModel.getFullName()) == false){
				continue;
			}
			List typeNames = getArgTypes(m);
			List modelParameters = methodModel.getMethodParameters();
			if(typeNames.size() != methodModel.getParameters().size()){
				continue;
			}
			List modelTypeNames = new ArrayList<>();
			for(MethodParameterNode parameter : modelParameters){
				modelTypeNames.add(parameter.getType());
			}
			if(modelTypeNames.equals(typeNames) == false){
				continue;
			}
			return true;
		}
		return false;
	}

	@Override
	protected boolean enumDefinitionImplemented(String qualifiedName) {
		Class classDefinition = loadClass(qualifiedName);
		return classDefinition != null && classDefinition.isEnum();
	}

	@Override
	protected boolean enumValueImplemented(String qualifiedName, String value) {
		Class classDefinition = loadClass(qualifiedName);
		if(classDefinition != null && classDefinition.isEnum()){
			for(Field field : classDefinition.getFields()){
				if(field.isEnumConstant() && field.getName().equals(value)){
					return true;
				}
			}
		}
		return false;
	}

	private EImplementationStatus implementationStatus(AbstractNode node) {
		try {
			return (EImplementationStatus)node.accept(fStatusVisitor);
		} catch (Exception e) {SystemLogger.logCatch(e);}
		return EImplementationStatus.NOT_IMPLEMENTED;
	}

	private List getArgTypes(Method method) {
		List argTypes = new ArrayList();
		for(Class parameter : method.getParameterTypes()){
			argTypes.add(JavaTypeHelper.getTypeName(parameter.getCanonicalName()));
		}
		return argTypes;
	}

	private Class loadClass(String name){
		if(fLoadedClasses.containsKey(name) == false){
			Class loaded = fLoader.loadClass(name);
			fLoadedClasses.put(name, loaded);
		}
		return fLoadedClasses.get(name);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy