Package it.wallgren.android.platform.project

Source Code of it.wallgren.android.platform.project.AndroidPlatformProject

/**
* Copyright 2012 Martin Wallgren
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package it.wallgren.android.platform.project;

import org.eclipse.core.resources.FileInfoMatcherDescription;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResourceFilterDescription;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Map;

public class AndroidPlatformProject extends AndroidProject {
    private static String FILE_FILTER_ID = "org.eclipse.ui.ide.patternFilterMatcher";
    private static final String[] BROKEN_CLASSPATH_ENTRIES = new String[]{"frameworks/ex/carousel/java"};

    private final IPath repoPath;

    private final String projectName;

    public AndroidPlatformProject(IPath repoPath) {
        this.repoPath = repoPath;
        this.projectName = getProjectName(repoPath);
    }

    public static String getProjectName(IPath repoPath) {
        return repoPath.lastSegment() + "-platform";
    }

    @Override
    public String getName() {
        return projectName;
    }

    @Override
    public IPath getPath() {
        return repoPath;
    }

    @Override
    public void doCreate(IProgressMonitor monitor) throws CoreException {
        final IProject project = createProject(projectName, monitor);
        addJavaNature(project, monitor);
    }

    private void addJavaNature(IProject project, IProgressMonitor monitor) throws CoreException {
        if (project == null) {
            throw new IllegalStateException(
                    "Project must be created before giving it a Java nature");
        }
        final IFolder repoLink = createRepoLink(monitor, project, repoPath);
        IFile classpath = repoLink.getFile("development/ide/eclipse/.classpath");
        IFile classpathDestination = project.getFile(".classpath");
        if (classpathDestination.exists()) {
            classpathDestination.delete(true, monitor);
        }
        classpath.copy(classpathDestination.getFullPath(), true, monitor);
        final IProjectDescription description = project.getDescription();
        final String[] natures = description.getNatureIds();
        final String[] newNatures = Arrays.copyOf(natures, natures.length + 1);
        newNatures[natures.length] = JavaCore.NATURE_ID;
        description.setNatureIds(newNatures);
        project.setDescription(description, null);
        final IJavaProject javaProject = JavaCore.create(project);
        @SuppressWarnings("rawtypes")
        final Map options = javaProject.getOptions(true);
        // Compliance level need to be 1.6
        JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options);
        javaProject.setOptions(options);

        IClasspathEntry[] classPath = mangleClasspath(javaProject.getRawClasspath(), project,
                repoLink);
        javaProject.setRawClasspath(classPath, monitor);
        javaProject.setOutputLocation(javaProject.getPath().append("out"), monitor);
    }

    private IClasspathEntry[] mangleClasspath(IClasspathEntry[] rawClasspath, IProject project,
            IFolder repoLink) {
        LinkedList<IClasspathEntry> entries = new LinkedList<IClasspathEntry>();

        // Filter out anything that is not framworks, packages, libcore or R
        IFile frameworks = project.getFile("frameworks");
        IFile packages = project.getFile("packages");
        IFile libcore = project.getFile("libcore");
        for (IClasspathEntry entry : rawClasspath) {
            if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
                // is frameworks source folder or R source folder
                if (frameworks.getFullPath().isPrefixOf(entry.getPath())
                        || libcore.getFullPath().isPrefixOf(entry.getPath())
                        || packages.getFullPath().isPrefixOf(entry.getPath())
                        || entry.getPath().lastSegment().equals("R")) {
                    IPath path = entry.getPath().removeFirstSegments(1);
                    IFolder entryFolder = repoLink.getFolder(path);
                    if (!isBroken(entryFolder)) {
                        entries.add(JavaCore.newSourceEntry(entryFolder.getFullPath()));
                    }
                }
            }
        }

        // Add the special platform libs container
        entries.add(getAndroidDependenceis(repoPath));
        return entries.toArray(new IClasspathEntry[0]);
    }

    /**
     * Returns true if the classpath entry is non existant or have an
     * compile/build error
     *
     * @param classpathEntry
     * @return
     */
    private boolean isBroken(IFolder classpathEntry) {
        for (String src : BROKEN_CLASSPATH_ENTRIES) {
            if (classpathEntry.getFullPath().toString().endsWith(src)) {
                return true;
            }
        }
        return !classpathEntry.exists();
    }

    private IFolder createRepoLink(IProgressMonitor monitor, IProject project, IPath repoPath)
            throws CoreException {
        final IFolder repoLink = project.getFolder(repoPath.lastSegment());
        if (repoLink.exists()) {
            // This is an existing project the link already exists
            return repoLink;
        }

        // List of root folders we want to keep, all else is hidden. This is for
        // performance reasons. Indexing the entire Android repo is expensive as
        // shit
        String[] resources = new String[] {
                "frameworks", "out", "libcore", "development"
        };

        for (String res : resources) {
            repoLink.createFilter(IResourceFilterDescription.INCLUDE_ONLY
                    | IResourceFilterDescription.FOLDERS, new FileInfoMatcherDescription(
                    FILE_FILTER_ID, res), 0, monitor);
        }

        // Let's filter out some content we don't need. To avoid it being
        // indexed
        repoLink.createFilter(IResourceFilterDescription.EXCLUDE_ALL
                | IResourceFilterDescription.FOLDERS | IResourceFilterDescription.INHERITABLE,
                new FileInfoMatcherDescription(FILE_FILTER_ID, "bin"), 0, monitor);
        repoLink.createFilter(IResourceFilterDescription.EXCLUDE_ALL
                | IResourceFilterDescription.FOLDERS, new FileInfoMatcherDescription(
                FILE_FILTER_ID, ".repo"), 0, monitor);
        repoLink.createFilter(IResourceFilterDescription.EXCLUDE_ALL
                | IResourceFilterDescription.FOLDERS | IResourceFilterDescription.INHERITABLE,
                new FileInfoMatcherDescription(FILE_FILTER_ID, ".git"), 0, monitor);
        // repoLink.createFilter(IResourceFilterDescription.EXCLUDE_ALL
        // | IResourceFilterDescription.FOLDERS, new FileInfoMatcherDescription(
        // FILE_FILTER_ID, "out"), 0, monitor);
        final IFolder out = repoLink.getFolder("out");
        // Only allow target/common/R in the out folder
        final int filterFlags = IResourceFilterDescription.INCLUDE_ONLY
                | IResourceFilterDescription.FOLDERS | IResourceFilterDescription.FILES;
        out.createFilter(filterFlags, new FileInfoMatcherDescription(FILE_FILTER_ID, "target"), 0,
                monitor);

        final IFolder target = out.getFolder("target");
        target.createFilter(filterFlags, new FileInfoMatcherDescription(FILE_FILTER_ID, "common"),
                0, monitor);

        final IFolder common = target.getFolder("common");
        common.createFilter(filterFlags, new FileInfoMatcherDescription(FILE_FILTER_ID, "R"), 0,
                monitor);
        repoLink.createLink(repoPath, 0, monitor);

        return repoLink;
    }

    private IClasspathEntry getAndroidDependenceis(IPath repoPath) {
        return JavaCore.newContainerEntry(new Path(
                "it.wallgren.android.platform.classpathContainerInitializer"
                        + repoPath.makeAbsolute()));
    }

    @Override
    public boolean preSelected() {
        return true;
    }
}
TOP

Related Classes of it.wallgren.android.platform.project.AndroidPlatformProject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.