Fixed ambiguous service call with no arguments.

Change-Id: Iee785ed958d1d1dc4c79a5b056222d469584d93c
diff --git a/plugins/org.eclipse.acceleo.aql.migration/META-INF/MANIFEST.MF b/plugins/org.eclipse.acceleo.aql.migration/META-INF/MANIFEST.MF
index 9358abb..dc81e8c 100644
--- a/plugins/org.eclipse.acceleo.aql.migration/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.acceleo.aql.migration/META-INF/MANIFEST.MF
@@ -15,6 +15,9 @@
  org.eclipse.ocl.ecore,
  org.eclipse.acceleo.aql,
  org.eclipse.acceleo.query,
- org.eclipse.acceleo.parser
+ org.eclipse.acceleo.parser,
+ org.eclipse.jdt.core,
+ org.eclipse.text,
+ org.eclipse.core.resources
 Export-Package: org.eclipse.acceleo.aql.migration,
  org.eclipse.acceleo.aql.migration.standalone
diff --git a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/ModuleMigrator.java b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/ModuleMigrator.java
index 2d8eaf9..31a7e9a 100644
--- a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/ModuleMigrator.java
+++ b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/ModuleMigrator.java
@@ -12,8 +12,8 @@
 

 import java.io.File;

 import java.io.IOException;

-import java.nio.file.FileSystems;

 import java.nio.file.Files;

+import java.nio.file.Path;

 import java.util.ArrayList;

 import java.util.List;

 

@@ -62,18 +62,21 @@
 	private IModuleResolver moduleResolver;

 

 	/**

-	 * The file separator.

+	 * The target folder {@link Path}.

 	 */

-	private final String fileSeparator = FileSystems.getDefault().getSeparator();

+	private final Path targetFolderPath;

 

 	/**

 	 * Constructor.

 	 * 

 	 * @param moduleResolver

 	 *            a resolver able to retrieve qualified names of proxy modules (imports, extends)

+	 * @param targetFolderPath

+	 *            the target folder {@link Path}

 	 */

