aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/icons/view.pngbin394 -> 0 bytes
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml51
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java8
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java20
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java43
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java3
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java11
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java35
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java73
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseClasspathContainerInitializer.java111
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java243
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java45
14 files changed, 500 insertions, 163 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png
deleted file mode 100644
index 35c4d8f..0000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/icons/view.png
+++ /dev/null
Binary files differ
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
index 0cd0354..e5e8229 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -57,6 +57,35 @@
<super type="org.eclipse.core.resources.textmarker" />
<persistent value="true" />
</extension>
+ <extension
+ id="com.android.ide.eclipse.adt.adtProblem"
+ name="Android ADT Problem"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.core.resources.problemmarker" />
+ <super type="org.eclipse.core.resources.textmarker" />
+ <persistent value="true" />
+ </extension>
+ <extension
+ id="com.android.ide.eclipse.adt.targetProblem"
+ name="Android Target Problem"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.core.resources.problemmarker" />
+ <persistent value="false" />
+ </extension>
+ <extension
+ id="com.android.ide.eclipse.adt.dependencyProblem"
+ name="Android Dependency Problem"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.core.resources.problemmarker" />
+ <persistent value="false" />
+ </extension>
+ <extension
+ id="com.android.ide.eclipse.adt.packagingProblem"
+ name="Android Packaging Problem"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.core.resources.problemmarker" />
+ <persistent value="true" />
+ </extension>
<extension point="org.eclipse.ui.ide.markerResolution">
<markerResolutionGenerator
markerType="com.android.ide.eclipse.adt.lintProblem"
@@ -385,28 +414,6 @@
<extension point="org.eclipse.core.runtime.preferences">
<initializer class="com.android.ide.eclipse.adt.internal.preferences.AdtPrefs" />
</extension>
- <extension
- id="com.android.ide.eclipse.adt.adtProblem"
- name="Android ADT Problem"
- point="org.eclipse.core.resources.markers">
- <super type="org.eclipse.core.resources.problemmarker" />
- <super type="org.eclipse.core.resources.textmarker" />
- <persistent value="true" />
- </extension>
- <extension
- id="com.android.ide.eclipse.adt.targetProblem"
- name="Android Target Problem"
- point="org.eclipse.core.resources.markers">
- <super type="org.eclipse.core.resources.problemmarker" />
- <persistent value="false" />
- </extension>
- <extension
- id="com.android.ide.eclipse.adt.packagingProblem"
- name="Android Packaging Problem"
- point="org.eclipse.core.resources.markers">
- <super type="org.eclipse.core.resources.problemmarker" />
- <persistent value="true" />
- </extension>
<extension point="org.eclipse.ui.perspectiveExtensions">
<perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
<newWizardShortcut id="com.android.ide.eclipse.adt.project.NewProjectWizard" />
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
index 796252b..0c7ed9f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/common/layout/grid/GridDropHandler.java
@@ -680,7 +680,8 @@ public class GridDropHandler {
// Ensure that we don't store columnCount=0
if (mGrid.actualColumnCount == 0) {
- mGrid.layout.setAttribute(ANDROID_URI, ATTR_COLUMN_COUNT, VALUE_1);
+ mGrid.layout.setAttribute(ANDROID_URI, ATTR_COLUMN_COUNT,
+ Integer.toString(Math.max(1, column + 1)));
}
return newChild;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
index 0a1f2bb..0b619fb 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
@@ -214,10 +214,16 @@ public class AdtConstants {
public final static String MARKER_ADT = AdtPlugin.PLUGIN_ID + ".adtProblem"; //$NON-NLS-1$
/** Marker for Android Target errors.
- * This is not cleared on each like other markers. Instead, it's cleared
+ * This is not cleared on each build like other markers. Instead, it's cleared
* when an AndroidClasspathContainerInitializer has succeeded in creating an
* AndroidClasspathContainer */
public final static String MARKER_TARGET = AdtPlugin.PLUGIN_ID + ".targetProblem"; //$NON-NLS-1$
+ /** Marker for Android Dependency errors.
+ * This is not cleared on each build like other markers. Instead, it's cleared
+ * when a LibraryClasspathContainerInitializer has succeeded in creating a
+ * LibraryClasspathContainer */
+ public final static String MARKER_DEPENDENCY = AdtPlugin.PLUGIN_ID + ".dependencyProblem"; //$NON-NLS-1$
+
/** aapt marker error when running the compile command, only to be used
* in {@link PreCompilerBuilder} */
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
index 7536c2f..e915544 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
@@ -19,7 +19,6 @@ package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AndroidPrintStream;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
@@ -747,6 +746,12 @@ public class BuildHelper {
mOutStream.setPrefix(CONSOLE_PREFIX_DX);
mErrStream.setPrefix(CONSOLE_PREFIX_DX);
+ if (mVerbose) {
+ for (String input : inputPaths) {
+ mOutStream.println("Input: " + input);
+ }
+ }
+
int res = wrapper.run(osOutFilePath,
inputPaths,
mVerbose,
@@ -794,9 +799,11 @@ public class BuildHelper {
String configFilter, int versionCode) throws AaptExecException, AaptResultException {
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
+ @SuppressWarnings("deprecation") String aapt = target.getPath(IAndroidTarget.AAPT);
+
// Create the command line.
ArrayList<String> commandArray = new ArrayList<String>();
- commandArray.add(target.getPath(IAndroidTarget.AAPT));
+ commandArray.add(aapt);
commandArray.add(aaptCommand);
if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
commandArray.add("-v"); //$NON-NLS-1$
@@ -1061,8 +1068,13 @@ public class BuildHelper {
IPath path = e.getPath();
IResource resource = wsRoot.findMember(path);
- // case of a jar file (which could be relative to the workspace or a full path)
- if (AdtConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
+
+ if (resource != null && resource.getType() == IResource.PROJECT) {
+ // if it's a project we should just ignore it because it's going to be added
+ // later when we add all the referenced projects.
+
+ } else if (AdtConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
+ // case of a jar file (which could be relative to the workspace or a full path)
if (resource != null && resource.exists() &&
resource.getType() == IResource.FILE) {
oslibraryList.add(resource.getLocation().toOSString());
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
index d65dedf..6c4eca4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
@@ -445,11 +445,9 @@ public class PostCompilerBuilder extends BaseBuilder {
IFolder javaOutputFolder = BaseProjectHelper.getJavaOutputFolder(project);
- writeLibraryPackage(jarIFile, project, appPackage, javaOutputFolder,
- referencedJavaProjects);
+ writeLibraryPackage(jarIFile, project, appPackage, javaOutputFolder);
saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex = false);
-
// refresh the bin folder content with no recursion to update the library
// jar file.
androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
@@ -815,13 +813,11 @@ public class PostCompilerBuilder extends BaseBuilder {
rootFolder.getFullPath());
String name = file.getName();
- // we don't package any R[$*] classes whatever the package (because we generate
- // more than one if there are library dependencies). Also ignore Manifest and
- // BuildConfig classes that are in the app package.
- if (R_PATTERN.matcher(name).matches() ||
- (mAppPackage.equals(packageApp.toString()) &&
+ // Ignore the library's R/Manifest/BuildConfig classes.
+ if (mAppPackage.equals(packageApp.toString()) &&
(BUILD_CONFIG_CLASS.equals(name) ||
- MANIFEST_PATTERN.matcher(name).matches()))) {
+ MANIFEST_PATTERN.matcher(name).matches() ||
+ R_PATTERN.matcher(name).matches())) {
return;
}
@@ -900,8 +896,15 @@ public class PostCompilerBuilder extends BaseBuilder {
return true;
}
+ /**
+ * Writes the library jar file.
+ * @param jarIFile the destination file
+ * @param project the library project
+ * @param appPackage the library android package
+ * @param javaOutputFolder the JDT output folder.
+ */
private void writeLibraryPackage(IFile jarIFile, IProject project, String appPackage,
- IFolder javaOutputFolder, List<IJavaProject> referencedJavaProjects) {
+ IFolder javaOutputFolder) {
JarOutputStream jos = null;
try {
@@ -920,26 +923,6 @@ public class PostCompilerBuilder extends BaseBuilder {
// now write the standard Java resources
BuildHelper.writeResources(jarBuilder, JavaCore.create(project));
- // do the same for all the referencedJava project
- for (IJavaProject javaProject : referencedJavaProjects) {
- // in case an Android project was referenced (which won't work), the
- // best thing is to ignore this project.
- if (javaProject.getProject().hasNature(AdtConstants.NATURE_DEFAULT)) {
- continue;
- }
-
- IFolder refProjectOutput = BaseProjectHelper.getJavaOutputFolder(
- javaProject.getProject());
-
- if (refProjectOutput != null) {
- // write the class files
- writeClassFilesIntoJar(jarBuilder, refProjectOutput, refProjectOutput);
-
- // now write the standard Java resources
- BuildHelper.writeResources(jarBuilder, javaProject);
- }
- }
-
saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
} catch (Exception e) {
AdtPlugin.log(e, "Failed to write jar file %s", jarIFile.getLocation().toOSString());
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
index 7713f47..8234f25 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
@@ -805,7 +805,8 @@ public class PreCompilerBuilder extends BaseBuilder {
array.add("--auto-add-overlay"); //$NON-NLS-1$
}
- if (libraryPackages != null) {
+ // there's no need to generate the R class of the libraries if this is a library too.
+ if (isLibrary == false && libraryPackages != null) {
array.add("--extra-packages"); //$NON-NLS-1$
array.add(libraryPackages);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
index f57d904..6915052 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.adt.internal.editors.layout;
+import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_HEIGHT;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_WIDTH;
import static com.android.ide.common.layout.LayoutConstants.ATTR_PADDING;
@@ -24,6 +25,7 @@ import static com.android.ide.common.layout.LayoutConstants.VALUE_MATCH_PARENT;
import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.ATTR_LAYOUT;
import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_FRAGMENT;
import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_INCLUDE;
+import static com.android.tools.lint.detector.api.LintConstants.AUTO_URI;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.ViewInfo;
@@ -366,6 +368,15 @@ public class UiElementPullParser extends BasePullParser {
}
Node attribute = xmlNode.getAttributes().getNamedItemNS(namespace, localName);
+
+ // Auto-convert http://schemas.android.com/apk/res-auto resources. The lookup
+ // will be for the current application's resource package, e.g.
+ // http://schemas.android.com/apk/res/foo.bar, but the XML document will
+ // be using http://schemas.android.com/apk/res-auto in library projects:
+ if (attribute == null && namespace != null && !namespace.equals(ANDROID_URI)) {
+ attribute = xmlNode.getAttributes().getNamedItemNS(AUTO_URI, localName);
+ }
+
if (attribute != null) {
String value = attribute.getNodeValue();
if (mIncreaseExistingPadding && ATTR_PADDING.equals(localName) &&
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
index ef1a17c..485d574 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/OutlinePage.java
@@ -17,6 +17,7 @@
package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
import static com.android.ide.common.layout.LayoutConstants.ANDROID_URI;
+import static com.android.ide.common.layout.LayoutConstants.ATTR_CLASS;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_COLUMN;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_COLUMN_SPAN;
import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ROW;
@@ -28,6 +29,7 @@ import static com.android.ide.common.layout.LayoutConstants.DRAWABLE_PREFIX;
import static com.android.ide.common.layout.LayoutConstants.LAYOUT_PREFIX;
import static com.android.ide.common.layout.LayoutConstants.LINEAR_LAYOUT;
import static com.android.ide.common.layout.LayoutConstants.VALUE_VERTICAL;
+import static com.android.ide.eclipse.adt.internal.editors.layout.descriptors.LayoutDescriptors.VIEW_VIEWTAG;
import static org.eclipse.jface.viewers.StyledString.QUALIFIER_STYLER;
import com.android.annotations.VisibleForTesting;
@@ -496,13 +498,26 @@ public class OutlinePage extends ContentOutlinePage
Image img = null;
// Special case for the common case of vertical linear layouts:
// show vertical linear icon (the default icon shows horizontal orientation)
- if (desc.getUiName().equals(LINEAR_LAYOUT)) {
+ String uiName = desc.getUiName();
+ if (uiName.equals(LINEAR_LAYOUT)) {
Element e = (Element) node.getXmlNode();
if (VALUE_VERTICAL.equals(e.getAttributeNS(ANDROID_URI,
ATTR_ORIENTATION))) {
IconFactory factory = IconFactory.getInstance();
img = factory.getIcon("VerticalLinearLayout"); //$NON-NLS-1$
}
+ } else if (uiName.equals(VIEW_VIEWTAG)) {
+ Node xmlNode = node.getXmlNode();
+ if (xmlNode instanceof Element) {
+ String className = ((Element) xmlNode).getAttribute(ATTR_CLASS);
+ if (className != null && className.length() > 0) {
+ int index = className.lastIndexOf('.');
+ if (index != -1) {
+ className = className.substring(index + 1);
+ }
+ img = IconFactory.getInstance().getIcon(className);
+ }
+ }
}
if (img == null) {
img = desc.getGenericIcon();
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
index a8ebe75..8f34b48 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
@@ -35,7 +35,6 @@ import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.sdklib.xml.AndroidXPathFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
@@ -57,10 +56,6 @@ import org.w3c.dom.Node;
import java.util.Collection;
import java.util.List;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
/**
* Multi-page form editor for AndroidManifest.xml.
*/
@@ -189,18 +184,24 @@ public final class ManifestEditor extends AndroidXmlEditor {
private Node getManifestXmlNode(Document xmlDoc) {
if (xmlDoc != null) {
- ElementDescriptor manifest_desc = mUiManifestNode.getDescriptor();
- try {
- XPath xpath = AndroidXPathFactory.newXPath();
- Node node = (Node) xpath.evaluate("/" + manifest_desc.getXmlName(), //$NON-NLS-1$
- xmlDoc,
- XPathConstants.NODE);
- assert node != null && node.getNodeName().equals(manifest_desc.getXmlName());
-
- return node;
- } catch (XPathExpressionException e) {
- AdtPlugin.log(e, "XPath error when trying to find '%s' element in XML.", //$NON-NLS-1$
- manifest_desc.getXmlName());
+ ElementDescriptor manifestDesc = mUiManifestNode.getDescriptor();
+ String manifestXmlName = manifestDesc == null ? null : manifestDesc.getXmlName();
+ assert manifestXmlName != null;
+
+ if (manifestXmlName != null) {
+ Node node = xmlDoc.getDocumentElement();
+ if (node != null && manifestXmlName.equals(node.getNodeName())) {
+ return node;
+ }
+
+ for (node = xmlDoc.getFirstChild();
+ node != null;
+ node = node.getNextSibling()) {
+ if (node.getNodeType() == Node.ELEMENT_NODE &&
+ manifestXmlName.equals(node.getNodeName())) {
+ return node;
+ }
+ }
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
index b2be4a1..c2493e3 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
@@ -26,22 +26,15 @@ import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
import com.android.sdklib.SdkConstants;
-import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
@@ -66,7 +59,7 @@ import java.util.regex.Pattern;
* Classpath container initializer responsible for binding {@link AndroidClasspathContainer} to
* {@link IProject}s. This removes the hard-coded path to the android.jar.
*/
-public class AndroidClasspathContainerInitializer extends ClasspathContainerInitializer {
+public class AndroidClasspathContainerInitializer extends BaseClasspathContainerInitializer {
public static final String NULL_API_URL = "<null>"; //$NON-NLS-1$
@@ -276,69 +269,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
};
}
} finally {
- if (markerMessage != null) {
- // log the error and put the marker on the project if we can.
- if (outputToConsole) {
- AdtPlugin.printErrorToConsole(iProject, markerMessage);
- }
-
- try {
- BaseProjectHelper.markProject(iProject, AdtConstants.MARKER_TARGET,
- markerMessage, IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH);
- } catch (CoreException e) {
- // In some cases, the workspace may be locked for modification when we
- // pass here.
- // We schedule a new job to put the marker after.
- final String fmessage = markerMessage;
- Job markerJob = new Job("Android SDK: Resolving error markers") {
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- try {
- BaseProjectHelper.markProject(iProject,
- AdtConstants.MARKER_TARGET,
- fmessage, IMarker.SEVERITY_ERROR,
- IMarker.PRIORITY_HIGH);
- } catch (CoreException e2) {
- return e2.getStatus();
- }
-
- return Status.OK_STATUS;
- }
- };
-
- // build jobs are run after other interactive jobs
- markerJob.setPriority(Job.BUILD);
- markerJob.schedule();
- }
- } else {
- // no error, remove potential MARKER_TARGETs.
- try {
- if (iProject.exists()) {
- iProject.deleteMarkers(AdtConstants.MARKER_TARGET, true,
- IResource.DEPTH_INFINITE);
- }
- } catch (CoreException ce) {
- // In some cases, the workspace may be locked for modification when we pass
- // here, so we schedule a new job to put the marker after.
- Job markerJob = new Job("Android SDK: Resolving error markers") {
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- try {
- iProject.deleteMarkers(AdtConstants.MARKER_TARGET, true,
- IResource.DEPTH_INFINITE);
- } catch (CoreException e2) {
- return e2.getStatus();
- }
-
- return Status.OK_STATUS;
- }
- };
-
- // build jobs are run after other interactive jobs
- markerJob.setPriority(Job.BUILD);
- markerJob.schedule();
- }
- }
+ processError(iProject, markerMessage, AdtConstants.MARKER_TARGET, outputToConsole);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseClasspathContainerInitializer.java
new file mode 100644
index 0000000..403b17b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseClasspathContainerInitializer.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 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.project;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+
+/**
+ * Base CPC initializer providing support to all our initializer.
+ *
+ */
+abstract class BaseClasspathContainerInitializer extends ClasspathContainerInitializer {
+
+
+ /**
+ * Adds an error to a project, or remove all markers if error message is null
+ * @param project the project to modify
+ * @param errorMessage the errorMessage or null to remove errors.
+ * @param markerType the marker type to be used.
+ * @param outputToConsole whether to output to the console.
+ */
+ protected static void processError(final IProject project, final String errorMessage,
+ final String markerType, boolean outputToConsole) {
+ if (errorMessage != null) {
+ // log the error and put the marker on the project if we can.
+ if (outputToConsole) {
+ AdtPlugin.printErrorToConsole(project, errorMessage);
+ }
+
+ try {
+ BaseProjectHelper.markProject(project, markerType,
+ errorMessage, IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH);
+ } catch (CoreException e) {
+ // In some cases, the workspace may be locked for modification when we
+ // pass here.
+ // We schedule a new job to put the marker after.
+ final String fmessage = errorMessage;
+ Job markerJob = new Job("Android SDK: Resolving error markers") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ BaseProjectHelper.markProject(project,
+ markerType,
+ fmessage, IMarker.SEVERITY_ERROR,
+ IMarker.PRIORITY_HIGH);
+ } catch (CoreException e2) {
+ return e2.getStatus();
+ }
+
+ return Status.OK_STATUS;
+ }
+ };
+
+ // build jobs are run after other interactive jobs
+ markerJob.setPriority(Job.BUILD);
+ markerJob.schedule();
+ }
+ } else {
+ // no error, remove existing markers.
+ try {
+ if (project.exists()) {
+ project.deleteMarkers(markerType, true,
+ IResource.DEPTH_INFINITE);
+ }
+ } catch (CoreException ce) {
+ // In some cases, the workspace may be locked for modification when we pass
+ // here, so we schedule a new job to put the marker after.
+ Job markerJob = new Job("Android SDK: Resolving error markers") {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ project.deleteMarkers(markerType, true,
+ IResource.DEPTH_INFINITE);
+ } catch (CoreException e2) {
+ return e2.getStatus();
+ }
+
+ return Status.OK_STATUS;
+ }
+ };
+
+ // build jobs are run after other interactive jobs
+ markerJob.setPriority(Job.BUILD);
+ markerJob.schedule();
+ }
+ }
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java
index 7b6c9b7..197d18c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java
@@ -18,20 +18,24 @@ package com.android.ide.eclipse.adt.internal.project;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.AndroidPrintStream;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.SdkConstants;
+import com.android.sdklib.build.JarListSanitizer;
+import com.android.sdklib.build.JarListSanitizer.DifferentLibException;
+import com.android.sdklib.build.JarListSanitizer.Sha1Exception;
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.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
@@ -40,9 +44,11 @@ import org.eclipse.jdt.core.JavaModelException;
import java.io.File;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
-public class LibraryClasspathContainerInitializer extends ClasspathContainerInitializer {
+public class LibraryClasspathContainerInitializer extends BaseClasspathContainerInitializer {
public LibraryClasspathContainerInitializer() {
}
@@ -60,7 +66,7 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
IClasspathContainer[] containers = new IClasspathContainer[projectCount];
for (int i = 0 ; i < projectCount; i++) {
- containers[i] = allocateAndroidContainer(androidProjects[i]);
+ containers[i] = allocateLibraryContainer(androidProjects[i]);
}
// give each project their new container in one call.
@@ -97,7 +103,7 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
@Override
public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
if (AdtConstants.CONTAINER_LIBRARIES.equals(containerPath.toString())) {
- IClasspathContainer container = allocateAndroidContainer(project);
+ IClasspathContainer container = allocateLibraryContainer(project);
if (container != null) {
JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_LIBRARIES),
new IJavaProject[] { project },
@@ -107,7 +113,7 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
}
}
- private static IClasspathContainer allocateAndroidContainer(IJavaProject javaProject) {
+ private static IClasspathContainer allocateLibraryContainer(IJavaProject javaProject) {
final IProject iProject = javaProject.getProject();
AdtPlugin plugin = AdtPlugin.getDefault();
@@ -115,8 +121,8 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
return null;
}
+ // First check that the project has a library-type container.
try {
- // First check that the project has a library-type container.
IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
IClasspathEntry[] oldRawClasspath = rawClasspath;
@@ -138,7 +144,8 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
if (foundLibrariesContainer == false) {
// add the android container to the array
rawClasspath = ProjectHelper.addEntryToClasspath(rawClasspath,
- JavaCore.newContainerEntry(new Path(AdtConstants.CONTAINER_LIBRARIES)));
+ JavaCore.newContainerEntry(new Path(AdtConstants.CONTAINER_LIBRARIES),
+ true /*isExported*/));
}
// set the new list of entries to the project
@@ -154,10 +161,29 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
// check if the project has a valid target.
ProjectState state = Sdk.getProjectState(iProject);
+ /*
+ * At this point we're going to gather a list of all that need to go in the
+ * dependency container.
+ * - Library project outputs (direct and indirect)
+ * - Java project output (those can be indirectly referenced through library projects
+ * or other other Java projects)
+ * - Jar files:
+ * + inside this project's libs/
+ * + inside the library projects' libs/
+ * + inside the referenced Java projects' classpath
+ */
+
List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ // list of java project dependencies and jar files that will be built while
+ // going through the library projects.
+ Set<File> jarFiles = new HashSet<File>();
+ Set<IProject> refProjects = new HashSet<IProject>();
+
+ // process all the libraries
+
List<IProject> libProjects = state.getFullLibraryProjects();
for (IProject libProject : libProjects) {
// get the project output
@@ -179,34 +205,223 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit
}
}
+ // we can directly add a CPE for this jar as there's no risk of a duplicate.
IClasspathEntry entry = JavaCore.newLibraryEntry(
jarIFile.getLocation(),
sourceFolder, // source attachment path
- null); // default source attachment root path.
+ null, // default source attachment root path.
+ true /*isExported*/);
entries.add(entry);
+
+ // now, gather the content of this library project's libs folder.
+ getJarListFromLibsFolder(libProject, jarFiles);
}
+
+ // get project dependencies
+ processReferencedProjects(libProject, refProjects, jarFiles);
}
+ // now process this projects' referenced projects
+ processReferencedProjects(iProject, refProjects, jarFiles);
+ // and its own jar files from libs
+ getJarListFromLibsFolder(iProject, jarFiles);
+
// annotations support for older version of android
if (state.getTarget() != null && state.getTarget().getVersion().getApiLevel() <= 15) {
File annotationsJar = new File(Sdk.getCurrent().getSdkLocation(),
SdkConstants.FD_TOOLS + File.separator + SdkConstants.FD_SUPPORT +
File.separator + SdkConstants.FN_ANNOTATIONS_JAR);
- IClasspathEntry entry = JavaCore.newLibraryEntry(
- new Path(annotationsJar.getAbsolutePath()),
- null, // source attachment path
- null); // default source attachment root path.
+ jarFiles.add(annotationsJar);
+ }
+
+ // now add a classpath entry for each Java project (this is a set so dups are already
+ // removed)
+ for (IProject p : refProjects) {
+ entries.add(JavaCore.newProjectEntry(p.getFullPath(), true /*isExported*/));
+ }
+
+ // and process the jar files list, but first sanitize it to remove dups.
+ JarListSanitizer sanitizer = new JarListSanitizer(
+ iProject.getFolder(SdkConstants.FD_OUTPUT).getLocation().toFile(),
+ new AndroidPrintStream(iProject, null /*prefix*/,
+ AdtPlugin.getOutStream()));
+
+ String errorMessage = null;
- entries.add(0, entry);
+ try {
+ List<File> sanitizedList = sanitizer.sanitize(jarFiles);
+
+ for (File jarFile : sanitizedList) {
+ if (jarFile instanceof CPEFile) {
+ CPEFile cpeFile = (CPEFile) jarFile;
+ IClasspathEntry e = cpeFile.getClasspathEntry();
+
+ entries.add(JavaCore.newLibraryEntry(
+ e.getPath(),
+ e.getSourceAttachmentPath(),
+ e.getSourceAttachmentRootPath(),
+ e.getAccessRules(),
+ e.getExtraAttributes(),
+ true /*isExported*/));
+ } else {
+ entries.add(JavaCore.newLibraryEntry(new Path(jarFile.getAbsolutePath()),
+ null /*sourceAttachmentPath*/, null /*sourceAttachmentRootPath*/,
+ true /*isExported*/));
+ }
+ }
+ } catch (DifferentLibException e) {
+ errorMessage = e.getMessage();
+ AdtPlugin.printErrorToConsole(iProject, (Object[]) e.getDetails());
+ } catch (Sha1Exception e) {
+ errorMessage = e.getMessage();
}
+ processError(iProject, errorMessage, AdtConstants.MARKER_DEPENDENCY,
+ true /*outputToConsole*/);
+
return new AndroidClasspathContainer(
entries.toArray(new IClasspathEntry[entries.size()]),
new Path(AdtConstants.CONTAINER_LIBRARIES),
- "Library Projects",
+ "Android Dependencies",
IClasspathContainer.K_APPLICATION);
}
+
+ private static void processReferencedProjects(IProject project,
+ Set<IProject> projects, Set<File> jarFiles) {
+ try {
+ IProject[] refs = project.getReferencedProjects();
+ for (IProject p : refs) {
+ // ignore if it's an Android project, or if it's not a Java Project
+ if (p.hasNature(JavaCore.NATURE_ID) &&
+ p.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
+ // add this project to the list
+ projects.add(p);
+
+ // get the jar dependencies of the project in the list
+ getJarListFromClasspath(p, jarFiles);
+
+ // and then process the referenced project by this project too.
+ processReferencedProjects(p, projects, jarFiles);
+ }
+ }
+ } catch (CoreException e) {
+ // can't get the referenced projects? ignore
+ }
+ }
+
+ /**
+ * Finds all the jar files inside a project's libs folder.
+ * @param project
+ * @param jarFiles
+ */
+ private static void getJarListFromLibsFolder(IProject project, Set<File> jarFiles) {
+ IFolder libsFolder = project.getFolder(SdkConstants.FD_NATIVE_LIBS);
+ if (libsFolder.exists()) {
+ try {
+ IResource[] members = libsFolder.members();
+ for (IResource member : members) {
+ if (member.getType() == IResource.FILE &&
+ AdtConstants.EXT_JAR.equalsIgnoreCase(member.getFileExtension())) {
+ jarFiles.add(member.getLocation().toFile());
+ }
+ }
+ } catch (CoreException e) {
+ // can't get the list? ignore this folder.
+ }
+ }
+ }
+
+ /**
+ * Finds all the jars a given project depends on by looking at the classpath.
+ * This must be a non android project, as android project have container that really
+ * we shouldn't go through.
+ * @param project the project to query
+ * @param jarFiles the list of file to fill.
+ */
+ private static void getJarListFromClasspath(IProject project, Set<File> jarFiles) {
+ IJavaProject javaProject = JavaCore.create(project);
+ IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+ // we could use IJavaProject.getResolvedClasspath directly, but we actually
+ // want to see the containers themselves.
+ IClasspathEntry[] classpaths = javaProject.readRawClasspath();
+ if (classpaths != null) {
+ for (IClasspathEntry e : classpaths) {
+ // if this is a classpath variable reference, we resolve it.
+ if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
+ e = JavaCore.getResolvedClasspathEntry(e);
+ }
+
+ if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+ handleClasspathEntry(e, wsRoot, jarFiles);
+ } else if (e.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+ // get the container.
+ try {
+ IClasspathContainer container = JavaCore.getClasspathContainer(
+ e.getPath(), javaProject);
+ // ignore the system and default_system types as they represent
+ // libraries that are part of the runtime.
+ if (container != null &&
+ container.getKind() == IClasspathContainer.K_APPLICATION) {
+ IClasspathEntry[] entries = container.getClasspathEntries();
+ for (IClasspathEntry entry : entries) {
+ handleClasspathEntry(entry, wsRoot, jarFiles);
+ }
+ }
+ } catch (JavaModelException jme) {
+ // can't resolve the container? ignore it.
+ AdtPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", e.getPath());
+ }
+ }
+ }
+ }
+ }
+
+ private static final class CPEFile extends File {
+ private static final long serialVersionUID = 1L;
+
+ private final IClasspathEntry mClasspathEntry;
+
+ public CPEFile(String pathname, IClasspathEntry classpathEntry) {
+ super(pathname);
+ mClasspathEntry = classpathEntry;
+ }
+
+ public CPEFile(File file, IClasspathEntry classpathEntry) {
+ super(file.getAbsolutePath());
+ mClasspathEntry = classpathEntry;
+ }
+
+ public IClasspathEntry getClasspathEntry() {
+ return mClasspathEntry;
+ }
+ }
+
+ private static void handleClasspathEntry(IClasspathEntry e, IWorkspaceRoot wsRoot,
+ Set<File> jarFiles) {
+ // get the IPath
+ IPath path = e.getPath();
+
+ IResource resource = wsRoot.findMember(path);
+
+ if (AdtConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
+ // case of a jar file (which could be relative to the workspace or a full path)
+ if (resource != null && resource.exists() &&
+ resource.getType() == IResource.FILE) {
+ jarFiles.add(new CPEFile(resource.getLocation().toFile(), e));
+ } else {
+ // if the jar path doesn't match a workspace resource,
+ // then we get an OSString and check if this links to a valid file.
+ String osFullPath = path.toOSString();
+
+ File f = new CPEFile(osFullPath, e);
+ if (f.isFile()) {
+ jarFiles.add(f);
+ }
+ }
+ }
+ }
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
index 092ffb5..63f381f 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -83,6 +83,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -712,7 +713,8 @@ public final class Sdk {
// is called back during registration with project opened in the workspace.
monitor.addResourceEventListener(mResourceEventListener);
monitor.addProjectListener(mProjectListener);
- monitor.addFileListener(mFileListener, IResourceDelta.CHANGED | IResourceDelta.ADDED);
+ monitor.addFileListener(mFileListener,
+ IResourceDelta.CHANGED | IResourceDelta.ADDED | IResourceDelta.REMOVED);
// pre-compute some paths
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
@@ -1062,6 +1064,47 @@ public final class Sdk {
// This can't happen as it's only for closed project (or non existing)
// but in that case we can't get a fileChanged on this file.
}
+ } else if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
+ // check if it's an add/remove on a jar files inside libs
+ if (file.getProjectRelativePath().segmentCount() == 2 &&
+ file.getParent().getName().equals(SdkConstants.FD_NATIVE_LIBS)) {
+ // need to update the project and whatever depend on it.
+
+ processJarFileChange(file);
+ }
+ }
+ }
+
+ private void processJarFileChange(final IFile file) {
+ try {
+ IProject iProject = file.getProject();
+
+ if (iProject.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
+ return;
+ }
+
+ List<IJavaProject> projectList = new ArrayList<IJavaProject>();
+ IJavaProject javaProject = BaseProjectHelper.getJavaProject(iProject);
+ if (javaProject != null) {
+ projectList.add(javaProject);
+ }
+
+ ProjectState state = Sdk.getProjectState(iProject);
+
+ Collection<ProjectState> parents = state.getFullParentProjects();
+ for (ProjectState s : parents) {
+ javaProject = BaseProjectHelper.getJavaProject(s.getProject());
+ if (javaProject != null) {
+ projectList.add(javaProject);
+ }
+ }
+
+ ProjectHelper.updateProjects(
+ projectList.toArray(new IJavaProject[projectList.size()]));
+
+ } catch (CoreException e) {
+ // This can't happen as it's only for closed project (or non existing)
+ // but in that case we can't get a fileChanged on this file.
}
}
};