155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/*
255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Licensed under the Eclipse Public License, Version 1.0 (the "License");
555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * you may not use this file except in compliance with the License.
655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * You may obtain a copy of the License at
755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *      http://www.eclipse.org/org/documents/epl-v10.php
955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project *
1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * See the License for the specific language governing permissions and
1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * limitations under the License.
1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1759f8d5012426884e40b77b02a7c3274eb66019a1Xavier Ducrohetpackage com.android.ide.eclipse.adt.internal.build.builders;
1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1981cefe2a26dd6db8a878e30874d12cdcbff0e83bXavier Ducrohetimport com.android.SdkConstants;
20c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohetimport com.android.ide.eclipse.adt.AdtConstants;
21731561089a529425432ccd0540b1f80492949b95Xavier Ducrohetimport com.android.ide.eclipse.adt.AdtPlugin;
2259f8d5012426884e40b77b02a7c3274eb66019a1Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.build.Messages;
23b26699c2e42ff60ce56a07e2550e42223c5cc361Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
24b26699c2e42ff60ce56a07e2550e42223c5cc361Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
25f2880494706ad8dfd43e21471096216be4ca7c69Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
2699b9ad2143e5e9e626879309ecc6f883403bdcaeXavier Ducrohetimport com.android.ide.eclipse.adt.internal.project.ProjectHelper;
27f2880494706ad8dfd43e21471096216be4ca7c69Xavier Ducrohetimport com.android.ide.eclipse.adt.internal.sdk.Sdk;
2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport com.android.sdklib.IAndroidTarget;
2985e4a1a9dd133abb879ec211ce8dd385004edf22Xavier Ducrohetimport com.android.utils.Pair;
3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.resources.IFolder;
3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.resources.IMarker;
3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.resources.IProject;
3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.resources.IResource;
3567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.core.resources.IWorkspaceRoot;
364b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohetimport org.eclipse.core.resources.IncrementalProjectBuilder;
3767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.core.resources.ResourcesPlugin;
3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.runtime.CoreException;
3967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.core.runtime.IPath;
4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.core.runtime.IProgressMonitor;
41282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohetimport org.eclipse.core.runtime.IStatus;
42282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohetimport org.eclipse.core.runtime.Status;
4367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.core.runtime.SubProgressMonitor;
44282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohetimport org.eclipse.core.runtime.jobs.Job;
4567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.jdt.core.IClasspathEntry;
4667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.jdt.core.IJavaProject;
4767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Projectimport org.eclipse.jdt.core.JavaCore;
4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
49dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohetimport java.util.List;
5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport java.util.Map;
5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/**
5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Resource manager builder whose only purpose is to refresh the resource folder
5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * so that the other builder use an up to date version.
5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */
5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpublic class ResourceManagerBuilder extends BaseBuilder {
5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public static final String ID = "com.android.ide.eclipse.adt.ResourceManagerBuilder"; //$NON-NLS-1$
5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    public ResourceManagerBuilder() {
6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        super();
6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
649a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet    @Override
659a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet    protected void clean(IProgressMonitor monitor) throws CoreException {
669a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet        super.clean(monitor);
679a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet
689a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet        // Get the project.
699a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet        IProject project = getProject();
709a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet
719a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet        // Clear the project of the generic markers
72c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet        removeMarkersFromContainer(project, AdtConstants.MARKER_ADT);
739a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet    }
749a68767a27170689fd647276cb0b082d192448fdXavier Ducrohet
7555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    // build() returns a list of project from which this project depends for future compilation.
760cae8d05fb387d895254779475fe15d39fe322abRicky Ng-Adam    @SuppressWarnings("unchecked")
7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    @Override
7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
7955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            throws CoreException {
8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // Get the project.
81282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet        final IProject project = getProject();
829e2ff90642669592f832d9f1cb56cc6871d5aaabXavier Ducrohet        IJavaProject javaProject = JavaCore.create(project);
8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // Clear the project of the generic markers
85c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet        removeMarkersFromContainer(project, AdtConstants.MARKER_ADT);
862fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
8767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        // check for existing target marker, in which case we abort.
8867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        // (this means: no SDK, no target, or unresolvable target.)
89dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet        try {
90dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            abortOnBadSetup(javaProject);
91dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet        } catch (AbortBuildException e) {
92dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            return null;
93dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet        }
9455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
9555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // Check the compiler compliance level, displaying the error message
9655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // since this is the first builder.
97a191f888e588227df57868114b3a127b955bf76cRaphael Moll        Pair<Integer, String> result = ProjectHelper.checkCompilerCompliance(project);
9855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        String errorMessage = null;
99a191f888e588227df57868114b3a127b955bf76cRaphael Moll        switch (result.getFirst().intValue()) {
10055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            case ProjectHelper.COMPILER_COMPLIANCE_LEVEL:
101a191f888e588227df57868114b3a127b955bf76cRaphael Moll                errorMessage = Messages.Requires_Compiler_Compliance_s;
1023bd45f0b16f5ebfafd8080a0f17f71d85c9840edXavier Ducrohet                break;
10355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            case ProjectHelper.COMPILER_COMPLIANCE_SOURCE:
104a191f888e588227df57868114b3a127b955bf76cRaphael Moll                errorMessage = Messages.Requires_Source_Compatibility_s;
1053bd45f0b16f5ebfafd8080a0f17f71d85c9840edXavier Ducrohet                break;
10655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            case ProjectHelper.COMPILER_COMPLIANCE_CODEGEN_TARGET:
107a191f888e588227df57868114b3a127b955bf76cRaphael Moll                errorMessage = Messages.Requires_Class_Compatibility_s;
1083bd45f0b16f5ebfafd8080a0f17f71d85c9840edXavier Ducrohet                break;
10955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
11055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
11155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (errorMessage != null) {
112a191f888e588227df57868114b3a127b955bf76cRaphael Moll            errorMessage = String.format(errorMessage,
113a191f888e588227df57868114b3a127b955bf76cRaphael Moll                    result.getSecond() == null ? "(no value)" : result.getSecond());
114a191f888e588227df57868114b3a127b955bf76cRaphael Moll
115c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet            markProject(AdtConstants.MARKER_ADT, errorMessage, IMarker.SEVERITY_ERROR);
11655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            AdtPlugin.printErrorToConsole(project, errorMessage);
1172fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
118dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            return null;
11955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
12055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
12155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // Check that the SDK directory has been setup.
12255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        String osSdkFolder = AdtPlugin.getOsSdkFolder();
12355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
12455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (osSdkFolder == null || osSdkFolder.length() == 0) {
12567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            AdtPlugin.printErrorToConsole(project, Messages.No_SDK_Setup_Error);
126c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet            markProject(AdtConstants.MARKER_ADT, Messages.No_SDK_Setup_Error,
12755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    IMarker.SEVERITY_ERROR);
12855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
129dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            return null;
13055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
13155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
13255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // check the project has a target
13355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
13455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (projectTarget == null) {
13555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // no target. marker has been set by the container initializer: exit silently.
136dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            return null;
13755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
1382fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
13967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        // check the 'gen' source folder is present
14067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        boolean hasGenSrcFolder = false; // whether the project has a 'gen' source folder setup
1412fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
14267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
14367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        if (classpaths != null) {
14467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            for (IClasspathEntry e : classpaths) {
14567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
14667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                    IPath path = e.getPath();
14767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                    if (path.segmentCount() == 2 &&
14867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                            path.segment(1).equals(SdkConstants.FD_GEN_SOURCES)) {
14967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        hasGenSrcFolder = true;
15067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        break;
15167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                    }
15267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                }
15367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            }
15467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        }
15567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project
15667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        boolean genFolderPresent = false; // whether the gen folder actually exists
15767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        IResource resource = project.findMember(SdkConstants.FD_GEN_SOURCES);
15867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        genFolderPresent = resource != null && resource.exists();
1592fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
16067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        if (hasGenSrcFolder == false && genFolderPresent) {
16167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // No source folder setup for 'gen' in the project, but there's already a
16267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // 'gen' resource (file or folder).
16367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            String message;
16467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            if (resource.getType() == IResource.FOLDER) {
16567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                // folder exists already! This is an error. If the folder had been created
16667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                // by the NewProjectWizard, it'd be a source folder.
16767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                message = String.format("%1$s already exists but is not a source folder. Convert to a source folder or rename it.",
16867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        resource.getFullPath().toString());
16967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            } else {
17067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                // resource exists but is not a folder.
17167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                message = String.format(
17267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        "Resource %1$s is in the way. ADT needs a source folder called 'gen' to work. Rename or delete resource.",
17367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        resource.getFullPath().toString());
17467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            }
17567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project
17667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            AdtPlugin.printErrorToConsole(project, message);
177c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet            markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
17867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project
179dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            return null;
18067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        } else if (hasGenSrcFolder == false || genFolderPresent == false) {
18167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // either there is no 'gen' source folder in the project (older SDK),
18267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // or the folder does not exist (was deleted, or was a fresh svn checkout maybe.)
18367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project
18467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // In case we are migrating from an older SDK, we go through the current source
18567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // folders and delete the generated Java files.
186dec739da5551ddf52a8f3cff06c63de4aced2578Xavier Ducrohet            List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
18767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
18867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            for (IPath path : sourceFolders) {
18967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                IResource member = root.findMember(path);
19067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                if (member != null) {
19167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                    removeDerivedResources(member, monitor);
19267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                }
19367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            }
19467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project
19567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // create the new source folder, if needed
19667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            IFolder genFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
19767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            if (genFolderPresent == false) {
198b26699c2e42ff60ce56a07e2550e42223c5cc361Xavier Ducrohet                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
19967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        "Creating 'gen' source folder for generated Java files");
20067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                genFolder.create(true /* force */, true /* local */,
20167dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        new SubProgressMonitor(monitor, 10));
20267dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            }
2032fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
20467dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            // add it to the source folder list, if needed only (or it will throw)
20567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            if (hasGenSrcFolder == false) {
20667dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                IClasspathEntry[] entries = javaProject.getRawClasspath();
20767dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                entries = ProjectHelper.addEntryToClasspath(entries,
20867dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                        JavaCore.newSourceEntry(genFolder.getFullPath()));
20967dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project                javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10));
21067dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            }
2112fb27a8d7f3c4636c775377cd09fa6b00c077440Xavier Ducrohet
212648e03eafbf9cac55142d1d6349e4d5cc8b4299dXavier Ducrohet            // refresh specifically the gen folder first, as it may break the build
21396ab96b1964cd20588834a8d81e74db7b3f3a5d8Raphael            // if it doesn't arrive in time then refresh the whole project as usual.
21496ab96b1964cd20588834a8d81e74db7b3f3a5d8Raphael            genFolder.refreshLocal(IResource.DEPTH_ZERO, new SubProgressMonitor(monitor, 10));
21567dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project            project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 10));
216282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet
217282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // it seems like doing this fails to properly rebuild the project. the Java builder
218282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // running right after this builder will not see the gen folder, and will not be
219282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // restarted after this build. Therefore in this particular case, we start another
220282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // build asynchronously so that it's rebuilt after this build.
221282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            launchJob(new Job("rebuild") {
222282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                @Override
223282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                protected IStatus run(IProgressMonitor m) {
224282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    try {
225282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, m);
226282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        return Status.OK_STATUS;
227282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    } catch (CoreException e) {
228282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        return e.getStatus();
229282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    }
230282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                }
231282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            });
232282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet
23367dc23a61d888ba1b39fe6ed23d9f4d1a3df80eeThe Android Open Source Project        }
23455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
2354b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        // convert older projects which use bin as the eclipse output folder into projects
2364b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        // using bin/classes
2378fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet        IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(project);
2384b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(project);
2394b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        if (androidOutput.exists() == false || javaOutput == null ||
2404b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet                javaOutput.getParent().equals(androidOutput) == false) {
2414b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            // get what we want as the new java output.
2424b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            IFolder newJavaOutput = androidOutput.getFolder(SdkConstants.FD_CLASSES_OUTPUT);
2434b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet
2444b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            if (androidOutput.exists() == false) {
2454b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet                androidOutput.create(true /*force*/, true /*local*/, monitor);
2464b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            }
2474b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet
2484b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            if (newJavaOutput.exists() == false) {
2494b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet                newJavaOutput.create(true /*force*/, true /*local*/, monitor);
2504b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            }
2514b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet
2524b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            // set the java output to this project.
2534b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet            javaProject.setOutputLocation(newJavaOutput.getFullPath(), monitor);
2544b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet
255282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // need to do a full build. Can't build while we're already building, so launch a
256282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            // job to build it right after this build
257282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            launchJob(new Job("rebuild") {
258282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                @Override
259282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                protected IStatus run(IProgressMonitor jobMonitor) {
260282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    try {
261282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        project.build(IncrementalProjectBuilder.CLEAN_BUILD, jobMonitor);
262282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        return Status.OK_STATUS;
263282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    } catch (CoreException e) {
264282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                        return e.getStatus();
265282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                    }
266282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet                }
267282120bcc8fdabb43de8a2add39d3750430ed1dfXavier Ducrohet            });
2684b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        }
2694b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet
2704b85f4ea69e9f7098abcae6e813cb85824c0de58Xavier Ducrohet        // check that we have bin/res/
2718fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet        IFolder binResFolder = androidOutput.getFolder(SdkConstants.FD_RESOURCES);
2728fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet        if (binResFolder.exists() == false) {
2738fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet            binResFolder.create(true /* force */, true /* local */,
2748fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet                    new SubProgressMonitor(monitor, 10));
2758fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet            project.refreshLocal(IResource.DEPTH_ONE, new SubProgressMonitor(monitor, 10));
2768fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet        }
2778fa568349cdfcf075f1f6ca98f33579f209b3326Xavier Ducrohet
27855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // Check the preference to be sure we are supposed to refresh
27955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        // the folders.
280b26699c2e42ff60ce56a07e2550e42223c5cc361Xavier Ducrohet        if (AdtPrefs.getPrefs().getBuildForceResResfresh()) {
281b26699c2e42ff60ce56a07e2550e42223c5cc361Xavier Ducrohet            AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, Messages.Refreshing_Res);
28255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
28355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // refresh the res folder.
284c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet            IFolder resFolder = project.getFolder(AdtConstants.WS_RESOURCES);
28555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            resFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
28655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
28755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // Also refresh the assets folder to make sure the ApkBuilder
28855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            // will now it's changed and will force a new resource packaging.
289c3105b949cd2a0f6cbf8a12ec4f30e49b5b5a502Xavier Ducrohet            IFolder assetsFolder = project.getFolder(AdtConstants.WS_ASSETS);
29055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            assetsFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
29155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
29255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
29355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        return null;
29455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
29555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project}
296