-	public ModuleMigrator(IModuleResolver moduleResolver) {

+	public ModuleMigrator(IModuleResolver moduleResolver, Path targetFolderPath) {

 		this.moduleResolver = moduleResolver;

+		this.targetFolderPath = targetFolderPath;

 		this.resourceSet = createA3ResourceSet();

 	}

 

@@ -91,7 +94,7 @@
 		org.eclipse.acceleo.model.mtl.Module legacyModule = (org.eclipse.acceleo.model.mtl.Module)ModelUtils

 				.load(emtlFile, resourceSet);

 

-		ModuleConverter moduleConverter = new ModuleConverter(moduleResolver);

+		ModuleConverter moduleConverter = new ModuleConverter(moduleResolver, targetFolderPath);

 		Module convertedModule = (Module)moduleConverter.convert(legacyModule);

 		if (originMTLFile != null) {

 			parseModuleDocumentation(convertedModule, originMTLFile);

diff --git a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ExpressionConverter.java b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ExpressionConverter.java
index 355a74e..1fe19fc 100644
--- a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ExpressionConverter.java
+++ b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ExpressionConverter.java
@@ -10,6 +10,14 @@
  *******************************************************************************/

 package org.eclipse.acceleo.aql.migration.converters;

 

+import java.io.File;

+import java.io.IOException;

+import java.nio.file.FileSystems;

+import java.nio.file.Files;

+import java.nio.file.Path;

+import java.nio.file.StandardOpenOption;

+import java.util.Collections;

+

 import org.eclipse.acceleo.AcceleoFactory;

 import org.eclipse.acceleo.ExpressionStatement;

 import org.eclipse.acceleo.Statement;

@@ -43,6 +51,23 @@
 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.emf.ecore.EOperation;

 import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl;

+import org.eclipse.jdt.core.dom.AST;

+import org.eclipse.jdt.core.dom.ASTNode;

+import org.eclipse.jdt.core.dom.ASTParser;

+import org.eclipse.jdt.core.dom.ASTVisitor;

+import org.eclipse.jdt.core.dom.Block;

+import org.eclipse.jdt.core.dom.CompilationUnit;

+import org.eclipse.jdt.core.dom.MethodDeclaration;

+import org.eclipse.jdt.core.dom.MethodInvocation;

+import org.eclipse.jdt.core.dom.ReturnStatement;

+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

+import org.eclipse.jdt.core.dom.Type;

+import org.eclipse.jdt.core.dom.TypeDeclaration;

+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.Document;

+import org.eclipse.jface.text.IDocument;

 import org.eclipse.ocl.ecore.BooleanLiteralExp;

 import org.eclipse.ocl.ecore.CollectionItem;

 import org.eclipse.ocl.ecore.CollectionLiteralExp;

@@ -62,6 +87,8 @@
 import org.eclipse.ocl.ecore.TypeExp;

 import org.eclipse.ocl.ecore.Variable;

 import org.eclipse.ocl.ecore.VariableExp;

+import org.eclipse.text.edits.MalformedTreeException;

+import org.eclipse.text.edits.TextEdit;

 

 /**

  * A converter dedicated to OCLExpressions.

@@ -70,6 +97,72 @@
  */

 public final class ExpressionConverter extends AbstractConverter {

 

+	private final class ServiceMethodRefactorVisitor extends ASTVisitor {

+

+		/**

+		 * The {@link IDocument} of the source code.

+		 */

+		private final IDocument document;

+

+		/**

+		 * The service name.

+		 */

+		private final String serviceName;

+

+		private ServiceMethodRefactorVisitor(IDocument document, String serviceName) {

+			this.document = document;

+			this.serviceName = serviceName;

+		}

+

+		@Override

+		public boolean visit(MethodDeclaration method) {

+			if (method.getName().getIdentifier().equals(serviceName) && method.parameters().isEmpty()) {

+				final ASTRewrite rewrite = ASTRewrite.create(method.getAST());

+

+				final MethodDeclaration newMethod = method.getAST().newMethodDeclaration();

+				// newMethod: <serviceModifiers> <serviceType> <serviceName>JavaService(Object object)

+				for (Object modifier : method.modifiers()) {

+					newMethod.modifiers().add(rewrite.createCopyTarget((ASTNode)modifier));

+				}

+				newMethod.setReturnType2((Type)rewrite.createCopyTarget(method.getReturnType2()));

+				newMethod.setName(newMethod.getAST().newSimpleName(serviceName + JAVA_SERVICE));

+				final SingleVariableDeclaration parameter = newMethod.getAST().newSingleVariableDeclaration();

+				parameter.setName(newMethod.getAST().newSimpleName("object"));

+				parameter.setType(newMethod.getAST().newSimpleType(newMethod.getAST().newName("Object")));

+				newMethod.parameters().add(parameter);

+

+				// newMethod body: return <serviceName>();

+				final Block body = newMethod.getAST().newBlock();

+				final ReturnStatement returnStatement = newMethod.getAST().newReturnStatement();

+				final MethodInvocation methodInvocation = newMethod.getAST().newMethodInvocation();

+				methodInvocation.setName(newMethod.getAST().newSimpleName(serviceName));

+				returnStatement.setExpression(methodInvocation);

+				body.statements().add(returnStatement);

+				newMethod.setBody(body);

+

+				// add the newMethod to the containing Class

+				final TypeDeclaration typeDeclaration = (TypeDeclaration)method.getParent();

+				final ListRewrite declarations = rewrite.getListRewrite(typeDeclaration,

+						TypeDeclaration.BODY_DECLARATIONS_PROPERTY);

+				declarations.insertAfter(newMethod, method, null);

+				try {

+					final TextEdit edit = rewrite.rewriteAST(document, Collections.EMPTY_MAP);

+					edit.apply(document);

+				} catch (IllegalArgumentException | MalformedTreeException | BadLocationException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+				}

+			}

+

+			return super.visit(method);

+		}

+	}

+

+	/**

+	 * The java service suffix.

+	 */

+	private static final String JAVA_SERVICE = "JavaService";

+

 	/**

 	 * The self variable.

 	 */

@@ -81,6 +174,21 @@
 	private boolean resolveSelf = true;

 

 	/**

+	 * The trget folder {@link Path}.

+	 */

+	private final Path targetFolderPath;

+

+	/**

+	 * Constructor.

+	 * 

+	 * @param targetFolderPath

+	 *            the target folder {@link Path}

+	 */

+	public ExpressionConverter(Path targetFolderPath) {

+		this.targetFolderPath = targetFolderPath;

+	}

+

+	/**

 	 * Converts the given {@link OCLExpression} to a {@link Statement}.

 	 * 

 	 * @param input

@@ -265,11 +373,19 @@
 			output.setServiceName(serviceName);

 			map(((CollectionLiteralExp)input.getArgument().get(2)).getPart(), output.getArguments());

 			if (output.getArguments().isEmpty()) {

+				output.setServiceName(serviceName + JAVA_SERVICE);

 				final String varName = ((Query)input.eContainer()).getParameter().get(0).getName();

 				final VarRef varRef = AstFactory.eINSTANCE.createVarRef();

 				varRef.setVariableName(varName);

 				output.getArguments().add(varRef);

-				// TODO add an arguments to the existing Java method ?

+				final String serviceClassName = ((org.eclipse.ocl.expressions.StringLiteralExp<EClassifier>)input

+						.getArgument().get(0)).getStringSymbol();

+				try {

+					refactorService(serviceClassName, serviceName);

+				} catch (IOException e) {

+					// TODO Auto-generated catch block

+					e.printStackTrace();

+				}

 			}

 			res = output;

 		} else {

@@ -283,6 +399,30 @@
 	}

 

 	/**

+	 * Renames the service and add an {@link Object} parameter.

+	 * 

+	 * @param serviceClassName

+	 *            the service Class name

+	 * @param serviceName

+	 *            the service name

+	 * @throws IOException

+	 *             if the java file can't be read or written

+	 */

+	private void refactorService(String serviceClassName, String serviceName) throws IOException {

+		ASTParser parser = ASTParser.newParser(AST.JLS10);

+		final File javaFile = new File(targetFolderPath + FileSystems.getDefault().getSeparator()

+				+ serviceClassName.replace(".", FileSystems.getDefault().getSeparator()) + ".java");

+		if (javaFile.exists()) {

+			final IDocument document = new Document(new String(Files.readAllBytes(javaFile.toPath())));

+			parser.setSource(document.get().toCharArray());

+			parser.setKind(ASTParser.K_COMPILATION_UNIT);

+			final CompilationUnit cu = (CompilationUnit)parser.createAST(null);

+			cu.accept(new ServiceMethodRefactorVisitor(document, serviceName));

+			Files.write(javaFile.toPath(), document.get().getBytes(), StandardOpenOption.CREATE);

+		}

+	}

+

+	/**

 	 * Tells if the given {@link OperationCallExp} is an invoke() call.

 	 * 

 	 * @param input

diff --git a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ModuleConverter.java b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ModuleConverter.java
index ae4d266..b063966 100644
--- a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ModuleConverter.java
+++ b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/converters/ModuleConverter.java
@@ -10,6 +10,7 @@
  *******************************************************************************/

 package org.eclipse.acceleo.aql.migration.converters;

 

+import java.nio.file.Path;

 import java.util.ArrayList;

 import java.util.Collections;

 import java.util.HashSet;

@@ -73,7 +74,7 @@
 	/**

 	 * A converter dedicated to expressions.

 	 */

-	private ExpressionConverter expressionConverter = new ExpressionConverter();

+	private ExpressionConverter expressionConverter;

 

 	/**

 	 * The module resolver, for imports/extends.

@@ -90,9 +91,12 @@
 	 * 

 	 * @param moduleResolver

 	 *            the module resolver

+	 * @param targetFolderPath

+	 *            the target folder {@link Path}

 	 */

-	public ModuleConverter(IModuleResolver moduleResolver) {

+	public ModuleConverter(IModuleResolver moduleResolver, Path targetFolderPath) {

 		this.moduleResolver = moduleResolver;

+		expressionConverter = new ExpressionConverter(targetFolderPath);

 	}

 

 	/**

diff --git a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/standalone/StandaloneMigrator.java b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/standalone/StandaloneMigrator.java
index 60a4d50..4004c8c 100644
--- a/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/standalone/StandaloneMigrator.java
+++ b/plugins/org.eclipse.acceleo.aql.migration/src/org/eclipse/acceleo/aql/migration/standalone/StandaloneMigrator.java
@@ -15,6 +15,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.util.Iterator;
 
 import org.eclipse.acceleo.aql.migration.MigrationException;
@@ -90,28 +91,28 @@
 	 * @throws IOException
 	 */
 	public void migrateAll() throws IOException {
-		Iterator<Path> iterator = Files.walk(sourceFolderPath).filter(p -> p.getFileName().toString()
+		Iterator<Path> iterator = Files.walk(sourceFolderPath).filter(p -> !p.getFileName().toString()
 				.endsWith(MTL_FILE_EXTENSION)).iterator();
 		while (iterator.hasNext()) {
-			Path mtlFile = (Path)iterator.next();
-			migrate(mtlFile);
-		}
-
-		iterator = Files.walk(sourceFolderPath).filter(p -> !p.getFileName().toString().endsWith(
-				MTL_FILE_EXTENSION)).iterator();
-		while (iterator.hasNext()) {
 			final Path javaPath = iterator.next();
 			final Path relativeJavaPath = sourceFolderPath.relativize(javaPath.toAbsolutePath());
 			final Path javaTargetPath = targetFolderPath.resolve(relativeJavaPath);
 
 			final File javaFile = javaPath.toFile();
 			final File javaTargetFile = javaTargetPath.toFile();
-			if (javaFile.exists() && !javaTargetFile.exists()) {
+			if (javaFile.exists() && !javaFile.isDirectory()) {
 				javaTargetFile.getParentFile().mkdirs();
-				Files.copy(javaFile.toPath(), javaTargetFile.toPath());
+				Files.copy(javaFile.toPath(), javaTargetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
 				System.out.println("Copied " + javaFile.getAbsolutePath());
 			}
 		}
+
+		iterator = Files.walk(sourceFolderPath).filter(p -> p.getFileName().toString().endsWith(
+				MTL_FILE_EXTENSION)).iterator();
+		while (iterator.hasNext()) {
+			Path mtlFile = (Path)iterator.next();
+			migrate(mtlFile);
+		}
 	}
 
 	/**
@@ -130,7 +131,7 @@
 			try {
 				// migrate AST
 				org.eclipse.acceleo.Module module = new ModuleMigrator(new StandaloneModuleResolver(
-						binFolderPath)).migrate(emtlFile, mtlFile.toFile());
+						binFolderPath), targetFolderPath).migrate(emtlFile, mtlFile.toFile());
 
 				// serialize
 				String a4Content = new AcceleoAstSerializer().serialize(module);
diff --git a/tests/org.eclipse.acceleo.aql.migration.tests/src/org/eclipse/acceleo/aql/migration/tests/utils/AbstractMigrationTestSuite.java b/tests/org.eclipse.acceleo.aql.migration.tests/src/org/eclipse/acceleo/aql/migration/tests/utils/AbstractMigrationTestSuite.java
index 10f7442..78486f8 100644
--- a/tests/org.eclipse.acceleo.aql.migration.tests/src/org/eclipse/acceleo/aql/migration/tests/utils/AbstractMigrationTestSuite.java
+++ b/tests/org.eclipse.acceleo.aql.migration.tests/src/org/eclipse/acceleo/aql/migration/tests/utils/AbstractMigrationTestSuite.java
@@ -64,7 +64,7 @@
 					.replaceAll("/", "::").replaceAll(".emtl", "");
 			return qualifiedName;
 		}
-	});
+	}, null);
 
 	/**
 	 * The test folder path.