/******************************************************************************* * Copyright (c) 2012 BMW Car IT 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 org.jnario.spec.ui.wizards; import static com.google.common.collect.Iterables.filter; import static org.eclipse.xtext.util.Strings.isEmpty; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.xtext.common.types.JvmGenericType; import org.eclipse.xtext.common.types.JvmOperation; import org.eclipse.xtext.common.types.access.IJvmTypeProvider; import org.eclipse.xtext.common.types.access.IJvmTypeProvider.Factory; import org.eclipse.xtext.common.types.access.jdt.JdtTypeProviderFactory; import org.eclipse.xtext.common.types.util.jdt.IJavaElementFinder; import org.eclipse.xtext.ui.resource.XtextResourceSetProvider; import org.jnario.spec.naming.OperationNameProvider; import org.jnario.ui.wizards.JnarioFileCreator; import com.google.inject.Inject; /** * @author Sebastian Benz - Initial contribution and API */ @SuppressWarnings("restriction") public class SpecCreator extends JnarioFileCreator{ private final OperationNameProvider nameProvider; private final Factory typeProviderFactory; private final IJavaElementFinder javaElementFinder; private XtextResourceSetProvider resourceSetProvider; @Inject public SpecCreator(JdtTypeProviderFactory typeProviderFactory, OperationNameProvider nameProvider, IJavaElementFinder javaElementFinder, XtextResourceSetProvider resourceSetProvider){ this.typeProviderFactory = typeProviderFactory; this.nameProvider = nameProvider; this.javaElementFinder = javaElementFinder; this.resourceSetProvider = resourceSetProvider; } public String create(IJavaProject javaProject, String description, IPackageFragment packageFragment, String classUnderTest, IMethod[] contextMethods, IProgressMonitor monitor) { IJvmTypeProvider typeProvider = createTypeProvider(javaProject); StringBuffer sb = new StringBuffer(); if(packageFragment.getElementName() != null && !packageFragment.getElementName().equals("")){ sb.append("package "); sb.append(packageFragment.getElementName()); sb.append("\n\n"); } if(!isEmpty(classUnderTest)) { addImport(sb, classUnderTest); sb.append("\n"); } sb.append("describe "); if(!isEmpty(classUnderTest)){ sb.append(stripPackage(classUnderTest)); sb.append(" "); } if(!isEmpty(description)){ sb.append("\""); sb.append(description); sb.append("\""); } if(isEmpty(classUnderTest) && isEmpty(description)){ sb.append("\"\""); } sb.append("{\n"); for (IMethod method : contextMethods) { sb.append("\n\tcontext "); sb.append(signature(method, typeProvider)); sb.append("{\n\t\t\n\t}\n"); } sb.append("\n}"); return sb.toString(); } protected IJvmTypeProvider createTypeProvider(IJavaProject javaProject) { ResourceSet resourceSet = resourceSetProvider.get(javaProject.getProject()); return typeProviderFactory.createTypeProvider(resourceSet); } private String signature(IMethod method, IJvmTypeProvider typeProvider) { String typeName = method.getClassFile().getType().getFullyQualifiedName(); JvmGenericType type = (JvmGenericType) typeProvider.findTypeByName(typeName); for (JvmOperation operation : filter(type.getMembers(), JvmOperation.class)) { IJavaElement javaElement = javaElementFinder.findElementFor(operation); if(javaElement.equals(method)){ return nameProvider.apply(operation).getFirstSegment(); } } throw new IllegalStateException("Could not resolve JVM identifiable for " + method); } private Object stripPackage(Object superType) { return superType.toString().replaceAll("^(\\w+\\.)*", "") ; } private void addImport(StringBuffer sb, Object object) { sb.append("import "); sb.append(removeGenerics(object)); sb.append("\n"); } private String removeGenerics(Object object) { return object.toString().replaceAll("<.*>$", ""); } }