OSDN Git Service

Respect Eclipse classpath when adding files to APK
authorDominic Mitchell <dom@happygiraffe.net>
Thu, 25 Nov 2010 17:58:58 +0000 (17:58 +0000)
committerDominic Mitchell <dom@happygiraffe.net>
Mon, 31 Jan 2011 12:45:17 +0000 (12:45 +0000)
Iterating through the source folder may include files that the user has asked to be ignored.

http://code.google.com/p/android/issues/detail?id=12809

Change-Id: I18915cb8868feffe81499276923fec1415076186

eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java

index 982ca33..4b395ac 100644 (file)
@@ -26,22 +26,24 @@ import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
 import com.android.prefs.AndroidLocation.AndroidLocationException;
 import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
+import com.android.sdklib.SdkConstants;
 import com.android.sdklib.build.ApkBuilder;
+import com.android.sdklib.build.ApkBuilder.JarStatus;
+import com.android.sdklib.build.ApkBuilder.SigningInfo;
 import com.android.sdklib.build.ApkCreationException;
 import com.android.sdklib.build.DuplicateFileException;
 import com.android.sdklib.build.SealedApkException;
-import com.android.sdklib.build.ApkBuilder.JarStatus;
-import com.android.sdklib.build.ApkBuilder.SigningInfo;
 import com.android.sdklib.internal.build.DebugKeyProvider;
-import com.android.sdklib.internal.build.SignedJarBuilder;
 import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException;
+import com.android.sdklib.internal.build.SignedJarBuilder;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -762,10 +764,11 @@ public class BuildHelper {
      * @throws SealedApkException if the APK is already sealed.
      * @throws DuplicateFileException if a file conflicts with another already added to the APK
      *                                   at the same location inside the APK archive.
+     * @throws CoreException
      */
     private void writeStandardProjectResources(ApkBuilder apkBuilder,
             IJavaProject javaProject, IWorkspaceRoot wsRoot, ArrayList<String> list)
-            throws DuplicateFileException, ApkCreationException, SealedApkException {
+            throws DuplicateFileException, ApkCreationException, SealedApkException, CoreException {
         // get the source pathes
         ArrayList<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
 
@@ -773,9 +776,40 @@ public class BuildHelper {
         for (IPath sourcePath : sourceFolders) {
             IResource sourceResource = wsRoot.findMember(sourcePath);
             if (sourceResource != null && sourceResource.getType() == IResource.FOLDER) {
-                // get a File from the IResource
-                apkBuilder.addSourceFolder(sourceResource.getLocation().toFile());
+                writeFolderResources(apkBuilder, javaProject, (IFolder) sourceResource);
+            }
+        }
+    }
+
+    private void writeFolderResources(ApkBuilder apkBuilder, final IJavaProject javaProject,
+            IFolder root) throws CoreException, ApkCreationException,
+            SealedApkException, DuplicateFileException {
+        final List<IPath> pathsToPackage = new ArrayList<IPath>();
+        root.accept(new IResourceProxyVisitor() {
+            public boolean visit(IResourceProxy proxy) throws CoreException {
+                if (proxy.getType() == IResource.FOLDER) {
+                    // If this folder isn't wanted, don't traverse into it.
+                    return ApkBuilder.checkFolderForPackaging(proxy.getName());
+                }
+                // If it's not a folder, it must be a file.  We won't see any other resource type.
+                if (!ApkBuilder.checkFileForPackaging(proxy.getName())) {
+                    return true;
+                }
+                IResource res = proxy.requestResource();
+                if (!javaProject.isOnClasspath(res)) {
+                    return true;
+                }
+                // Just record that we need to package this.  Packaging here throws
+                // inappropriate checked exceptions.
+                IPath location = res.getLocation();
+                pathsToPackage.add(location);
+                return true;
             }
+        }, 0);
+        IPath rootLocation = root.getLocation();
+        for (IPath path : pathsToPackage) {
+            IPath archivePath = path.makeRelativeTo(rootLocation);
+            apkBuilder.addFile(path.toFile(), archivePath.toString());
         }
     }