org.eclipse.recommenders.testing.rcp.completion.rules.TemporaryFile.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.recommenders.testing.rcp.completion.rules.TemporaryFile.java

Source

/**
 * Copyright (c) 2015 Codetrails GmbH. 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
 *
 * Contributors: Simon Laffoy - initial API and implementation.
 */
package org.eclipse.recommenders.testing.rcp.completion.rules;

import static java.io.File.separator;
import static org.eclipse.recommenders.testing.jdt.AstUtils.MARKER;
import static org.eclipse.recommenders.testing.rcp.completion.rules.TemporaryProject.SRC_FOLDER_NAME;
import static org.eclipse.recommenders.utils.Checks.ensureIsTrue;
import static org.eclipse.recommenders.utils.Pair.newPair;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
import org.eclipse.recommenders.completion.rcp.IRecommendersCompletionContext;
import org.eclipse.recommenders.completion.rcp.RecommendersCompletionContext;
import org.eclipse.recommenders.internal.rcp.CachingAstProvider;
import org.eclipse.recommenders.testing.rcp.jdt.JavaContentAssistContextMock;
import org.eclipse.recommenders.utils.Constants;
import org.eclipse.recommenders.utils.Pair;

import com.google.common.collect.Sets;

@SuppressWarnings("restriction")
public class TemporaryFile {

    private static final String JAVA_IDENTIFIER_REGEX = "([a-zA-Z_$\\p{Lu}\\p{Ll}]{1}"
            + "[a-zA-Z_$0-9\\p{Lu}\\p{Ll}\\p{Nl}]*)";

    private final ICompilationUnit cu;
    private final Set<Integer> markers;
    private final TemporaryProject tempProject;

    TemporaryFile(TemporaryProject parentProject, CharSequence code) throws CoreException {
        this.tempProject = parentProject;

        Pair<ICompilationUnit, Set<Integer>> struct = createFileAndParseWithMarkers(code);
        this.cu = struct.getFirst();
        this.markers = struct.getSecond();
    }

    public CompilationUnit getAst() {
        return SharedASTProvider.getAST(cu, SharedASTProvider.WAIT_YES, null);
    }

    public IRecommendersCompletionContext triggerContentAssist() throws JavaModelException {
        JavaContentAssistInvocationContext javaContext = new JavaContentAssistContextMock(cu,
                markers.iterator().next());
        return new RecommendersCompletionContext(javaContext, new CachingAstProvider());
    }

    private Pair<ICompilationUnit, Set<Integer>> createFileAndParseWithMarkers(
            final CharSequence contentWithMarkers) throws CoreException {
        final Pair<String, Set<Integer>> content = findMarkers(contentWithMarkers, MARKER);

        final ICompilationUnit cu = createFile(content.getFirst());
        tempProject.refreshAndBuildProject();

        return Pair.newPair(cu, content.getSecond());
    }

    private Pair<String, Set<Integer>> findMarkers(final CharSequence content, String marker) {
        final Set<Integer> markers = Sets.newTreeSet();
        int pos = 0;
        final StringBuilder sb = new StringBuilder(content);
        while ((pos = sb.indexOf(marker, pos)) != -1) {
            sb.deleteCharAt(pos);
            markers.add(pos);
            ensureIsTrue(pos <= sb.length());
            pos--;
        }
        return newPair(sb.toString(), markers);
    }

    private ICompilationUnit createFile(final String content) throws CoreException {
        // get filename
        final String fileName = findClassName(content) + Constants.DOT_JAVA;

        // add the file name and get the file
        StringBuilder projectRelativeFilePath = new StringBuilder();
        projectRelativeFilePath.append(SRC_FOLDER_NAME);
        projectRelativeFilePath.append(separator);

        projectRelativeFilePath.append(fileName);
        final IPath projectRelativePath = new Path(projectRelativeFilePath.toString());

        final IFile file = tempProject.getProject().getFile(projectRelativePath);

        // delete file
        if (file.exists()) {
            file.delete(true, null);
        }

        // create file
        final ByteArrayInputStream is = new ByteArrayInputStream(content.getBytes());
        file.create(is, true, null);
        int attempts = 0;
        while (!file.exists()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            attempts++;
            if (attempts > 10) {
                throw new IllegalStateException("Failed to create file");
            }
        }

        IJavaProject javaProject = tempProject.getJavaProject();
        if (javaProject == null) {
            throw new IllegalStateException("The temporaryProject does not yet have an associated IJavaProject.");
        }

        // get the compilation unit
        Path srcRelativePath = new Path(fileName);
        ICompilationUnit cu = (ICompilationUnit) javaProject.findElement(srcRelativePath);
        while (cu == null) {
            cu = (ICompilationUnit) javaProject.findElement(srcRelativePath);
        }
        return cu;
    }

    private static String findClassName(final CharSequence source) {
        Pattern p = Pattern.compile(".*?class\\s+" + JAVA_IDENTIFIER_REGEX + ".*", Pattern.DOTALL);
        Matcher matcher = p.matcher(source);
        if (!matcher.matches()) {
            p = Pattern.compile(".*interface\\s+" + JAVA_IDENTIFIER_REGEX + ".*", Pattern.DOTALL);
            matcher = p.matcher(source);
        }
        assertTrue(matcher.matches());
        return matcher.group(1);
    }
}