From 658d10ddc7323f72df373f464307ae692fffd441 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Thu, 25 Feb 2010 15:28:28 -0800 Subject: [PATCH] Add a delta visitor for the library projects. This is used by the precompiler to trigger recompilation of the resource (generates R.java) and by the ApkBuilder to trigger resource packaging. Change-Id: I3a18817a50aa2cdbbd3745a2bba0fda2adbf8556 --- .../ide/eclipse/adt/internal/build/ApkBuilder.java | 19 ++++++ .../adt/internal/build/ApkDeltaVisitor.java | 22 +++---- .../eclipse/adt/internal/build/BaseBuilder.java | 2 +- .../adt/internal/build/LibraryDeltaVisitor.java | 68 ++++++++++++++++++++++ .../adt/internal/build/PreCompilerBuilder.java | 19 ++++++ .../internal/build/PreCompilerDeltaVisitor.java | 3 +- .../eclipse/adt/internal/project/ProjectState.java | 2 +- 7 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/LibraryDeltaVisitor.java diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java index fcefbb9bc..6ecde3721 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java @@ -337,6 +337,25 @@ public class ApkBuilder extends BaseBuilder { mBuildFinalPackage |= dv.getMakeFinalPackage(); } + // if the main resources didn't change, then we check for the library + // ones (will trigger resource repackaging too) + if (mPackageResources == false && libProjects != null && + libProjects.length > 0) { + for (IProject libProject : libProjects) { + delta = getDelta(libProject); + if (delta != null) { + LibraryDeltaVisitor visitor = new LibraryDeltaVisitor(); + delta.accept(visitor); + + mPackageResources = visitor.getResChange(); + + if (mPackageResources) { + break; + } + } + } + } + // also go through the delta for all the referenced projects, until we are forced to // compile anyway for (int i = 0 ; i < referencedJavaProjects.length && diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java index 2cebd91a7..cdc803eb8 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java @@ -63,7 +63,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor * apk file. */ private boolean mPackageResources = false; - + /** * Final package flag. This is set to true if one of the changed/added/removed * file is a non java file (or aidl) in the resource folder. Upon visiting all the @@ -94,11 +94,11 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor IFolder outputfolder) { super(builder); mSourceFolders = sourceFolders; - + if (outputfolder != null) { mOutputPath = outputfolder.getFullPath(); } - + IResource assetFolder = builder.getProject().findMember(SdkConstants.FD_ASSETS); if (assetFolder != null) { mAssetPath = assetFolder.getFullPath(); @@ -108,7 +108,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor if (resFolder != null) { mResPath = resFolder.getFullPath(); } - + IResource libFolder = builder.getProject().findMember(SdkConstants.FD_NATIVE_LIBS); if (libFolder != null) { mLibFolder = libFolder.getFullPath(); @@ -122,14 +122,14 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor public boolean getPackageResources() { return mPackageResources; } - + public boolean getMakeFinalPackage() { return mMakeFinalPackage; } /** * {@inheritDoc} - * @throws CoreException + * @throws CoreException * * @see org.eclipse.core.resources.IResourceDeltaVisitor * #visit(org.eclipse.core.resources.IResourceDelta) @@ -142,7 +142,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor // we are only going to look for changes in res/, src/ and in // AndroidManifest.xml since the delta visitor goes through the main - // folder before its childre we can check when the path segment + // folder before its children we can check when the path segment // count is 2 (format will be /$Project/folder) and make sure we are // processing res/, src/ or AndroidManifest.xml IResource resource = delta.getResource(); @@ -168,7 +168,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor // any for this resource anyway. return false; } - + // check the other folders. if (mOutputPath != null && mOutputPath.isPrefixOf(path)) { // a resource changed inside the output folder. @@ -179,7 +179,7 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor if (AndroidConstants.EXT_CLASS.equalsIgnoreCase(ext)) { mConvertToDex = true; mMakeFinalPackage = true; - + // no need to check the children, as we are in a package // and there can only be subpackage children containing // only .class files @@ -267,12 +267,12 @@ public class ApkDeltaVisitor extends BaseDeltaVisitor return false; } - + } } } } - + // if the folder is not inside one of the folders we are interested in (res, assets, output, // source folders), it could be a folder leading to them, so we return true. return true; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java index fde293b59..7bf000f16 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java @@ -183,7 +183,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { } /** - * Finds a matching Source folder for the current path. This checkds if the current path + * Finds a matching Source folder for the current path. This checks if the current path * leads to, or is a source folder. * @param sourceFolders The list of source folders * @param pathSegments The segments of the current path diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/LibraryDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/LibraryDeltaVisitor.java new file mode 100644 index 000000000..a24eff01c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/LibraryDeltaVisitor.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.eclipse.adt.internal.build; + +import com.android.sdklib.SdkConstants; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * Delta visitor specifically for Library resources. + * The goal is to detect library resource change when compiling the main project + * and trigger a resource recompilation/repackaging. + * + */ +public class LibraryDeltaVisitor implements IResourceDeltaVisitor { + + private boolean mResChange = false; + + public boolean getResChange() { + return mResChange; + } + + public boolean visit(IResourceDelta delta) throws CoreException { + // we are only going to look for changes in res/ + // Since the delta visitor goes through the main + // folder before its children we can check when the path segment + // count is 2 (format will be /$Project/folder) and make sure we are + // processing res/ + + IResource resource = delta.getResource(); + IPath path = resource.getFullPath(); + String[] segments = path.segments(); + + // since the delta visitor also visits the root we return true if + // segments.length = 1 + if (segments.length == 1) { + // this is always the Android project since we call + // Builder#getDelta(IProject) on the project itself. + return true; + } else if (segments.length == 2) { + if (SdkConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) { + // res folder was changed! + // This is all that matters, we can stop (return false below) + mResChange = true; + } + } + + return false; + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java index 5ec1abda2..076434687 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java @@ -279,6 +279,25 @@ public class PreCompilerBuilder extends BaseBuilder { // get the java package from the visitor javaPackage = dv.getManifestPackage(); minSdkVersion = dv.getMinSdkVersion(); + + // if the main resources didn't change, then we check for the library + // ones (will trigger resource recompilation too) + if (mMustCompileResources == false && libProjects != null && + libProjects.length > 0) { + for (IProject libProject : libProjects) { + delta = getDelta(libProject); + if (delta != null) { + LibraryDeltaVisitor visitor = new LibraryDeltaVisitor(); + delta.accept(visitor); + + mMustCompileResources = visitor.getResChange(); + + if (mMustCompileResources) { + break; + } + } + } + } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java index f09bace77..7d37f9ac7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java @@ -195,7 +195,8 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements // since the delta visitor also visits the root we return true if // segments.length = 1 if (segments.length == 1) { - // FIXME: check this is an Android project. + // this is always the Android project since we call + // Builder#getDelta(IProject) on the project itself. return true; } else if (segments.length == 2) { // if we are at an item directly under the root directory, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectState.java index 76df63ee5..3bff813d7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectState.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectState.java @@ -132,7 +132,7 @@ public final class ProjectState { /** * Reloads the content of the properties. *

This also reset the reference to the target as it may have changed. - *

This should be follow by a call to {@link Sdk#loadTarget(ProjectState)}. + *

This should be followed by a call to {@link Sdk#loadTarget(ProjectState)}. */ public void reloadProperties() { mTarget = null; -- 2.11.0