aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptExecException.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptParser.java783
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFix.java431
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptResultException.java29
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java484
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java1225
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchDialog.java144
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchQuickFixProcessor.java224
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DefaultSourceChangeHandler.java105
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexException.java33
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexWrapper.java218
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ExecResultException.java72
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java150
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NativeLibInJarException.java61
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardExecException.java30
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardResultException.java34
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java244
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RsSourceChangeHandler.java90
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceChangeHandler.java25
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceFileData.java132
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java454
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties67
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java483
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSet.java70
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSetHelper.java200
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/JavaResChangedSet.java46
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PatternBasedDeltaVisitor.java139
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java946
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java1401
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java417
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java317
31 files changed, 0 insertions, 9083 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptExecException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptExecException.java
deleted file mode 100644
index 23b1baa92..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptExecException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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;
-
-/**
- * Exception thrown when the execution of aapt fails.
- *
- */
-public final class AaptExecException extends Exception {
- private static final long serialVersionUID = 1L;
-
- AaptExecException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptParser.java
deleted file mode 100644
index 1f17fb7c6..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptParser.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * 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.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-
-import org.eclipse.core.resources.IFile;
-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.jface.text.FindReplaceDocumentAdapter;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Region;
-import org.eclipse.ui.editors.text.TextFileDocumentProvider;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-
-import java.io.File;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public final class AaptParser {
-
- // TODO: rename the pattern to something that makes sense + javadoc comments.
- /**
- * Single line aapt warning for skipping files.<br>
- * " (skipping hidden file '&lt;file path&gt;'"
- */
- private final static Pattern sPattern0Line1 = Pattern.compile(
- "^\\s+\\(skipping hidden file\\s'(.*)'\\)$"); //$NON-NLS-1$
-
- /**
- * First line of dual line aapt error.<br>
- * "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
- * " (Occurred while parsing &lt;path&gt;)"
- */
- private final static Pattern sPattern1Line1 = Pattern.compile(
- "^ERROR\\s+at\\s+line\\s+(\\d+):\\s+(.*)$"); //$NON-NLS-1$
- /**
- * Second line of dual line aapt error.<br>
- * "ERROR at line &lt;line&gt;: &lt;error&gt;"<br>
- * " (Occurred while parsing &lt;path&gt;)"<br>
- * @see #sPattern1Line1
- */
- private final static Pattern sPattern1Line2 = Pattern.compile(
- "^\\s+\\(Occurred while parsing\\s+(.*)\\)$"); //$NON-NLS-1$
- /**
- * First line of dual line aapt error.<br>
- * "ERROR: &lt;error&gt;"<br>
- * "Defined at file &lt;path&gt; line &lt;line&gt;"
- */
- private final static Pattern sPattern2Line1 = Pattern.compile(
- "^ERROR:\\s+(.+)$"); //$NON-NLS-1$
- /**
- * Second line of dual line aapt error.<br>
- * "ERROR: &lt;error&gt;"<br>
- * "Defined at file &lt;path&gt; line &lt;line&gt;"<br>
- * @see #sPattern2Line1
- */
- private final static Pattern sPattern2Line2 = Pattern.compile(
- "Defined\\s+at\\s+file\\s+(.+)\\s+line\\s+(\\d+)"); //$NON-NLS-1$
- /**
- * Single line aapt error<br>
- * "&lt;path&gt; line &lt;line&gt;: &lt;error&gt;"
- */
- private final static Pattern sPattern3Line1 = Pattern.compile(
- "^(.+)\\sline\\s(\\d+):\\s(.+)$"); //$NON-NLS-1$
- /**
- * First line of dual line aapt error.<br>
- * "ERROR parsing XML file &lt;path&gt;"<br>
- * "&lt;error&gt; at line &lt;line&gt;"
- */
- private final static Pattern sPattern4Line1 = Pattern.compile(
- "^Error\\s+parsing\\s+XML\\s+file\\s(.+)$"); //$NON-NLS-1$
- /**
- * Second line of dual line aapt error.<br>
- * "ERROR parsing XML file &lt;path&gt;"<br>
- * "&lt;error&gt; at line &lt;line&gt;"<br>
- * @see #sPattern4Line1
- */
- private final static Pattern sPattern4Line2 = Pattern.compile(
- "^(.+)\\s+at\\s+line\\s+(\\d+)$"); //$NON-NLS-1$
-
- /**
- * Single line aapt warning<br>
- * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
- */
- private final static Pattern sPattern5Line1 = Pattern.compile(
- "^(.+?):(\\d+):\\s+WARNING:(.+)$"); //$NON-NLS-1$
-
- /**
- * Single line aapt error<br>
- * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
- */
- private final static Pattern sPattern6Line1 = Pattern.compile(
- "^(.+?):(\\d+):\\s+(.+)$"); //$NON-NLS-1$
-
- /**
- * 4 line aapt error<br>
- * "ERROR: 9-path image &lt;path&gt; malformed"<br>
- * Line 2 and 3 are taken as-is while line 4 is ignored (it repeats with<br>
- * 'ERROR: failure processing &lt;path&gt;)
- */
- private final static Pattern sPattern7Line1 = Pattern.compile(
- "^ERROR:\\s+9-patch\\s+image\\s+(.+)\\s+malformed\\.$"); //$NON-NLS-1$
-
- private final static Pattern sPattern8Line1 = Pattern.compile(
- "^(invalid resource directory name): (.*)$"); //$NON-NLS-1$
-
- /**
- * Portion of the error message which states the context in which the error occurred,
- * such as which property was being processed and what the string value was that
- * caused the error.
- * <p>
- * Example:
- * error: No resource found that matches the given name (at 'text' with value '@string/foo')
- */
- private static final Pattern sValueRangePattern =
- Pattern.compile("\\(at '(.+)' with value '(.*)'\\)"); //$NON-NLS-1$
-
-
- /**
- * Portion of error message which points to the second occurrence of a repeated resource
- * definition.
- * <p>
- * Example:
- * error: Resource entry repeatedStyle1 already has bag item android:gravity.
- */
- private static final Pattern sRepeatedRangePattern =
- Pattern.compile("Resource entry (.+) already has bag item (.+)\\."); //$NON-NLS-1$
-
- /**
- * Error message emitted when aapt skips a file because for example it's name is
- * invalid, such as a layout file name which starts with _.
- * <p>
- * This error message is used by AAPT in Tools 19 and earlier.
- */
- private static final Pattern sSkippingPattern =
- Pattern.compile(" \\(skipping (.+) .+ '(.*)'\\)"); //$NON-NLS-1$
-
- /**
- * Error message emitted when aapt skips a file because for example it's name is
- * invalid, such as a layout file name which starts with _.
- * <p>
- * This error message is used by AAPT in Tools 20 and later.
- */
- private static final Pattern sNewSkippingPattern =
- Pattern.compile(" \\(skipping .+ '(.+)' due to ANDROID_AAPT_IGNORE pattern '.+'\\)"); //$NON-NLS-1$
-
- /**
- * Suffix of error message which points to the first occurrence of a repeated resource
- * definition.
- * Example:
- * Originally defined here.
- */
- private static final String ORIGINALLY_DEFINED_MSG = "Originally defined here."; //$NON-NLS-1$
-
- /**
- * Portion of error message which points to the second occurrence of a repeated resource
- * definition.
- * <p>
- * Example:
- * error: Resource entry repeatedStyle1 already has bag item android:gravity.
- */
- private static final Pattern sNoResourcePattern =
- Pattern.compile("No resource found that matches the given name: attr '(.+)'\\."); //$NON-NLS-1$
-
- /**
- * Portion of error message which points to a missing required attribute in a
- * resource definition.
- * <p>
- * Example:
- * error: error: A 'name' attribute is required for <style>
- */
- private static final Pattern sRequiredPattern =
- Pattern.compile("A '(.+)' attribute is required for <(.+)>"); //$NON-NLS-1$
-
- /**
- * 2 line aapt error<br>
- * "ERROR: Invalid configuration: foo"<br>
- * " ^^^"<br>
- * There's no need to parse the 2nd line.
- */
- private final static Pattern sPattern9Line1 = Pattern.compile(
- "^Invalid configuration: (.+)$"); //$NON-NLS-1$
-
- private final static Pattern sXmlBlockPattern = Pattern.compile(
- "W/ResourceType\\(.*\\): Bad XML block: no root element node found"); //$NON-NLS-1$
-
- /**
- * Parse the output of aapt and mark the incorrect file with error markers
- *
- * @param results the output of aapt
- * @param project the project containing the file to mark
- * @return true if the parsing failed, false if success.
- */
- public static boolean parseOutput(List<String> results, IProject project) {
- int size = results.size();
- if (size > 0) {
- return parseOutput(results.toArray(new String[size]), project);
- }
-
- return false;
- }
-
- /**
- * Parse the output of aapt and mark the incorrect file with error markers
- *
- * @param results the output of aapt
- * @param project the project containing the file to mark
- * @return true if the parsing failed, false if success.
- */
- public static boolean parseOutput(String[] results, IProject project) {
- // nothing to parse? just return false;
- if (results.length == 0) {
- return false;
- }
-
- // get the root of the project so that we can make IFile from full
- // file path
- String osRoot = project.getLocation().toOSString();
-
- Matcher m;
-
- for (int i = 0; i < results.length ; i++) {
- String p = results[i];
-
- m = sPattern0Line1.matcher(p);
- if (m.matches()) {
- // we ignore those (as this is an ignore message from aapt)
- continue;
- }
-
- m = sPattern1Line1.matcher(p);
- if (m.matches()) {
- String lineStr = m.group(1);
- String msg = m.group(2);
-
- // get the matcher for the next line.
- m = getNextLineMatcher(results, ++i, sPattern1Line2);
- if (m == null) {
- return true;
- }
-
- String location = m.group(1);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
- continue;
- }
-
- // this needs to be tested before Pattern2 since they both start with 'ERROR:'
- m = sPattern7Line1.matcher(p);
- if (m.matches()) {
- String location = m.group(1);
- String msg = p; // default msg is the line in case we don't find anything else
-
- if (++i < results.length) {
- msg = results[i].trim();
- if (++i < results.length) {
- msg = msg + " - " + results[i].trim(); //$NON-NLS-1$
-
- // skip the next line
- i++;
- }
- }
-
- // display the error
- if (checkAndMark(location, null, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern2Line1.matcher(p);
- if (m.matches()) {
- // get the msg
- String msg = m.group(1);
-
- // get the matcher for the next line.
- m = getNextLineMatcher(results, ++i, sPattern2Line2);
- if (m == null) {
- return true;
- }
-
- String location = m.group(1);
- String lineStr = m.group(2);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
- continue;
- }
-
- m = sPattern3Line1.matcher(p);
- if (m.matches()) {
- String location = m.group(1);
- String lineStr = m.group(2);
- String msg = m.group(3);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern4Line1.matcher(p);
- if (m.matches()) {
- // get the filename.
- String location = m.group(1);
-
- // get the matcher for the next line.
- m = getNextLineMatcher(results, ++i, sPattern4Line2);
- if (m == null) {
- return true;
- }
-
- String msg = m.group(1);
- String lineStr = m.group(2);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern5Line1.matcher(p);
- if (m.matches()) {
- String location = m.group(1);
- String lineStr = m.group(2);
- String msg = m.group(3);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern6Line1.matcher(p);
- if (m.matches()) {
- String location = m.group(1);
- String lineStr = m.group(2);
- String msg = m.group(3);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, lineStr, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern8Line1.matcher(p);
- if (m.matches()) {
- String location = m.group(2);
- String msg = m.group(1);
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, null, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sPattern9Line1.matcher(p);
- if (m.matches()) {
- String badConfig = m.group(1);
- String msg = String.format("APK Configuration filter '%1$s' is invalid", badConfig);
-
- // skip the next line
- i++;
-
- // check the values and attempt to mark the file.
- if (checkAndMark(null /*location*/, null, msg, osRoot, project,
- AdtConstants.MARKER_AAPT_PACKAGE, IMarker.SEVERITY_ERROR) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sNewSkippingPattern.matcher(p);
- if (m.matches()) {
- String location = m.group(1);
-
- if (location.startsWith(".") //$NON-NLS-1$
- || location.endsWith("~")) { //$NON-NLS-1$
- continue;
- }
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, null, p.trim(), osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sSkippingPattern.matcher(p);
- if (m.matches()) {
- String location = m.group(2);
-
- // Certain files can safely be skipped without marking the project
- // as having errors. See isHidden() in AaptAssets.cpp:
- String type = m.group(1);
- if (type.equals("backup") //$NON-NLS-1$ // main.xml~, etc
- || type.equals("hidden") //$NON-NLS-1$ // .gitignore, etc
- || type.equals("index")) { //$NON-NLS-1$ // thumbs.db, etc
- continue;
- }
-
- // check the values and attempt to mark the file.
- if (checkAndMark(location, null, p.trim(), osRoot, project,
- AdtConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
- return true;
- }
-
- // success, go to the next line
- continue;
- }
-
- m = sXmlBlockPattern.matcher(p);
- if (m.matches()) {
- // W/ResourceType(12345): Bad XML block: no root element node found
- // Sadly there's NO filename reference; this error typically describes the
- // error *after* this line.
- if (results.length == 1) {
- // This is the only error message: dump to console and quit
- return true;
- }
- // Continue: the real culprit is displayed next and should get a marker
- continue;
- }
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Check if the parameters gotten from the error output are valid, and mark
- * the file with an AAPT marker.
- * @param location the full OS path of the error file. If null, the project is marked
- * @param lineStr
- * @param message
- * @param root The root directory of the project, in OS specific format.
- * @param project
- * @param markerId The marker id to put.
- * @param severity The severity of the marker to put (IMarker.SEVERITY_*)
- * @return true if the parameters were valid and the file was marked successfully.
- *
- * @see IMarker
- */
- private static final boolean checkAndMark(String location, String lineStr,
- String message, String root, IProject project, String markerId, int severity) {
- // check this is in fact a file
- if (location != null) {
- File f = new File(location);
- if (f.exists() == false) {
- return false;
- }
- }
-
- // get the line number
- int line = -1; // default value for error with no line.
-
- if (lineStr != null) {
- try {
- line = Integer.parseInt(lineStr);
- } catch (NumberFormatException e) {
- // looks like the string we extracted wasn't a valid
- // file number. Parsing failed and we return true
- return false;
- }
- }
-
- // add the marker
- IResource f2 = project;
- if (location != null) {
- f2 = getResourceFromFullPath(location, root, project);
- if (f2 == null) {
- return false;
- }
- }
-
- // Attempt to determine the exact range of characters affected by this error.
- // This will look up the actual text of the file, go to the particular error line
- // and scan for the specific string mentioned in the error.
- int startOffset = -1;
- int endOffset = -1;
- if (f2 instanceof IFile) {
- IRegion region = findRange((IFile) f2, line, message);
- if (region != null) {
- startOffset = region.getOffset();
- endOffset = startOffset + region.getLength();
- }
- }
-
- // check if there's a similar marker already, since aapt is launched twice
- boolean markerAlreadyExists = false;
- try {
- IMarker[] markers = f2.findMarkers(markerId, true, IResource.DEPTH_ZERO);
-
- for (IMarker marker : markers) {
- if (startOffset != -1) {
- int tmpBegin = marker.getAttribute(IMarker.CHAR_START, -1);
- if (tmpBegin != startOffset) {
- break;
- }
- int tmpEnd = marker.getAttribute(IMarker.CHAR_END, -1);
- if (tmpEnd != startOffset) {
- break;
- }
- }
-
- int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1);
- if (tmpLine != line) {
- break;
- }
-
- int tmpSeverity = marker.getAttribute(IMarker.SEVERITY, -1);
- if (tmpSeverity != severity) {
- break;
- }
-
- String tmpMsg = marker.getAttribute(IMarker.MESSAGE, null);
- if (tmpMsg == null || tmpMsg.equals(message) == false) {
- break;
- }
-
- // if we're here, all the marker attributes are equals, we found it
- // and exit
- markerAlreadyExists = true;
- break;
- }
-
- } catch (CoreException e) {
- // if we couldn't get the markers, then we just mark the file again
- // (since markerAlreadyExists is initialized to false, we do nothing)
- }
-
- if (markerAlreadyExists == false) {
- BaseProjectHelper.markResource(f2, markerId, message, line,
- startOffset, endOffset, severity);
- }
-
- return true;
- }
-
- /**
- * Given an aapt error message in a given file and a given (initial) line number,
- * return the corresponding offset range for the error, or null.
- */
- private static IRegion findRange(IFile file, int line, String message) {
- Matcher matcher = sValueRangePattern.matcher(message);
- if (matcher.find()) {
- String property = matcher.group(1);
- String value = matcher.group(2);
-
- // First find the property. We can't just immediately look for the
- // value, because there could be other attributes in this element
- // earlier than the one in error, and we might accidentally pick
- // up on a different occurrence of the value in a context where
- // it is valid.
- if (value.length() > 0) {
- return findRange(file, line, property, value);
- } else {
- // Find first occurrence of property followed by '' or ""
- IRegion region1 = findRange(file, line, property, "\"\""); //$NON-NLS-1$
- IRegion region2 = findRange(file, line, property, "''"); //$NON-NLS-1$
- if (region1 == null) {
- if (region2 == null) {
- // Highlight the property instead
- return findRange(file, line, property, null);
- }
- return region2;
- } else if (region2 == null) {
- return region1;
- } else if (region1.getOffset() < region2.getOffset()) {
- return region1;
- } else {
- return region2;
- }
- }
- }
-
- matcher = sRepeatedRangePattern.matcher(message);
- if (matcher.find()) {
- String property = matcher.group(2);
- return findRange(file, line, property, null);
- }
-
- matcher = sNoResourcePattern.matcher(message);
- if (matcher.find()) {
- String property = matcher.group(1);
- return findRange(file, line, property, null);
- }
-
- matcher = sRequiredPattern.matcher(message);
- if (matcher.find()) {
- String elementName = matcher.group(2);
- IRegion region = findRange(file, line, '<' + elementName, null);
- if (region != null && region.getLength() > 1) {
- // Skip the opening <
- region = new Region(region.getOffset() + 1, region.getLength() - 1);
- }
- return region;
- }
-
- if (message.endsWith(ORIGINALLY_DEFINED_MSG)) {
- return findLineTextRange(file, line);
- }
-
- return null;
- }
-
- /**
- * Given a file and line number, return the range of the first match starting on the
- * given line. If second is non null, also search for the second string starting at he
- * location of the first string.
- */
- private static IRegion findRange(IFile file, int line, String first,
- String second) {
- IRegion region = null;
- IDocumentProvider provider = new TextFileDocumentProvider();
- try {
- provider.connect(file);
- IDocument document = provider.getDocument(file);
- if (document != null) {
- IRegion lineInfo = document.getLineInformation(line - 1);
- int lineStartOffset = lineInfo.getOffset();
- // The aapt errors will be anchored on the line where the
- // element starts - which means that with formatting where
- // attributes end up on subsequent lines we don't find it on
- // the error line indicated by aapt.
- // Therefore, search forwards in the document.
- FindReplaceDocumentAdapter adapter =
- new FindReplaceDocumentAdapter(document);
-
- region = adapter.find(lineStartOffset, first,
- true /*forwardSearch*/, true /*caseSensitive*/,
- false /*wholeWord*/, false /*regExSearch*/);
- if (region != null && second != null) {
- region = adapter.find(region.getOffset() + first.length(), second,
- true /*forwardSearch*/, true /*caseSensitive*/,
- false /*wholeWord*/, false /*regExSearch*/);
- }
- }
- } catch (Exception e) {
- AdtPlugin.log(e, "Can't find range information for %1$s", file.getName());
- } finally {
- provider.disconnect(file);
- }
- return region;
- }
-
- /** Returns the non-whitespace line range at the given line number. */
- private static IRegion findLineTextRange(IFile file, int line) {
- IDocumentProvider provider = new TextFileDocumentProvider();
- try {
- provider.connect(file);
- IDocument document = provider.getDocument(file);
- if (document != null) {
- IRegion lineInfo = document.getLineInformation(line - 1);
- String lineContents = document.get(lineInfo.getOffset(), lineInfo.getLength());
- int lineBegin = 0;
- int lineEnd = lineContents.length()-1;
-
- for (; lineEnd >= 0; lineEnd--) {
- char c = lineContents.charAt(lineEnd);
- if (!Character.isWhitespace(c)) {
- break;
- }
- }
- lineEnd++;
- for (; lineBegin < lineEnd; lineBegin++) {
- char c = lineContents.charAt(lineBegin);
- if (!Character.isWhitespace(c)) {
- break;
- }
- }
- if (lineBegin < lineEnd) {
- return new Region(lineInfo.getOffset() + lineBegin, lineEnd - lineBegin);
- }
- }
- } catch (Exception e) {
- AdtPlugin.log(e, "Can't find range information for %1$s", file.getName());
- } finally {
- provider.disconnect(file);
- }
-
- return null;
- }
-
- /**
- * Returns a matching matcher for the next line
- * @param lines The array of lines
- * @param nextIndex The index of the next line
- * @param pattern The pattern to match
- * @return null if error or no match, the matcher otherwise.
- */
- private static final Matcher getNextLineMatcher(String[] lines,
- int nextIndex, Pattern pattern) {
- // unless we can't, because we reached the last line
- if (nextIndex == lines.length) {
- // we expected a 2nd line, so we flag as error
- // and we bail
- return null;
- }
-
- Matcher m = pattern.matcher(lines[nextIndex]);
- if (m.matches()) {
- return m;
- }
-
- return null;
- }
-
- private static IResource getResourceFromFullPath(String filename, String root,
- IProject project) {
- if (filename.startsWith(root)) {
- String file = filename.substring(root.length());
-
- // get the resource
- IResource r = project.findMember(file);
-
- // if the resource is valid, we add the marker
- if (r != null && r.exists()) {
- return r;
- }
- }
-
- return null;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFix.java
deleted file mode 100644
index 3db380832..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptQuickFix.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2011 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 static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.XMLNS_ANDROID;
-import static com.android.SdkConstants.XMLNS_URI;
-
-import com.android.ide.common.resources.ResourceUrl;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
-import com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
-import com.android.resources.ResourceType;
-import com.android.utils.Pair;
-
-import org.eclipse.core.resources.IFile;
-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.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.contentassist.ICompletionProposal;
-import org.eclipse.jface.text.contentassist.IContextInformation;
-import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
-import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.IMarkerResolution;
-import org.eclipse.ui.IMarkerResolution2;
-import org.eclipse.ui.IMarkerResolutionGenerator2;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.editors.text.TextFileDocumentProvider;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-/**
- * Shared handler for both quick assist processors (Control key handler) and quick fix
- * marker resolution (Problem view handling), since there is a lot of overlap between
- * these two UI handlers.
- */
-@SuppressWarnings("restriction") // XML model
-public class AaptQuickFix implements IMarkerResolutionGenerator2, IQuickAssistProcessor {
-
- public AaptQuickFix() {
- }
-
- /** Returns the error message from aapt that signals missing resources */
- private static String getTargetMarkerErrorMessage() {
- return "No resource found that matches the given name";
- }
-
- /** Returns the error message from aapt that signals a missing namespace declaration */
- private static String getUnboundErrorMessage() {
- return "Error parsing XML: unbound prefix";
- }
-
- // ---- Implements IMarkerResolution2 ----
-
- @Override
- public boolean hasResolutions(IMarker marker) {
- String message = null;
- try {
- message = (String) marker.getAttribute(IMarker.MESSAGE);
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
-
- return message != null
- && (message.contains(getTargetMarkerErrorMessage())
- || message.contains(getUnboundErrorMessage()));
- }
-
- @Override
- public IMarkerResolution[] getResolutions(IMarker marker) {
- IResource markerResource = marker.getResource();
- IProject project = markerResource.getProject();
- try {
- String message = (String) marker.getAttribute(IMarker.MESSAGE);
- if (message.contains(getUnboundErrorMessage()) && markerResource instanceof IFile) {
- return new IMarkerResolution[] {
- new CreateNamespaceFix((IFile) markerResource)
- };
- }
- } catch (CoreException e1) {
- AdtPlugin.log(e1, null);
- }
-
- int start = marker.getAttribute(IMarker.CHAR_START, 0);
- int end = marker.getAttribute(IMarker.CHAR_END, 0);
- if (end > start) {
- int length = end - start;
- IDocumentProvider provider = new TextFileDocumentProvider();
- try {
- provider.connect(markerResource);
- IDocument document = provider.getDocument(markerResource);
- String resource = document.get(start, length);
- if (ResourceHelper.canCreateResource(resource)) {
- return new IMarkerResolution[] {
- new CreateResourceProposal(project, resource)
- };
- }
- } catch (Exception e) {
- AdtPlugin.log(e, "Can't find range information for %1$s", markerResource);
- } finally {
- provider.disconnect(markerResource);
- }
- }
-
- return null;
- }
-
- // ---- Implements IQuickAssistProcessor ----
-
- @Override
- public boolean canAssist(IQuickAssistInvocationContext invocationContext) {
- return true;
- }
-
- @Override
- public boolean canFix(Annotation annotation) {
- return true;
- }
-
- @Override
- public ICompletionProposal[] computeQuickAssistProposals(
- IQuickAssistInvocationContext invocationContext) {
-
- // We have to find the corresponding project/file (so we can look up the aapt
- // error markers). Unfortunately, an IQuickAssistProcessor only gets
- // access to an ISourceViewer which has no hooks back to the surrounding
- // editor.
- //
- // However, the IQuickAssistProcessor will only be used interactively by a file
- // being edited, so we can cheat like the hyperlink detector and simply
- // look up the currently active file in the IDE. To be on the safe side,
- // we'll make sure that that editor has the same sourceViewer such that
- // we are indeed looking at the right file:
- ISourceViewer sourceViewer = invocationContext.getSourceViewer();
- AndroidXmlEditor editor = AndroidXmlEditor.fromTextViewer(sourceViewer);
- if (editor != null) {
- IFile file = editor.getInputFile();
- if (file == null) {
- return null;
- }
- IDocument document = sourceViewer.getDocument();
- List<IMarker> markers = AdtUtils.findMarkersOnLine(AdtConstants.MARKER_AAPT_COMPILE,
- file, document, invocationContext.getOffset());
- try {
- for (IMarker marker : markers) {
- String message = marker.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
- if (message.contains(getTargetMarkerErrorMessage())) {
- int start = marker.getAttribute(IMarker.CHAR_START, 0);
- int end = marker.getAttribute(IMarker.CHAR_END, 0);
- int length = end - start;
- String resource = document.get(start, length);
- // Can only offer create value for non-framework value
- // resources
- if (ResourceHelper.canCreateResource(resource)) {
- IProject project = editor.getProject();
- return new ICompletionProposal[] {
- new CreateResourceProposal(project, resource)
- };
- }
- } else if (message.contains(getUnboundErrorMessage())) {
- return new ICompletionProposal[] {
- new CreateNamespaceFix(null)
- };
- }
- }
- } catch (BadLocationException e) {
- AdtPlugin.log(e, null);
- }
- }
-
- return null;
- }
-
- @Override
- public String getErrorMessage() {
- return null;
- }
-
- /** Quick fix to insert namespace binding when missing */
- private final static class CreateNamespaceFix
- implements ICompletionProposal, IMarkerResolution2 {
- private IFile mFile;
-
- public CreateNamespaceFix(IFile file) {
- mFile = file;
- }
-
- private IndexedRegion perform(IDocument doc) {
- IModelManager manager = StructuredModelManager.getModelManager();
- IStructuredModel model = manager.getExistingModelForEdit(doc);
- if (model != null) {
- try {
- perform(model);
- } finally {
- model.releaseFromEdit();
- }
- }
-
- return null;
- }
-
- private IndexedRegion perform(IFile file) {
- IModelManager manager = StructuredModelManager.getModelManager();
- IStructuredModel model;
- try {
- model = manager.getModelForEdit(file);
- if (model != null) {
- try {
- perform(model);
- } finally {
- model.releaseFromEdit();
- }
- }
- } catch (Exception e) {
- AdtPlugin.log(e, "Can't look up XML model");
- }
-
- return null;
- }
-
- private IndexedRegion perform(IStructuredModel model) {
- if (model instanceof IDOMModel) {
- IDOMModel domModel = (IDOMModel) model;
- Document document = domModel.getDocument();
- Element element = document.getDocumentElement();
- Attr attr = document.createAttributeNS(XMLNS_URI, XMLNS_ANDROID);
- attr.setValue(ANDROID_URI);
- element.getAttributes().setNamedItemNS(attr);
- return (IndexedRegion) attr;
- }
-
- return null;
- }
-
- // ---- Implements ICompletionProposal ----
-
- @Override
- public void apply(IDocument document) {
- perform(document);
- }
-
- @Override
- public String getAdditionalProposalInfo() {
- return "Adds an Android namespace declaratiopn to the root element.";
- }
-
- @Override
- public IContextInformation getContextInformation() {
- return null;
- }
-
- @Override
- public String getDisplayString() {
- return "Insert namespace binding";
- }
-
- @Override
- public Image getImage() {
- return AdtPlugin.getAndroidLogo();
- }
-
- @Override
- public Point getSelection(IDocument doc) {
- return null;
- }
-
-
- // ---- Implements MarkerResolution2 ----
-
- @Override
- public String getLabel() {
- return getDisplayString();
- }
-
- @Override
- public void run(IMarker marker) {
- try {
- AdtPlugin.openFile(mFile, null);
- } catch (PartInitException e) {
- AdtPlugin.log(e, "Can't open file %1$s", mFile.getName());
- }
-
- IndexedRegion indexedRegion = perform(mFile);
- if (indexedRegion != null) {
- try {
- IRegion region =
- new Region(indexedRegion.getStartOffset(), indexedRegion.getLength());
- AdtPlugin.openFile(mFile, region);
- } catch (PartInitException e) {
- AdtPlugin.log(e, "Can't open file %1$s", mFile.getName());
- }
- }
- }
-
- @Override
- public String getDescription() {
- return getAdditionalProposalInfo();
- }
- }
-
- private static class CreateResourceProposal
- implements ICompletionProposal, IMarkerResolution2 {
- private final IProject mProject;
- private final String mResource;
-
- CreateResourceProposal(IProject project, String resource) {
- super();
- mProject = project;
- mResource = resource;
- }
-
- private void perform() {
- ResourceUrl resource = ResourceUrl.parse(mResource);
- if (resource == null) {
- return;
- }
- ResourceType type = resource.type;
- String name = resource.name;
- assert !resource.framework;
- String value = ""; //$NON-NLS-1$
-
- // Try to pick a reasonable first guess. The new value will be highlighted and
- // selected for editing, but if we have an initial value then the new file
- // won't show an error.
- switch (type) {
- case STRING: value = "TODO"; break; //$NON-NLS-1$
- case DIMEN: value = "1dp"; break; //$NON-NLS-1$
- case BOOL: value = "true"; break; //$NON-NLS-1$
- case COLOR: value = "#000000"; break; //$NON-NLS-1$
- case INTEGER: value = "1"; break; //$NON-NLS-1$
- case ARRAY: value = "<item>1</item>"; break; //$NON-NLS-1$
- }
-
- Pair<IFile, IRegion> location =
- ResourceHelper.createResource(mProject, type, name, value);
- if (location != null) {
- IFile file = location.getFirst();
- IRegion region = location.getSecond();
- try {
- AdtPlugin.openFile(file, region);
- } catch (PartInitException e) {
- AdtPlugin.log(e, "Can't open file %1$s", file.getName());
- }
- }
- }
-
- // ---- Implements ICompletionProposal ----
-
- @Override
- public void apply(IDocument document) {
- perform();
- }
-
- @Override
- public String getAdditionalProposalInfo() {
- return "Creates an XML file entry for the given missing resource "
- + "and opens it in the editor.";
- }
-
- @Override
- public IContextInformation getContextInformation() {
- return null;
- }
-
- @Override
- public String getDisplayString() {
- return String.format("Create resource %1$s", mResource);
- }
-
- @Override
- public Image getImage() {
- return AdtPlugin.getAndroidLogo();
- }
-
- @Override
- public Point getSelection(IDocument document) {
- return null;
- }
-
- // ---- Implements MarkerResolution2 ----
-
- @Override
- public String getLabel() {
- return getDisplayString();
- }
-
- @Override
- public void run(IMarker marker) {
- perform();
- }
-
- @Override
- public String getDescription() {
- return getAdditionalProposalInfo();
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptResultException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptResultException.java
deleted file mode 100644
index 8d8fe683f..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AaptResultException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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;
-
-/**
- * Exception thrown when aapt reports an error in the resources.
- *
- */
-public final class AaptResultException extends ExecResultException {
- private static final long serialVersionUID = 1L;
-
- AaptResultException(int errorCode, String[] output) {
- super(errorCode, output);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java
deleted file mode 100644
index 806fa9c40..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/AidlProcessor.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2011 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.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
-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;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.io.FileOp;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-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.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IJavaProject;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A {@link SourceProcessor} for aidl files.
- *
- */
-public class AidlProcessor extends SourceProcessor {
-
- private static final String PROPERTY_COMPILE_AIDL = "compileAidl"; //$NON-NLS-1$
-
- /**
- * Single line aidl error<br>
- * {@code <path>:<line>: <error>}<br>
- * or<br>
- * {@code <path>:<line> <error>}<br>
- */
- private static Pattern sAidlPattern1 = Pattern.compile("^(.+?):(\\d+):?\\s(.+)$"); //$NON-NLS-1$
-
- private final static Set<String> EXTENSIONS = Collections.singleton(SdkConstants.EXT_AIDL);
-
- private enum AidlType {
- UNKNOWN, INTERFACE, PARCELABLE;
- }
-
- // See comment in #getAidlType()
-// private final static Pattern sParcelablePattern = Pattern.compile(
-// "^\\s*parcelable\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*;\\s*$");
-//
-// private final static Pattern sInterfacePattern = Pattern.compile(
-// "^\\s*interface\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?:\\{.*)?$");
-
-
- public AidlProcessor(@NonNull IJavaProject javaProject, @NonNull BuildToolInfo buildToolInfo,
- @NonNull IFolder genFolder) {
- super(javaProject, buildToolInfo, genFolder);
- }
-
- @Override
- protected Set<String> getExtensions() {
- return EXTENSIONS;
- }
-
- @Override
- protected String getSavePropertyName() {
- return PROPERTY_COMPILE_AIDL;
- }
-
- @Override
- protected void doCompileFiles(List<IFile> sources, BaseBuilder builder,
- IProject project, IAndroidTarget projectTarget,
- List<IPath> sourceFolders, List<IFile> notCompiledOut, List<File> libraryProjectsOut,
- IProgressMonitor monitor) throws CoreException {
- // create the command line
- List<String> commandList = new ArrayList<String>(
- 4 + sourceFolders.size() + libraryProjectsOut.size());
- commandList.add(getBuildToolInfo().getPath(BuildToolInfo.PathId.AIDL));
- commandList.add(quote("-p" + projectTarget.getPath(IAndroidTarget.ANDROID_AIDL))); //$NON-NLS-1$
-
- // since the path are relative to the workspace and not the project itself, we need
- // the workspace root.
- IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
- for (IPath p : sourceFolders) {
- IFolder f = wsRoot.getFolder(p);
- if (f.exists()) { // if the resource doesn't exist, getLocation will return null.
- commandList.add(quote("-I" + f.getLocation().toOSString())); //$NON-NLS-1$
- }
- }
-
- for (File libOut : libraryProjectsOut) {
- // FIXME: make folder configurable
- File aidlFile = new File(libOut, SdkConstants.FD_AIDL);
- if (aidlFile.isDirectory()) {
- commandList.add(quote("-I" + aidlFile.getAbsolutePath())); //$NON-NLS-1$
- }
- }
-
- // convert to array with 2 extra strings for the in/out file paths.
- int index = commandList.size();
- String[] commands = commandList.toArray(new String[index + 2]);
-
- boolean verbose = AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE;
-
- // remove the generic marker from the project
- builder.removeMarkersFromResource(project, AdtConstants.MARKER_AIDL);
-
- // prepare the two output folders.
- IFolder genFolder = getGenFolder();
- IFolder projectOut = BaseProjectHelper.getAndroidOutputFolder(project);
- IFolder aidlOutFolder = projectOut.getFolder(SdkConstants.FD_AIDL);
- if (aidlOutFolder.exists() == false) {
- aidlOutFolder.create(true /*force*/, true /*local*/,
- new SubProgressMonitor(monitor, 10));
- }
-
- boolean success = false;
-
- // loop until we've compile them all
- for (IFile sourceFile : sources) {
- if (verbose) {
- String name = sourceFile.getName();
- IPath sourceFolderPath = getSourceFolderFor(sourceFile);
- if (sourceFolderPath != null) {
- // make a path to the source file relative to the source folder.
- IPath relative = sourceFile.getFullPath().makeRelativeTo(sourceFolderPath);
- name = relative.toString();
- }
- AdtPlugin.printToConsole(project, "AIDL: " + name);
- }
-
- // Remove the AIDL error markers from the aidl file
- builder.removeMarkersFromResource(sourceFile, AdtConstants.MARKER_AIDL);
-
- // get the path of the source file.
- IPath sourcePath = sourceFile.getLocation();
- String osSourcePath = sourcePath.toOSString();
-
- // look if we already know the output
- SourceFileData data = getFileData(sourceFile);
- if (data == null) {
- data = new SourceFileData(sourceFile);
- addData(data);
- }
-
- // if there's no output file yet, compute it.
- if (data.getOutput() == null) {
- IFile javaFile = getAidlOutputFile(sourceFile, genFolder,
- true /*replaceExt*/, true /*createFolders*/, monitor);
- data.setOutputFile(javaFile);
- }
-
- // finish to set the command line.
- commands[index] = quote(osSourcePath);
- commands[index + 1] = quote(data.getOutput().getLocation().toOSString());
-
- // launch the process
- if (execAidl(builder, project, commands, sourceFile, verbose) == false) {
- // aidl failed. File should be marked. We add the file to the list
- // of file that will need compilation again.
- notCompiledOut.add(sourceFile);
- } else {
- // Success. we'll return that we generated code
- setCompilationStatus(COMPILE_STATUS_CODE);
- success = true;
-
- // Also copy the file to the bin folder.
- IFile aidlOutFile = getAidlOutputFile(sourceFile, aidlOutFolder,
- false /*replaceExt*/, true /*createFolders*/, monitor);
-
- FileOp op = new FileOp();
- try {
- op.copyFile(sourceFile.getLocation().toFile(),
- aidlOutFile.getLocation().toFile());
- } catch (IOException e) {
- }
- }
- }
-
- if (success) {
- aidlOutFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
- }
- }
-
- @Override
- protected void loadOutputAndDependencies() {
- IProgressMonitor monitor = new NullProgressMonitor();
- IFolder genFolder = getGenFolder();
-
- Collection<SourceFileData> dataList = getAllFileData();
- for (SourceFileData data : dataList) {
- try {
- IFile javaFile = getAidlOutputFile(data.getSourceFile(), genFolder,
- true /*replaceExt*/, false /*createFolders*/, monitor);
- data.setOutputFile(javaFile);
- } catch (CoreException e) {
- // ignore, we're not asking to create the folder so this won't happen anyway.
- }
-
- }
- }
-
- /**
- * Execute the aidl command line, parse the output, and mark the aidl file
- * with any reported errors.
- * @param command the String array containing the command line to execute.
- * @param file The IFile object representing the aidl file being
- * compiled.
- * @param verbose the build verbosity
- * @return false if the exec failed, and build needs to be aborted.
- */
- private boolean execAidl(BaseBuilder builder, IProject project, String[] command, IFile file,
- boolean verbose) {
- // do the exec
- try {
- if (verbose) {
- StringBuilder sb = new StringBuilder();
- for (String c : command) {
- sb.append(c);
- sb.append(' ');
- }
- String cmd_line = sb.toString();
- AdtPlugin.printToConsole(project, cmd_line);
- }
-
- Process p = Runtime.getRuntime().exec(command);
-
- // list to store each line of stderr
- ArrayList<String> stdErr = new ArrayList<String>();
-
- // get the output and return code from the process
- int returnCode = BuildHelper.grabProcessOutput(project, p, stdErr);
-
- if (stdErr.size() > 0) {
- // attempt to parse the error output
- boolean parsingError = parseAidlOutput(stdErr, file);
-
- // If the process failed and we couldn't parse the output
- // we print a message, mark the project and exit
- if (returnCode != 0) {
-
- if (parsingError || verbose) {
- // display the message in the console.
- if (parsingError) {
- AdtPlugin.printErrorToConsole(project, stdErr.toArray());
-
- // mark the project
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_AIDL,
- Messages.Unparsed_AIDL_Errors, IMarker.SEVERITY_ERROR);
- } else {
- AdtPlugin.printToConsole(project, stdErr.toArray());
- }
- }
- return false;
- }
- } else if (returnCode != 0) {
- // no stderr output but exec failed.
- String msg = String.format(Messages.AIDL_Exec_Error_d, returnCode);
-
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_AIDL,
- msg, IMarker.SEVERITY_ERROR);
-
- return false;
- }
- } catch (IOException e) {
- // mark the project and exit
- String msg = String.format(Messages.AIDL_Exec_Error_s, command[0]);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_AIDL, msg,
- IMarker.SEVERITY_ERROR);
- return false;
- } catch (InterruptedException e) {
- // mark the project and exit
- String msg = String.format(Messages.AIDL_Exec_Error_s, command[0]);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_AIDL, msg,
- IMarker.SEVERITY_ERROR);
- return false;
- }
-
- return true;
- }
-
- /**
- * Parse the output of aidl and mark the file with any errors.
- * @param lines The output to parse.
- * @param file The file to mark with error.
- * @return true if the parsing failed, false if success.
- */
- private boolean parseAidlOutput(ArrayList<String> lines, IFile file) {
- // nothing to parse? just return false;
- if (lines.size() == 0) {
- return false;
- }
-
- Matcher m;
-
- for (int i = 0; i < lines.size(); i++) {
- String p = lines.get(i);
-
- m = sAidlPattern1.matcher(p);
- if (m.matches()) {
- // we can ignore group 1 which is the location since we already
- // have a IFile object representing the aidl file.
- String lineStr = m.group(2);
- String msg = m.group(3);
-
- // get the line number
- int line = 0;
- try {
- line = Integer.parseInt(lineStr);
- } catch (NumberFormatException e) {
- // looks like the string we extracted wasn't a valid
- // file number. Parsing failed and we return true
- return true;
- }
-
- // mark the file
- BaseProjectHelper.markResource(file, AdtConstants.MARKER_AIDL, msg, line,
- IMarker.SEVERITY_ERROR);
-
- // success, go to the next line
- continue;
- }
-
- // invalid line format, flag as error, and bail
- return true;
- }
-
- return false;
- }
-
- /**
- * Returns the {@link IFile} handle to the destination file for a given aidl source file
- * ({@link AidlData}).
- * @param sourceFile The source file
- * @param outputFolder the top level output folder (not including the package folders)
- * @param createFolders whether or not the parent folder of the destination should be created
- * if it does not exist.
- * @param monitor the progress monitor
- * @return the handle to the destination file.
- * @throws CoreException
- */
- private IFile getAidlOutputFile(IFile sourceFile, IFolder outputFolder, boolean replaceExt,
- boolean createFolders, IProgressMonitor monitor) throws CoreException {
-
- IPath sourceFolderPath = getSourceFolderFor(sourceFile);
-
- // this really shouldn't happen since the sourceFile must be in a source folder
- // since it comes from the delta visitor
- if (sourceFolderPath != null) {
- // make a path to the source file relative to the source folder.
- IPath relative = sourceFile.getFullPath().makeRelativeTo(sourceFolderPath);
- // remove the file name. This is now the destination folder.
- relative = relative.removeLastSegments(1);
-
- // get an IFolder for this path.
- IFolder destinationFolder = outputFolder.getFolder(relative);
-
- // create it if needed.
- if (destinationFolder.exists() == false && createFolders) {
- createFolder(destinationFolder, monitor);
- }
-
- // Build the Java file name from the aidl name.
- String javaName;
- if (replaceExt) {
- javaName = sourceFile.getName().replaceAll(
- AdtConstants.RE_AIDL_EXT, SdkConstants.DOT_JAVA);
- } else {
- javaName = sourceFile.getName();
- }
-
- // get the resource for the java file.
- IFile javaFile = destinationFolder.getFile(javaName);
- return javaFile;
- }
-
- return null;
- }
-
- /**
- * Creates the destination folder. Because
- * {@link IFolder#create(boolean, boolean, IProgressMonitor)} only works if the parent folder
- * already exists, this goes and ensure that all the parent folders actually exist, or it
- * creates them as well.
- * @param destinationFolder The folder to create
- * @param monitor the {@link IProgressMonitor},
- * @throws CoreException
- */
- private void createFolder(IFolder destinationFolder, IProgressMonitor monitor)
- throws CoreException {
-
- // check the parent exist and create if necessary.
- IContainer parent = destinationFolder.getParent();
- if (parent.getType() == IResource.FOLDER && parent.exists() == false) {
- createFolder((IFolder)parent, monitor);
- }
-
- // create the folder.
- destinationFolder.create(true /*force*/, true /*local*/,
- new SubProgressMonitor(monitor, 10));
- }
-
- /**
- * Returns the type of the aidl file. Aidl files can either declare interfaces, or declare
- * parcelables. This method will attempt to parse the file and return the type. If the type
- * cannot be determined, then it will return {@link AidlType#UNKNOWN}.
- * @param file The aidl file
- * @return the type of the aidl.
- */
- private static AidlType getAidlType(IFile file) {
- // At this time, parsing isn't available, so we return UNKNOWN. This will force
- // a recompilation of all aidl file as soon as one is changed.
- return AidlType.UNKNOWN;
-
- // TODO: properly parse aidl file to determine type and generate dependency graphs.
-//
-// String className = file.getName().substring(0,
-// file.getName().length() - SdkConstants.DOT_AIDL.length());
-//
-// InputStream input = file.getContents(true /* force*/);
-// try {
-// BufferedReader reader = new BufferedReader(new InputStreateader(input));
-// String line;
-// while ((line = reader.readLine()) != null) {
-// if (line.length() == 0) {
-// continue;
-// }
-//
-// Matcher m = sParcelablePattern.matcher(line);
-// if (m.matches() && m.group(1).equals(className)) {
-// return AidlType.PARCELABLE;
-// }
-//
-// m = sInterfacePattern.matcher(line);
-// if (m.matches() && m.group(1).equals(className)) {
-// return AidlType.INTERFACE;
-// }
-// }
-// } catch (IOException e) {
-// throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-// "Error parsing aidl file", e));
-// } finally {
-// try {
-// input.close();
-// } catch (IOException e) {
-// throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
-// "Error parsing aidl file", e));
-// }
-// }
-//
-// return AidlType.UNKNOWN;
- }
-}
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
deleted file mode 100644
index 78d9d94e4..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- * 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.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-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.preferences.AdtPrefs;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-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.RenderScriptProcessor;
-import com.android.sdklib.build.SealedApkException;
-import com.android.sdklib.internal.build.DebugKeyProvider;
-import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException;
-import com.android.utils.GrabProcessOutput;
-import com.android.utils.GrabProcessOutput.IProcessOutput;
-import com.android.utils.GrabProcessOutput.Wait;
-import com.google.common.base.Charsets;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-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.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.IClasspathContainer;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jface.preference.IPreferenceStore;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-/**
- * Helper with methods for the last 3 steps of the generation of an APK.
- *
- * {@link #packageResources(IFile, IProject[], String, int, String, String)} packages the
- * application resources using aapt into a zip file that is ready to be integrated into the apk.
- *
- * {@link #executeDx(IJavaProject, String, String, IJavaProject[])} will convert the Java byte
- * code into the Dalvik bytecode.
- *
- * {@link #finalPackage(String, String, String, boolean, IJavaProject, IProject[], IJavaProject[], String, boolean)}
- * will make the apk from all the previous components.
- *
- * This class only executes the 3 above actions. It does not handle the errors, and simply sends
- * them back as custom exceptions.
- *
- * Warnings are handled by the {@link ResourceMarker} interface.
- *
- * Console output (verbose and non verbose) is handled through the {@link AndroidPrintStream} passed
- * to the constructor.
- *
- */
-public class BuildHelper {
-
- private static final String CONSOLE_PREFIX_DX = "Dx"; //$NON-NLS-1$
- private final static String TEMP_PREFIX = "android_"; //$NON-NLS-1$
-
- private static final String COMMAND_CRUNCH = "crunch"; //$NON-NLS-1$
- private static final String COMMAND_PACKAGE = "package"; //$NON-NLS-1$
-
- @NonNull
- private final ProjectState mProjectState;
- @NonNull
- private final IProject mProject;
- @NonNull
- private final BuildToolInfo mBuildToolInfo;
- @NonNull
- private final AndroidPrintStream mOutStream;
- @NonNull
- private final AndroidPrintStream mErrStream;
- private final boolean mForceJumbo;
- private final boolean mDisableDexMerger;
- private final boolean mVerbose;
- private final boolean mDebugMode;
-
- private final Set<String> mCompiledCodePaths = new HashSet<String>();
-
- public static final boolean BENCHMARK_FLAG = false;
- public static long sStartOverallTime = 0;
- public static long sStartJavaCTime = 0;
-
- private final static int MILLION = 1000000;
- private String mProguardFile;
-
- /**
- * An object able to put a marker on a resource.
- */
- public interface ResourceMarker {
- void setWarning(IResource resource, String message);
- }
-
- /**
- * Creates a new post-compiler helper
- * @param project
- * @param outStream
- * @param errStream
- * @param debugMode whether this is a debug build
- * @param verbose
- * @throws CoreException
- */
- public BuildHelper(@NonNull ProjectState projectState,
- @NonNull BuildToolInfo buildToolInfo,
- @NonNull AndroidPrintStream outStream,
- @NonNull AndroidPrintStream errStream,
- boolean forceJumbo, boolean disableDexMerger, boolean debugMode,
- boolean verbose, ResourceMarker resMarker) throws CoreException {
- mProjectState = projectState;
- mProject = projectState.getProject();
- mBuildToolInfo = buildToolInfo;
- mOutStream = outStream;
- mErrStream = errStream;
- mDebugMode = debugMode;
- mVerbose = verbose;
- mForceJumbo = forceJumbo;
- mDisableDexMerger = disableDexMerger;
-
- gatherPaths(resMarker);
- }
-
- public void updateCrunchCache() throws AaptExecException, AaptResultException {
- // Benchmarking start
- long startCrunchTime = 0;
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Starting Initial Packaging (.ap_)"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- startCrunchTime = System.nanoTime();
- }
-
- // Get the resources folder to crunch from
- IFolder resFolder = mProject.getFolder(AdtConstants.WS_RESOURCES);
- List<String> resPaths = new ArrayList<String>();
- resPaths.add(resFolder.getLocation().toOSString());
-
- // Get the output folder where the cache is stored.
- IFolder binFolder = BaseProjectHelper.getAndroidOutputFolder(mProject);
- IFolder cacheFolder = binFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_CRUNCHCACHE);
- String cachePath = cacheFolder.getLocation().toOSString();
-
- /* For crunching, we don't need the osManifestPath, osAssetsPath, or the configFilter
- * parameters for executeAapt
- */
- executeAapt(COMMAND_CRUNCH, "", resPaths, "", cachePath, "", 0);
-
- // Benchmarking end
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Ending Initial Package (.ap_). \nTime Elapsed: " //$NON-NLS-1$
- + ((System.nanoTime() - startCrunchTime)/MILLION) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- }
- }
-
- /**
- * Packages the resources of the projet into a .ap_ file.
- * @param manifestFile the manifest of the project.
- * @param libProjects the list of library projects that this project depends on.
- * @param resFilter an optional resource filter to be used with the -c option of aapt. If null
- * no filters are used.
- * @param versionCode an optional versionCode to be inserted in the manifest during packaging.
- * If the value is <=0, no values are inserted.
- * @param outputFolder where to write the resource ap_ file.
- * @param outputFilename the name of the resource ap_ file.
- * @throws AaptExecException
- * @throws AaptResultException
- */
- public void packageResources(IFile manifestFile, List<IProject> libProjects, String resFilter,
- int versionCode, String outputFolder, String outputFilename)
- throws AaptExecException, AaptResultException {
-
- // Benchmarking start
- long startPackageTime = 0;
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Starting Initial Packaging (.ap_)"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- startPackageTime = System.nanoTime();
- }
-
- // need to figure out some path before we can execute aapt;
- IFolder binFolder = BaseProjectHelper.getAndroidOutputFolder(mProject);
-
- // get the cache folder
- IFolder cacheFolder = binFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_CRUNCHCACHE);
-
- // get the BC folder
- IFolder bcFolder = binFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_BC);
-
- // get the resource folder
- IFolder resFolder = mProject.getFolder(AdtConstants.WS_RESOURCES);
-
- // and the assets folder
- IFolder assetsFolder = mProject.getFolder(AdtConstants.WS_ASSETS);
-
- // we need to make sure this one exists.
- if (assetsFolder.exists() == false) {
- assetsFolder = null;
- }
-
- // list of res folder (main project + maybe libraries)
- ArrayList<String> osResPaths = new ArrayList<String>();
-
- IPath resLocation = resFolder.getLocation();
- IPath manifestLocation = manifestFile.getLocation();
-
- if (resLocation != null && manifestLocation != null) {
-
- // png cache folder first.
- addFolderToList(osResPaths, cacheFolder);
- addFolderToList(osResPaths, bcFolder);
-
- // regular res folder next.
- osResPaths.add(resLocation.toOSString());
-
- // then libraries
- if (libProjects != null) {
- for (IProject lib : libProjects) {
- // png cache folder first
- IFolder libBinFolder = BaseProjectHelper.getAndroidOutputFolder(lib);
-
- IFolder libCacheFolder = libBinFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_CRUNCHCACHE);
- addFolderToList(osResPaths, libCacheFolder);
-
- IFolder libBcFolder = libBinFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_BC);
- addFolderToList(osResPaths, libBcFolder);
-
- // regular res folder next.
- IFolder libResFolder = lib.getFolder(AdtConstants.WS_RESOURCES);
- addFolderToList(osResPaths, libResFolder);
- }
- }
-
- String osManifestPath = manifestLocation.toOSString();
-
- String osAssetsPath = null;
- if (assetsFolder != null) {
- osAssetsPath = assetsFolder.getLocation().toOSString();
- }
-
- // build the default resource package
- executeAapt(COMMAND_PACKAGE, osManifestPath, osResPaths, osAssetsPath,
- outputFolder + File.separator + outputFilename, resFilter,
- versionCode);
- }
-
- // Benchmarking end
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Ending Initial Package (.ap_). \nTime Elapsed: " //$NON-NLS-1$
- + ((System.nanoTime() - startPackageTime)/MILLION) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- }
- }
-
- /**
- * Adds os path of a folder to a list only if the folder actually exists.
- * @param pathList
- * @param folder
- */
- private void addFolderToList(List<String> pathList, IFolder folder) {
- // use a File instead of the IFolder API to ignore workspace refresh issue.
- File testFile = new File(folder.getLocation().toOSString());
- if (testFile.isDirectory()) {
- pathList.add(testFile.getAbsolutePath());
- }
- }
-
- /**
- * Makes a final package signed with the debug key.
- *
- * Packages the dex files, the temporary resource file into the final package file.
- *
- * Whether the package is a debug package is controlled with the <var>debugMode</var> parameter
- * in {@link #PostCompilerHelper(IProject, PrintStream, PrintStream, boolean, boolean)}
- *
- * @param intermediateApk The path to the temporary resource file.
- * @param dex The path to the dex file.
- * @param output The path to the final package file to create.
- * @param libProjects an optional list of library projects (can be null)
- * @return true if success, false otherwise.
- * @throws ApkCreationException
- * @throws AndroidLocationException
- * @throws KeytoolException
- * @throws NativeLibInJarException
- * @throws CoreException
- * @throws DuplicateFileException
- */
- public void finalDebugPackage(String intermediateApk, String dex, String output,
- List<IProject> libProjects, ResourceMarker resMarker)
- throws ApkCreationException, KeytoolException, AndroidLocationException,
- NativeLibInJarException, DuplicateFileException, CoreException {
-
- AdtPlugin adt = AdtPlugin.getDefault();
- if (adt == null) {
- return;
- }
-
- // get the debug keystore to use.
- IPreferenceStore store = adt.getPreferenceStore();
- String keystoreOsPath = store.getString(AdtPrefs.PREFS_CUSTOM_DEBUG_KEYSTORE);
- if (keystoreOsPath == null || new File(keystoreOsPath).isFile() == false) {
- keystoreOsPath = DebugKeyProvider.getDefaultKeyStoreOsPath();
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, mProject,
- Messages.ApkBuilder_Using_Default_Key);
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, mProject,
- String.format(Messages.ApkBuilder_Using_s_To_Sign, keystoreOsPath));
- }
-
- // from the keystore, get the signing info
- SigningInfo info = ApkBuilder.getDebugKey(keystoreOsPath, mVerbose ? mOutStream : null);
-
- finalPackage(intermediateApk, dex, output, libProjects,
- info != null ? info.key : null, info != null ? info.certificate : null, resMarker);
- }
-
- /**
- * Makes the final package.
- *
- * Packages the dex files, the temporary resource file into the final package file.
- *
- * Whether the package is a debug package is controlled with the <var>debugMode</var> parameter
- * in {@link #PostCompilerHelper(IProject, PrintStream, PrintStream, boolean, boolean)}
- *
- * @param intermediateApk The path to the temporary resource file.
- * @param dex The path to the dex file.
- * @param output The path to the final package file to create.
- * @param debugSign whether the apk must be signed with the debug key.
- * @param libProjects an optional list of library projects (can be null)
- * @param abiFilter an optional filter. If not null, then only the matching ABI is included in
- * the final archive
- * @return true if success, false otherwise.
- * @throws NativeLibInJarException
- * @throws ApkCreationException
- * @throws CoreException
- * @throws DuplicateFileException
- */
- public void finalPackage(String intermediateApk, String dex, String output,
- List<IProject> libProjects,
- PrivateKey key, X509Certificate certificate, ResourceMarker resMarker)
- throws NativeLibInJarException, ApkCreationException, DuplicateFileException,
- CoreException {
-
- try {
- ApkBuilder apkBuilder = new ApkBuilder(output, intermediateApk, dex,
- key, certificate,
- mVerbose ? mOutStream: null);
- apkBuilder.setDebugMode(mDebugMode);
-
- // either use the full compiled code paths or just the proguard file
- // if present
- Collection<String> pathsCollection = mCompiledCodePaths;
- if (mProguardFile != null) {
- pathsCollection = Collections.singletonList(mProguardFile);
- mProguardFile = null;
- }
-
- // Now we write the standard resources from all the output paths.
- for (String path : pathsCollection) {
- File file = new File(path);
- if (file.isFile()) {
- JarStatus jarStatus = apkBuilder.addResourcesFromJar(file);
-
- // check if we found native libraries in the external library. This
- // constitutes an error or warning depending on if they are in lib/
- if (jarStatus.getNativeLibs().size() > 0) {
- String libName = file.getName();
-
- String msg = String.format(
- "Native libraries detected in '%1$s'. See console for more information.",
- libName);
-
- ArrayList<String> consoleMsgs = new ArrayList<String>();
-
- consoleMsgs.add(String.format(
- "The library '%1$s' contains native libraries that will not run on the device.",
- libName));
-
- if (jarStatus.hasNativeLibsConflicts()) {
- consoleMsgs.add("Additionally some of those libraries will interfer with the installation of the application because of their location in lib/");
- consoleMsgs.add("lib/ is reserved for NDK libraries.");
- }
-
- consoleMsgs.add("The following libraries were found:");
-
- for (String lib : jarStatus.getNativeLibs()) {
- consoleMsgs.add(" - " + lib);
- }
-
- String[] consoleStrings = consoleMsgs.toArray(new String[consoleMsgs.size()]);
-
- // if there's a conflict or if the prefs force error on any native code in jar
- // files, throw an exception
- if (jarStatus.hasNativeLibsConflicts() ||
- AdtPrefs.getPrefs().getBuildForceErrorOnNativeLibInJar()) {
- throw new NativeLibInJarException(jarStatus, msg, libName, consoleStrings);
- } else {
- // otherwise, put a warning, and output to the console also.
- if (resMarker != null) {
- resMarker.setWarning(mProject, msg);
- }
-
- for (String string : consoleStrings) {
- mOutStream.println(string);
- }
- }
- }
- } else if (file.isDirectory()) {
- // this is technically not a source folder (class folder instead) but since we
- // only care about Java resources (ie non class/java files) this will do the
- // same
- apkBuilder.addSourceFolder(file);
- }
- }
-
- // now write the native libraries.
- // First look if the lib folder is there.
- IResource libFolder = mProject.findMember(SdkConstants.FD_NATIVE_LIBS);
- if (libFolder != null && libFolder.exists() &&
- libFolder.getType() == IResource.FOLDER) {
- // get a File for the folder.
- apkBuilder.addNativeLibraries(libFolder.getLocation().toFile());
- }
-
- // next the native libraries for the renderscript support mode.
- if (mProjectState.getRenderScriptSupportMode()) {
- IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(mProject);
- IResource rsLibFolder = androidOutputFolder.getFolder(
- AdtConstants.WS_BIN_RELATIVE_RS_LIBS);
- File rsLibFolderFile = rsLibFolder.getLocation().toFile();
- if (rsLibFolderFile.isDirectory()) {
- apkBuilder.addNativeLibraries(rsLibFolderFile);
- }
-
- File rsLibs = RenderScriptProcessor.getSupportNativeLibFolder(
- mBuildToolInfo.getLocation().getAbsolutePath());
- if (rsLibs.isDirectory()) {
- apkBuilder.addNativeLibraries(rsLibs);
- }
- }
-
- // write the native libraries for the library projects.
- if (libProjects != null) {
- for (IProject lib : libProjects) {
- libFolder = lib.findMember(SdkConstants.FD_NATIVE_LIBS);
- if (libFolder != null && libFolder.exists() &&
- libFolder.getType() == IResource.FOLDER) {
- apkBuilder.addNativeLibraries(libFolder.getLocation().toFile());
- }
- }
- }
-
- // seal the APK.
- apkBuilder.sealApk();
- } catch (SealedApkException e) {
- // this won't happen as we control when the apk is sealed.
- }
- }
-
- public void setProguardOutput(String proguardFile) {
- mProguardFile = proguardFile;
- }
-
- public Collection<String> getCompiledCodePaths() {
- return mCompiledCodePaths;
- }
-
- public void runProguard(List<File> proguardConfigs, File inputJar, Collection<String> jarFiles,
- File obfuscatedJar, File logOutput)
- throws ProguardResultException, ProguardExecException, IOException {
- IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
-
- // prepare the command line for proguard
- List<String> command = new ArrayList<String>();
- command.add(AdtPlugin.getOsAbsoluteProguard());
-
- for (File configFile : proguardConfigs) {
- command.add("-include"); //$NON-NLS-1$
- command.add(quotePath(configFile.getAbsolutePath()));
- }
-
- command.add("-injars"); //$NON-NLS-1$
- StringBuilder sb = new StringBuilder(quotePath(inputJar.getAbsolutePath()));
- for (String jarFile : jarFiles) {
- sb.append(File.pathSeparatorChar);
- sb.append(quotePath(jarFile));
- }
- command.add(quoteWinArg(sb.toString()));
-
- command.add("-outjars"); //$NON-NLS-1$
- command.add(quotePath(obfuscatedJar.getAbsolutePath()));
-
- command.add("-libraryjars"); //$NON-NLS-1$
- sb = new StringBuilder(quotePath(target.getPath(IAndroidTarget.ANDROID_JAR)));
- IOptionalLibrary[] libraries = target.getOptionalLibraries();
- if (libraries != null) {
- for (IOptionalLibrary lib : libraries) {
- sb.append(File.pathSeparatorChar);
- sb.append(quotePath(lib.getJarPath()));
- }
- }
- command.add(quoteWinArg(sb.toString()));
-
- if (logOutput != null) {
- if (logOutput.isDirectory() == false) {
- logOutput.mkdirs();
- }
-
- command.add("-dump"); //$NON-NLS-1$
- command.add(new File(logOutput, "dump.txt").getAbsolutePath()); //$NON-NLS-1$
-
- command.add("-printseeds"); //$NON-NLS-1$
- command.add(new File(logOutput, "seeds.txt").getAbsolutePath()); //$NON-NLS-1$
-
- command.add("-printusage"); //$NON-NLS-1$
- command.add(new File(logOutput, "usage.txt").getAbsolutePath()); //$NON-NLS-1$
-
- command.add("-printmapping"); //$NON-NLS-1$
- command.add(new File(logOutput, "mapping.txt").getAbsolutePath()); //$NON-NLS-1$
- }
-
- String commandArray[] = null;
-
- if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- commandArray = createWindowsProguardConfig(command);
- }
-
- if (commandArray == null) {
- // For Mac & Linux, use a regular command string array.
- commandArray = command.toArray(new String[command.size()]);
- }
-
- // Define PROGUARD_HOME to point to $SDK/tools/proguard if it's not yet defined.
- // The Mac/Linux proguard.sh can infer it correctly but not the proguard.bat one.
- String[] envp = null;
- Map<String, String> envMap = new TreeMap<String, String>(System.getenv());
- if (!envMap.containsKey("PROGUARD_HOME")) { //$NON-NLS-1$
- envMap.put("PROGUARD_HOME", Sdk.getCurrent().getSdkOsLocation() + //$NON-NLS-1$
- SdkConstants.FD_TOOLS + File.separator +
- SdkConstants.FD_PROGUARD);
- envp = new String[envMap.size()];
- int i = 0;
- for (Map.Entry<String, String> entry : envMap.entrySet()) {
- envp[i++] = String.format("%1$s=%2$s", //$NON-NLS-1$
- entry.getKey(),
- entry.getValue());
- }
- }
-
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
- sb = new StringBuilder();
- for (String c : commandArray) {
- sb.append(c).append(' ');
- }
- AdtPlugin.printToConsole(mProject, sb.toString());
- }
-
- // launch
- int execError = 1;
- try {
- // launch the command line process
- Process process = Runtime.getRuntime().exec(commandArray, envp);
-
- // list to store each line of stderr
- ArrayList<String> results = new ArrayList<String>();
-
- // get the output and return code from the process
- execError = grabProcessOutput(mProject, process, results);
-
- if (mVerbose) {
- for (String resultString : results) {
- mOutStream.println(resultString);
- }
- }
-
- if (execError != 0) {
- throw new ProguardResultException(execError,
- results.toArray(new String[results.size()]));
- }
-
- } catch (IOException e) {
- String msg = String.format(Messages.Proguard_Exec_Error, commandArray[0]);
- throw new ProguardExecException(msg, e);
- } catch (InterruptedException e) {
- String msg = String.format(Messages.Proguard_Exec_Error, commandArray[0]);
- throw new ProguardExecException(msg, e);
- }
- }
-
- /**
- * For tools R8 up to R11, the proguard.bat launcher on Windows only accepts
- * arguments %1..%9. Since we generally have about 15 arguments, we were working
- * around this by generating a temporary config file for proguard and then using
- * that.
- * Starting with tools R12, the proguard.bat launcher has been fixed to take
- * all arguments using %* so we no longer need this hack.
- *
- * @param command
- * @return
- * @throws IOException
- */
- private String[] createWindowsProguardConfig(List<String> command) throws IOException {
-
- // Arg 0 is the proguard.bat path and arg 1 is the user config file
- String launcher = AdtPlugin.readFile(new File(command.get(0)));
- if (launcher.contains("%*")) { //$NON-NLS-1$
- // This is the launcher from Tools R12. Don't work around it.
- return null;
- }
-
- // On Windows, proguard.bat can only pass %1...%9 to the java -jar proguard.jar
- // call, but we have at least 15 arguments here so some get dropped silently
- // and quoting is a big issue. So instead we'll work around that by writing
- // all the arguments to a temporary config file.
-
- String[] commandArray = new String[3];
-
- commandArray[0] = command.get(0);
- commandArray[1] = command.get(1);
-
- // Write all the other arguments to a config file
- File argsFile = File.createTempFile(TEMP_PREFIX, ".pro"); //$NON-NLS-1$
- // TODO FIXME this may leave a lot of temp files around on a long session.
- // Should have a better way to clean up e.g. before each build.
- argsFile.deleteOnExit();
-
- FileWriter fw = new FileWriter(argsFile);
-
- for (int i = 2; i < command.size(); i++) {
- String s = command.get(i);
- fw.write(s);
- fw.write(s.startsWith("-") ? ' ' : '\n'); //$NON-NLS-1$
- }
-
- fw.close();
-
- commandArray[2] = "@" + argsFile.getAbsolutePath(); //$NON-NLS-1$
- return commandArray;
- }
-
- /**
- * Quotes a single path for proguard to deal with spaces.
- *
- * @param path The path to quote.
- * @return The original path if it doesn't contain a space.
- * Or the original path surrounded by single quotes if it contains spaces.
- */
- private String quotePath(String path) {
- if (path.indexOf(' ') != -1) {
- path = '\'' + path + '\'';
- }
- return path;
- }
-
- /**
- * Quotes a compound proguard argument to deal with spaces.
- * <p/>
- * Proguard takes multi-path arguments such as "path1;path2" for some options.
- * When the {@link #quotePath} methods adds quotes for such a path if it contains spaces,
- * the proguard shell wrapper will absorb the quotes, so we need to quote around the
- * quotes.
- *
- * @param path The path to quote.
- * @return The original path if it doesn't contain a single quote.
- * Or on Windows the original path surrounded by double quotes if it contains a quote.
- */
- private String quoteWinArg(String path) {
- if (path.indexOf('\'') != -1 &&
- SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) {
- path = '"' + path + '"';
- }
- return path;
- }
-
-
- /**
- * Execute the Dx tool for dalvik code conversion.
- * @param javaProject The java project
- * @param inputPaths the input paths for DX
- * @param osOutFilePath the path of the dex file to create.
- *
- * @throws CoreException
- * @throws DexException
- */
- public void executeDx(IJavaProject javaProject, Collection<String> inputPaths,
- String osOutFilePath)
- throws CoreException, DexException {
-
- // get the dex wrapper
- Sdk sdk = Sdk.getCurrent();
- DexWrapper wrapper = sdk.getDexWrapper(mBuildToolInfo);
-
- if (wrapper == null) {
- throw new CoreException(new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
- Messages.ApkBuilder_UnableBuild_Dex_Not_loaded));
- }
-
- try {
- // set a temporary prefix on the print streams.
- mOutStream.setPrefix(CONSOLE_PREFIX_DX);
- mErrStream.setPrefix(CONSOLE_PREFIX_DX);
-
- IFolder binFolder = BaseProjectHelper.getAndroidOutputFolder(javaProject.getProject());
- File binFile = binFolder.getLocation().toFile();
- File dexedLibs = new File(binFile, "dexedLibs");
- if (dexedLibs.exists() == false) {
- dexedLibs.mkdir();
- }
-
- // replace the libs by their dexed versions (dexing them if needed.)
- List<String> finalInputPaths = new ArrayList<String>(inputPaths.size());
- if (mDisableDexMerger || inputPaths.size() == 1) {
- // only one input, no need to put a pre-dexed version, even if this path is
- // just a jar file (case for proguard'ed builds)
- finalInputPaths.addAll(inputPaths);
- } else {
-
- for (String input : inputPaths) {
- File inputFile = new File(input);
- if (inputFile.isDirectory()) {
- finalInputPaths.add(input);
- } else if (inputFile.isFile()) {
- String fileName = getDexFileName(inputFile);
-
- File dexedLib = new File(dexedLibs, fileName);
- String dexedLibPath = dexedLib.getAbsolutePath();
-
- if (dexedLib.isFile() == false ||
- dexedLib.lastModified() < inputFile.lastModified()) {
-
- if (mVerbose) {
- mOutStream.println(
- String.format("Pre-Dexing %1$s -> %2$s", input, fileName));
- }
-
- if (dexedLib.isFile()) {
- dexedLib.delete();
- }
-
- int res = wrapper.run(dexedLibPath, Collections.singleton(input),
- mForceJumbo, mVerbose, mOutStream, mErrStream);
-
- if (res != 0) {
- // output error message and mark the project.
- String message = String.format(Messages.Dalvik_Error_d, res);
- throw new DexException(message);
- }
- } else {
- if (mVerbose) {
- mOutStream.println(
- String.format("Using Pre-Dexed %1$s <- %2$s",
- fileName, input));
- }
- }
-
- finalInputPaths.add(dexedLibPath);
- }
- }
- }
-
- if (mVerbose) {
- for (String input : finalInputPaths) {
- mOutStream.println("Input: " + input);
- }
- }
-
- int res = wrapper.run(osOutFilePath,
- finalInputPaths,
- mForceJumbo,
- mVerbose,
- mOutStream, mErrStream);
-
- mOutStream.setPrefix(null);
- mErrStream.setPrefix(null);
-
- if (res != 0) {
- // output error message and marker the project.
- String message = String.format(Messages.Dalvik_Error_d, res);
- throw new DexException(message);
- }
- } catch (DexException e) {
- throw e;
- } catch (Throwable t) {
- String message = t.getMessage();
- if (message == null) {
- message = t.getClass().getCanonicalName();
- }
- message = String.format(Messages.Dalvik_Error_s, message);
-
- throw new DexException(message, t);
- }
- }
-
- private String getDexFileName(File inputFile) {
- // get the filename
- String name = inputFile.getName();
- // remove the extension
- int pos = name.lastIndexOf('.');
- if (pos != -1) {
- name = name.substring(0, pos);
- }
-
- // add a hash of the original file path
- HashFunction hashFunction = Hashing.md5();
- HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charsets.UTF_8);
-
- return name + "-" + hashCode.toString() + ".jar";
- }
-
- /**
- * Executes aapt. If any error happen, files or the project will be marked.
- * @param command The command for aapt to execute. Currently supported: package and crunch
- * @param osManifestPath The path to the manifest file
- * @param osResPath The path to the res folder
- * @param osAssetsPath The path to the assets folder. This can be null.
- * @param osOutFilePath The path to the temporary resource file to create,
- * or in the case of crunching the path to the cache to create/update.
- * @param configFilter The configuration filter for the resources to include
- * (used with -c option, for example "port,en,fr" to include portrait, English and French
- * resources.)
- * @param versionCode optional version code to insert in the manifest during packaging. If <=0
- * then no value is inserted
- * @throws AaptExecException
- * @throws AaptResultException
- */
- private void executeAapt(String aaptCommand, String osManifestPath,
- List<String> osResPaths, String osAssetsPath, String osOutFilePath,
- String configFilter, int versionCode) throws AaptExecException, AaptResultException {
- IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
-
- String aapt = mBuildToolInfo.getPath(BuildToolInfo.PathId.AAPT);
-
- // Create the command line.
- ArrayList<String> commandArray = new ArrayList<String>();
- commandArray.add(aapt);
- commandArray.add(aaptCommand);
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
- commandArray.add("-v"); //$NON-NLS-1$
- }
-
- // Common to all commands
- for (String path : osResPaths) {
- commandArray.add("-S"); //$NON-NLS-1$
- commandArray.add(path);
- }
-
- if (aaptCommand.equals(COMMAND_PACKAGE)) {
- commandArray.add("-f"); //$NON-NLS-1$
- commandArray.add("--no-crunch"); //$NON-NLS-1$
-
- // if more than one res, this means there's a library (or more) and we need
- // to activate the auto-add-overlay
- if (osResPaths.size() > 1) {
- commandArray.add("--auto-add-overlay"); //$NON-NLS-1$
- }
-
- if (mDebugMode) {
- commandArray.add("--debug-mode"); //$NON-NLS-1$
- }
-
- if (versionCode > 0) {
- commandArray.add("--version-code"); //$NON-NLS-1$
- commandArray.add(Integer.toString(versionCode));
- }
-
- if (configFilter != null) {
- commandArray.add("-c"); //$NON-NLS-1$
- commandArray.add(configFilter);
- }
-
- // never compress apks.
- commandArray.add("-0");
- commandArray.add("apk");
-
- commandArray.add("-M"); //$NON-NLS-1$
- commandArray.add(osManifestPath);
-
- if (osAssetsPath != null) {
- commandArray.add("-A"); //$NON-NLS-1$
- commandArray.add(osAssetsPath);
- }
-
- commandArray.add("-I"); //$NON-NLS-1$
- commandArray.add(target.getPath(IAndroidTarget.ANDROID_JAR));
-
- commandArray.add("-F"); //$NON-NLS-1$
- commandArray.add(osOutFilePath);
- } else if (aaptCommand.equals(COMMAND_CRUNCH)) {
- commandArray.add("-C"); //$NON-NLS-1$
- commandArray.add(osOutFilePath);
- }
-
- String command[] = commandArray.toArray(
- new String[commandArray.size()]);
-
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
- StringBuilder sb = new StringBuilder();
- for (String c : command) {
- sb.append(c);
- sb.append(' ');
- }
- AdtPlugin.printToConsole(mProject, sb.toString());
- }
-
- // Benchmarking start
- long startAaptTime = 0;
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Starting " + aaptCommand //$NON-NLS-1$
- + " call to Aapt"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- startAaptTime = System.nanoTime();
- }
-
- // launch
- try {
- // launch the command line process
- Process process = Runtime.getRuntime().exec(command);
-
- // list to store each line of stderr
- ArrayList<String> stdErr = new ArrayList<String>();
-
- // get the output and return code from the process
- int returnCode = grabProcessOutput(mProject, process, stdErr);
-
- if (mVerbose) {
- for (String stdErrString : stdErr) {
- mOutStream.println(stdErrString);
- }
- }
- if (returnCode != 0) {
- throw new AaptResultException(returnCode,
- stdErr.toArray(new String[stdErr.size()]));
- }
- } catch (IOException e) {
- String msg = String.format(Messages.AAPT_Exec_Error_s, command[0]);
- throw new AaptExecException(msg, e);
- } catch (InterruptedException e) {
- String msg = String.format(Messages.AAPT_Exec_Error_s, command[0]);
- throw new AaptExecException(msg, e);
- }
-
- // Benchmarking end
- if (BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Ending " + aaptCommand //$NON-NLS-1$
- + " call to Aapt.\nBENCHMARK ADT: Time Elapsed: " //$NON-NLS-1$
- + ((System.nanoTime() - startAaptTime)/MILLION) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, mProject, msg);
- }
- }
-
- /**
- * Computes all the project output and dependencies that must go into building the apk.
- *
- * @param resMarker
- * @throws CoreException
- */
- private void gatherPaths(ResourceMarker resMarker)
- throws CoreException {
- IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
-
- // get a java project for the project.
- IJavaProject javaProject = JavaCore.create(mProject);
-
-
- // get the output of the main project
- IPath path = javaProject.getOutputLocation();
- IResource outputResource = wsRoot.findMember(path);
- if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
- mCompiledCodePaths.add(outputResource.getLocation().toOSString());
- }
-
- // 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) {
- // ignore non exported entries, unless they're in the DEPEDENCIES container,
- // in which case we always want it (there may be some older projects that
- // have it as non exported).
- if (e.isExported() ||
- (e.getEntryKind() == IClasspathEntry.CPE_CONTAINER &&
- e.getPath().toString().equals(AdtConstants.CONTAINER_DEPENDENCIES))) {
- handleCPE(e, javaProject, wsRoot, resMarker);
- }
- }
- }
- }
-
- private void handleCPE(IClasspathEntry entry, IJavaProject javaProject,
- IWorkspaceRoot wsRoot, ResourceMarker resMarker) {
-
- // if this is a classpath variable reference, we resolve it.
- if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
- entry = JavaCore.getResolvedClasspathEntry(entry);
- }
-
- if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
- IProject refProject = wsRoot.getProject(entry.getPath().lastSegment());
- try {
- // ignore if it's an Android project, or if it's not a Java Project
- if (refProject.hasNature(JavaCore.NATURE_ID) &&
- refProject.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
- IJavaProject refJavaProject = JavaCore.create(refProject);
-
- // get the output folder
- IPath path = refJavaProject.getOutputLocation();
- IResource outputResource = wsRoot.findMember(path);
- if (outputResource != null && outputResource.getType() == IResource.FOLDER) {
- mCompiledCodePaths.add(outputResource.getLocation().toOSString());
- }
- }
- } catch (CoreException exception) {
- // can't query the project nature? ignore
- }
-
- } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
- handleClasspathLibrary(entry, wsRoot, resMarker);
- } else if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
- // get the container
- try {
- IClasspathContainer container = JavaCore.getClasspathContainer(
- entry.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 cpe : entries) {
- handleCPE(cpe, javaProject, wsRoot, resMarker);
- }
- }
- } catch (JavaModelException jme) {
- // can't resolve the container? ignore it.
- AdtPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", entry.getPath());
- }
- }
- }
-
- private void handleClasspathLibrary(IClasspathEntry e, IWorkspaceRoot wsRoot,
- ResourceMarker resMarker) {
- // get the IPath
- IPath path = e.getPath();
-
- IResource resource = wsRoot.findMember(path);
-
- 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 (SdkConstants.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) {
- mCompiledCodePaths.add(resource.getLocation().toOSString());
- } 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 File(osFullPath);
- if (f.isFile()) {
- mCompiledCodePaths.add(osFullPath);
- } else {
- String message = String.format( Messages.Couldnt_Locate_s_Error,
- path);
- // always output to the console
- mOutStream.println(message);
-
- // put a marker
- if (resMarker != null) {
- resMarker.setWarning(mProject, message);
- }
- }
- }
- } else {
- // this can be the case for a class folder.
- if (resource != null && resource.exists() &&
- resource.getType() == IResource.FOLDER) {
- mCompiledCodePaths.add(resource.getLocation().toOSString());
- } else {
- // if the path doesn't match a workspace resource,
- // then we get an OSString and check if this links to a valid folder.
- String osFullPath = path.toOSString();
-
- File f = new File(osFullPath);
- if (f.isDirectory()) {
- mCompiledCodePaths.add(osFullPath);
- }
- }
- }
- }
-
- /**
- * Checks a {@link IFile} to make sure it should be packaged as standard resources.
- * @param file the IFile representing the file.
- * @return true if the file should be packaged as standard java resources.
- */
- public static boolean checkFileForPackaging(IFile file) {
- String name = file.getName();
-
- String ext = file.getFileExtension();
- return ApkBuilder.checkFileForPackaging(name, ext);
- }
-
- /**
- * Checks whether an {@link IFolder} and its content is valid for packaging into the .apk as
- * standard Java resource.
- * @param folder the {@link IFolder} to check.
- */
- public static boolean checkFolderForPackaging(IFolder folder) {
- String name = folder.getName();
- return ApkBuilder.checkFolderForPackaging(name);
- }
-
- /**
- * Returns a list of {@link IJavaProject} matching the provided {@link IProject} objects.
- * @param projects the IProject objects.
- * @return a new list object containing the IJavaProject object for the given IProject objects.
- * @throws CoreException
- */
- public static List<IJavaProject> getJavaProjects(List<IProject> projects) throws CoreException {
- ArrayList<IJavaProject> list = new ArrayList<IJavaProject>();
-
- for (IProject p : projects) {
- if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) {
-
- list.add(JavaCore.create(p));
- }
- }
-
- return list;
- }
-
- /**
- * Get the stderr output of a process and return when the process is done.
- * @param process The process to get the output from
- * @param stderr The array to store the stderr output
- * @return the process return code.
- * @throws InterruptedException
- */
- public final static int grabProcessOutput(
- final IProject project,
- final Process process,
- final ArrayList<String> stderr)
- throws InterruptedException {
-
- return GrabProcessOutput.grabProcessOutput(
- process,
- Wait.WAIT_FOR_READERS, // we really want to make sure we get all the output!
- new IProcessOutput() {
-
- @SuppressWarnings("unused")
- @Override
- public void out(@Nullable String line) {
- if (line != null) {
- // If benchmarking always print the lines that
- // correspond to benchmarking info returned by ADT
- if (BENCHMARK_FLAG && line.startsWith("BENCHMARK:")) { //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS,
- project, line);
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE,
- project, line);
- }
- }
- }
-
- @Override
- public void err(@Nullable String line) {
- if (line != null) {
- stderr.add(line);
- if (BuildVerbosity.VERBOSE == AdtPrefs.getPrefs().getBuildVerbosity()) {
- AdtPlugin.printErrorToConsole(project, line);
- }
- }
- }
- });
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchDialog.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchDialog.java
deleted file mode 100644
index 20bee5dac..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchDialog.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2011 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.ide.eclipse.adt.internal.editors.IconFactory;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.browser.IWebBrowser;
-
-import java.net.URL;
-
-/**
- * Dialog shown by the {@link ConvertSwitchQuickFixProcessor}. This is a custom
- * dialog rather than a plain {@link MessageDialog} such that we can show a link
- * and point to a web page for more info.
- */
-class ConvertSwitchDialog extends TitleAreaDialog implements SelectionListener {
- /** URL containing more info */
- private static final String URL = "http://tools.android.com/tips/non-constant-fields"; //$NON-NLS-1$
-
- private final String mField;
-
- private Link mLink;
-
- /**
- * Create the dialog.
- * @param parentShell the parent shell
- * @param field the field name we're warning about
- */
- public ConvertSwitchDialog(Shell parentShell, String field) {
- super(parentShell);
- mField = field;
- Image image = IconFactory.getInstance().getIcon("android-64"); //$NON-NLS-1$
- setTitleImage(image);
- }
-
- @Override
- protected Control createDialogArea(Composite parent) {
- String text = String.format(
- "As of ADT 14, the resource fields (such as %1$s) are no longer constants " +
- "when defined in library projects. This is necessary to make library " +
- "projects reusable without recompiling them.\n" +
- "\n" +
- "One consequence of this is that you can no longer use the fields directly " +
- "in switch statements. You must use an if-else chain instead.\n" +
- "\n" +
- "Eclipse can automatically convert from a switch statement to an if-else " +
- "statement. Just place the caret on the switch keyword and invoke " +
- "Quick Fix (Ctrl-1 on Windows and Linux, Cmd-1 on Mac), then select " +
- "\"Convert 'switch' to 'if-else'\".\n" +
- "\n" +
- "For more information, see <a href=\"" + URL + "\">" + URL + "</a>",
- mField);
-
- Composite area = (Composite) super.createDialogArea(parent);
- Composite container = new Composite(area, SWT.NONE);
- container.setLayout(new GridLayout(1, false));
- container.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- mLink = new Link(container, SWT.NONE);
- mLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));
- mLink.setText(text);
- mLink.addSelectionListener(this);
-
- setMessage("Non-Constant Expressions: Migration Necessary", IMessageProvider.INFORMATION);
-
- return area;
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
- createButton(parent, IDialogConstants.HELP_ID, IDialogConstants.HELP_LABEL, false);
- }
-
- @Override
- protected Point getInitialSize() {
- return new Point(500, 400);
- }
-
- private void showWebPage() {
- try {
- IWorkbench workbench = PlatformUI.getWorkbench();
- IWebBrowser browser = workbench.getBrowserSupport().getExternalBrowser();
- browser.openURL(new URL(URL));
- } catch (Exception e) {
- String message = String.format("Could not open browser. Vist\n%1$s\ninstead.",
- URL);
- MessageDialog.openError(getShell(), "Browser Error", message);
- }
-
- }
-
- @Override
- protected void buttonPressed(int buttonId) {
- if (buttonId == IDialogConstants.HELP_ID) {
- showWebPage();
- } else {
- super.buttonPressed(buttonId);
- }
- }
-
- // ---- Implements SelectionListener ----
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (e.getSource() == mLink) {
- showWebPage();
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchQuickFixProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchQuickFixProcessor.java
deleted file mode 100644
index a99dc7601..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ConvertSwitchQuickFixProcessor.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2011 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.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.AdtUtils;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IBuffer;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.QualifiedName;
-import org.eclipse.jdt.ui.text.java.IInvocationContext;
-import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
-import org.eclipse.jdt.ui.text.java.IProblemLocation;
-import org.eclipse.jdt.ui.text.java.IQuickFixProcessor;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.contentassist.IContextInformation;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.editors.text.TextFileDocumentProvider;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-
-import java.util.List;
-
-/**
- * A quickfix processor which looks for "case expressions must be constant
- * expressions" errors, and if they apply to fields in a class named R, it
- * assumes this is code related to library projects that are no longer final and
- * will need to be rewritten to use if-else chains instead.
- */
-public class ConvertSwitchQuickFixProcessor implements IQuickFixProcessor {
- /** Constructs a new {@link ConvertSwitchQuickFixProcessor} */
- public ConvertSwitchQuickFixProcessor() {
- }
-
- @Override
- public boolean hasCorrections(ICompilationUnit cu, int problemId) {
- return problemId == IProblem.NonConstantExpression;
- }
-
- @Override
- public IJavaCompletionProposal[] getCorrections(IInvocationContext context,
- IProblemLocation[] location) throws CoreException {
- if (location == null || location.length == 0) {
- return null;
- }
- ASTNode coveringNode = context.getCoveringNode();
- if (coveringNode == null) {
- return null;
- }
-
- // Look up the fully qualified name of the non-constant expression, if any, and
- // make sure it's R-something.
- if (coveringNode.getNodeType() == ASTNode.SIMPLE_NAME) {
- coveringNode = coveringNode.getParent();
- if (coveringNode == null) {
- return null;
- }
- }
- if (coveringNode.getNodeType() != ASTNode.QUALIFIED_NAME) {
- return null;
- }
- QualifiedName name = (QualifiedName) coveringNode;
- if (!name.getFullyQualifiedName().startsWith("R.")) { //$NON-NLS-1$
- return null;
- }
-
- IProblemLocation error = location[0];
- int errorStart = error.getOffset();
- int errorLength = error.getLength();
- int caret = context.getSelectionOffset();
-
- // Even though the hasCorrections() method above will return false for everything
- // other than non-constant expression errors, it turns out this getCorrections()
- // method will ALSO be called on lines where there is no such error. In particular,
- // if you have an invalid cast expression like this:
- // Button button = findViewById(R.id.textView);
- // then this method will be called, and the expression will pass all of the above
- // checks. However, we -don't- want to show a migrate code suggestion in that case!
- // Therefore, we'll need to check if we're *actually* on a line with the given
- // problem.
- //
- // Unfortunately, we don't get passed the problemId again, and there's no access
- // to it. So instead we'll need to look up the markers on the line, and see
- // if we actually have a constant expression warning. This is not pretty!!
-
- boolean foundError = false;
- ICompilationUnit compilationUnit = context.getCompilationUnit();
- IResource file = compilationUnit.getResource();
- if (file != null) {
- IDocumentProvider provider = new TextFileDocumentProvider();
- try {
- provider.connect(file);
- IDocument document = provider.getDocument(file);
- if (document != null) {
- List<IMarker> markers = AdtUtils.findMarkersOnLine(IMarker.PROBLEM,
- file, document, errorStart);
- for (IMarker marker : markers) {
- String message = marker.getAttribute(IMarker.MESSAGE, "");
- // There are no other attributes in the marker we can use to identify
- // the exact error, so we'll need to resort to the actual message
- // text even though that would not work if the messages had been
- // localized... This can also break if the error messages change. Yuck.
- if (message.contains("constant expressions")) { //$NON-NLS-1$
- foundError = true;
- }
- }
- }
- } catch (Exception e) {
- AdtPlugin.log(e, "Can't validate error message in %1$s", file.getName());
- } finally {
- provider.disconnect(file);
- }
- }
- if (!foundError) {
- // Not a constant-expression warning, so do nothing
- return null;
- }
-
- IBuffer buffer = compilationUnit.getBuffer();
- boolean sameLine = false;
- // See if the caret is on the same line as the error
- if (caret <= errorStart) {
- // Search backwards to beginning of line
- for (int i = errorStart; i >= 0; i--) {
- if (i <= caret) {
- sameLine = true;
- break;
- }
- char c = buffer.getChar(i);
- if (c == '\n') {
- break;
- }
- }
- } else {
- // Search forwards to the end of the line
- for (int i = errorStart + errorLength, n = buffer.getLength(); i < n; i++) {
- if (i >= caret) {
- sameLine = true;
- break;
- }
- char c = buffer.getChar(i);
- if (c == '\n') {
- break;
- }
- }
- }
-
- if (sameLine) {
- String expression = buffer.getText(errorStart, errorLength);
- return new IJavaCompletionProposal[] {
- new MigrateProposal(expression)
- };
- }
-
- return null;
- }
-
- /** Proposal for the quick fix which displays an explanation message to the user */
- private class MigrateProposal implements IJavaCompletionProposal {
- private String mExpression;
-
- private MigrateProposal(String expression) {
- mExpression = expression;
- }
-
- @Override
- public void apply(IDocument document) {
- Shell shell = AdtPlugin.getShell();
- ConvertSwitchDialog dialog = new ConvertSwitchDialog(shell, mExpression);
- dialog.open();
- }
-
- @Override
- public Point getSelection(IDocument document) {
- return null;
- }
-
- @Override
- public String getAdditionalProposalInfo() {
- return "As of ADT 14, resource fields cannot be used as switch cases. Invoke this " +
- "fix to get more information.";
- }
-
- @Override
- public String getDisplayString() {
- return "Migrate Android Code";
- }
-
- @Override
- public Image getImage() {
- return AdtPlugin.getAndroidLogo();
- }
-
- @Override
- public IContextInformation getContextInformation() {
- return null;
- }
-
- @Override
- public int getRelevance() {
- return 50;
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DefaultSourceChangeHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DefaultSourceChangeHandler.java
deleted file mode 100644
index ea0d695d1..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DefaultSourceChangeHandler.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2011 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 org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResourceDelta;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Base source change handler for the {@link SourceProcessor} classes.
- *
- * It can be used as is, as long as the matching {@link SourceProcessor} properly implements
- * its abstract methods, and the processor does not output resource files,
- * or can be extended to provide custom implementation for:
- * {@link #handleSourceFile(IFile, int)}
- * {@link #handleGeneratedFile(IFile, int)}
- * {@link #handleResourceFile(IFile, int)}
- * {@link #filterResourceFolder(IContainer)}
- *
- */
-public class DefaultSourceChangeHandler implements SourceChangeHandler {
-
- private SourceProcessor mProcessor;
-
- /** List of source files found that are modified or new. */
- private final Set<IFile> mToCompile = new HashSet<IFile>();
-
- /** List of source files that have been removed. */
- private final Set<IFile> mRemoved = new HashSet<IFile>();
-
- @Override
- public boolean handleGeneratedFile(IFile file, int kind) {
- if (kind == IResourceDelta.REMOVED || kind == IResourceDelta.CHANGED) {
- IFile sourceFile = mProcessor.isOutput(file);
- if (sourceFile != null) {
- mToCompile.add(sourceFile);
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public void handleSourceFile(IFile file, int kind) {
- // first the file itself if this is a match for the processor's extension
- if (mProcessor.getExtensions().contains(file.getFileExtension())) {
- if (kind == IResourceDelta.REMOVED) {
- mRemoved.add(file);
- } else {
- mToCompile.add(file);
- }
- }
-
- // now the dependencies. In all case we compile the files that depend on the
- // added/changed/removed file.
- mToCompile.addAll(mProcessor.isDependency(file));
- }
-
- protected void addFileToCompile(IFile file) {
- mToCompile.add(file);
- }
-
- Set<IFile> getFilesToCompile() {
- return mToCompile;
- }
-
- protected void addRemovedFile(IFile file) {
- mRemoved.add(file);
- }
-
- Set<IFile> getRemovedFiles() {
- return mRemoved;
- }
-
- public void reset() {
- mToCompile.clear();
- mRemoved.clear();
- }
-
- protected SourceProcessor getProcessor() {
- return mProcessor;
- }
-
- void init(SourceProcessor processor) {
- mProcessor = processor;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexException.java
deleted file mode 100644
index 032e5e646..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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;
-
-/**
- * Exception throw when dx fails.
- *
- */
-public final class DexException extends Exception {
- private static final long serialVersionUID = 1L;
-
- DexException(String message) {
- super(message);
- }
-
- DexException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexWrapper.java
deleted file mode 100644
index 3f882842b..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/DexWrapper.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2008 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.SdkConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-
-/**
- * Wrapper to access dx.jar through reflection.
- * <p/>Since there is no proper api to call the method in the dex library, this wrapper is going
- * to access it through reflection.
- */
-public final class DexWrapper {
-
- private final static String DEX_MAIN = "com.android.dx.command.dexer.Main"; //$NON-NLS-1$
- private final static String DEX_CONSOLE = "com.android.dx.command.DxConsole"; //$NON-NLS-1$
- private final static String DEX_ARGS = "com.android.dx.command.dexer.Main$Arguments"; //$NON-NLS-1$
-
- private final static String MAIN_RUN = "run"; //$NON-NLS-1$
-
- private Method mRunMethod;
-
- private Constructor<?> mArgConstructor;
- private Field mArgOutName;
- private Field mArgVerbose;
- private Field mArgJarOutput;
- private Field mArgFileNames;
- private Field mArgForceJumbo;
-
- private Field mConsoleOut;
- private Field mConsoleErr;
-
- /**
- * Loads the dex library from a file path.
- *
- * The loaded library can be used via
- * {@link DexWrapper#run(String, String[], boolean, PrintStream, PrintStream)}.
- *
- * @param osFilepath the location of the dx.jar file.
- * @return an IStatus indicating the result of the load.
- */
- public synchronized IStatus loadDex(String osFilepath) {
- try {
- File f = new File(osFilepath);
- if (f.isFile() == false) {
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, String.format(
- Messages.DexWrapper_s_does_not_exists, osFilepath));
- }
- URL url = f.toURI().toURL();
-
- @SuppressWarnings("resource")
- URLClassLoader loader = new URLClassLoader(new URL[] { url },
- DexWrapper.class.getClassLoader());
-
- // get the classes.
- Class<?> mainClass = loader.loadClass(DEX_MAIN);
- Class<?> consoleClass = loader.loadClass(DEX_CONSOLE);
- Class<?> argClass = loader.loadClass(DEX_ARGS);
-
- try {
- // now get the fields/methods we need
- mRunMethod = mainClass.getMethod(MAIN_RUN, argClass);
-
- mArgConstructor = argClass.getConstructor();
- mArgOutName = argClass.getField("outName"); //$NON-NLS-1$
- mArgJarOutput = argClass.getField("jarOutput"); //$NON-NLS-1$
- mArgFileNames = argClass.getField("fileNames"); //$NON-NLS-1$
- mArgVerbose = argClass.getField("verbose"); //$NON-NLS-1$
- mArgForceJumbo = argClass.getField("forceJumbo"); //$NON-NLS-1$
-
- mConsoleOut = consoleClass.getField("out"); //$NON-NLS-1$
- mConsoleErr = consoleClass.getField("err"); //$NON-NLS-1$
-
- } catch (SecurityException e) {
- return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_API, e);
- } catch (NoSuchMethodException e) {
- return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Method, e);
- } catch (NoSuchFieldException e) {
- return createErrorStatus(Messages.DexWrapper_SecuryEx_Unable_To_Find_Field, e);
- }
-
- return Status.OK_STATUS;
- } catch (MalformedURLException e) {
- // really this should not happen.
- return createErrorStatus(
- String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
- } catch (ClassNotFoundException e) {
- return createErrorStatus(
- String.format(Messages.DexWrapper_Failed_to_load_s, osFilepath), e);
- }
- }
-
- /**
- * Removes any reference to the dex library.
- * <p/>
- * {@link #loadDex(String)} must be called on the wrapper
- * before {@link #run(String, String[], boolean, PrintStream, PrintStream)} can
- * be used again.
- */
- public synchronized void unload() {
- mRunMethod = null;
- mArgConstructor = null;
- mArgOutName = null;
- mArgJarOutput = null;
- mArgFileNames = null;
- mArgVerbose = null;
- mConsoleOut = null;
- mConsoleErr = null;
- System.gc();
- }
-
- /**
- * Runs the dex command.
- * The wrapper must have been initialized via {@link #loadDex(String)} first.
- *
- * @param osOutFilePath the OS path to the outputfile (classes.dex
- * @param osFilenames list of input source files (.class and .jar files)
- * @param forceJumbo force jumbo mode.
- * @param verbose verbose mode.
- * @param outStream the stdout console
- * @param errStream the stderr console
- * @return the integer return code of com.android.dx.command.dexer.Main.run()
- * @throws CoreException
- */
- public synchronized int run(String osOutFilePath, Collection<String> osFilenames,
- boolean forceJumbo, boolean verbose,
- PrintStream outStream, PrintStream errStream) throws CoreException {
-
- assert mRunMethod != null;
- assert mArgConstructor != null;
- assert mArgOutName != null;
- assert mArgJarOutput != null;
- assert mArgFileNames != null;
- assert mArgForceJumbo != null;
- assert mArgVerbose != null;
- assert mConsoleOut != null;
- assert mConsoleErr != null;
-
- if (mRunMethod == null) {
- throw new CoreException(createErrorStatus(
- String.format(Messages.DexWrapper_Unable_To_Execute_Dex_s,
- "wrapper was not properly loaded first"),
- null /*exception*/));
- }
-
- try {
- // set the stream
- mConsoleErr.set(null /* obj: static field */, errStream);
- mConsoleOut.set(null /* obj: static field */, outStream);
-
- // create the Arguments object.
- Object args = mArgConstructor.newInstance();
- mArgOutName.set(args, osOutFilePath);
- mArgFileNames.set(args, osFilenames.toArray(new String[osFilenames.size()]));
- mArgJarOutput.set(args, osOutFilePath.endsWith(SdkConstants.DOT_JAR));
- mArgForceJumbo.set(args, forceJumbo);
- mArgVerbose.set(args, verbose);
-
- // call the run method
- Object res = mRunMethod.invoke(null /* obj: static method */, args);
-
- if (res instanceof Integer) {
- return ((Integer)res).intValue();
- }
-
- return -1;
- } catch (Exception e) {
- Throwable t = e;
- while (t.getCause() != null) {
- t = t.getCause();
- }
-
- String msg = t.getMessage();
- if (msg == null) {
- msg = String.format("%s. Check the Eclipse log for stack trace.",
- t.getClass().getName());
- }
-
- throw new CoreException(createErrorStatus(
- String.format(Messages.DexWrapper_Unable_To_Execute_Dex_s, msg), t));
- }
- }
-
- private static IStatus createErrorStatus(String message, Throwable e) {
- AdtPlugin.log(e, message);
- AdtPlugin.printErrorToConsole(Messages.DexWrapper_Dex_Loader, message);
-
- return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, message, e);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ExecResultException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ExecResultException.java
deleted file mode 100644
index 63a7a6946..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ExecResultException.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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;
-
-/**
- * Base exception class containing the error code and output of an external tool failed exec.
- *
- */
-class ExecResultException extends Exception {
- private static final long serialVersionUID = 1L;
-
- private final int mErrorCode;
- private final String[] mOutput;
-
- protected ExecResultException(int errorCode, String[] output) {
- mErrorCode = errorCode;
- mOutput = output;
- }
-
- /**
- * Returns the full output of aapt.
- */
- public String[] getOutput() {
- return mOutput;
- }
-
- /**
- * Returns the aapt return code.
- */
- public int getErrorCode() {
- return mErrorCode;
- }
-
- public String getLabel() {
- return "Command-line";
- }
-
- @Override
- public String toString() {
- String result = String.format("%1$s Error %2$d", getLabel(), mErrorCode);
- if (mOutput != null && mOutput.length > 0) {
- // Note : the "error detail" window in Eclipse seem to ignore the \n,
- // so we prefix them with a space. It's not optimal but it's slightly readable.
- result += " \nOutput:";
- for (String o : mOutput) {
- if (o != null) {
- result += " \n" + o;
- }
- }
- }
- return result;
- }
-
- @Override
- public String getMessage() {
- return toString();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java
deleted file mode 100644
index 9ceba205d..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java
+++ /dev/null
@@ -1,150 +0,0 @@
-
-package com.android.ide.eclipse.adt.internal.build;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
- private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.internal.build.build_messages"; //$NON-NLS-1$
-
- public static String AAPT_Error;
-
- public static String AAPT_Exec_Error_s;
-
- public static String AAPT_Exec_Error_d;
-
- public static String AAPT_Exec_Error_Other_s;
-
- public static String Added_s_s_Needs_Updating;
-
- public static String AIDL_Exec_Error_s;
-
- public static String AIDL_Exec_Error_d;
-
- public static String AIDL_Java_Conflict;
-
- public static String ApkBuilder_Certificate_Expired_on_s;
-
- public static String ApkBuilder_JAVA_HOME_is_s;
-
- public static String ApkBuilder_Packaging_s;
-
- public static String ApkBuilder_Packaging_s_into_s;
-
- public static String ApkBuilder_s_Conflict_with_file_s;
-
- public static String ApkBuilder_Signing_Key_Creation_s;
-
- public static String ApkBuilder_Unable_To_Gey_Key;
-
- public static String ApkBuilder_UnableBuild_Dex_Not_loaded;
-
- public static String ApkBuilder_Update_or_Execute_manually_s;
-
- public static String ApkBuilder_Using_Default_Key;
-
- public static String ApkBuilder_Using_s_To_Sign;
-
- public static String Checking_Package_Change;
-
- public static String Compiler_Compliance_Error;
-
- public static String Couldnt_Locate_s_Error;
-
- public static String Dalvik_Error_d;
-
- public static String Dalvik_Error_s;
-
- public static String Delete_Obsolete_Error;
-
- public static String DexWrapper_Dex_Loader;
-
- public static String DexWrapper_Failed_to_load_s;
-
- public static String DexWrapper_s_does_not_exists;
-
- public static String DexWrapper_SecuryEx_Unable_To_Find_API;
-
- public static String DexWrapper_SecuryEx_Unable_To_Find_Field;
-
- public static String DexWrapper_SecuryEx_Unable_To_Find_Method;
-
- public static String DexWrapper_Unable_To_Execute_Dex_s;
-
- public static String DX_Jar_Error;
-
- public static String Failed_To_Get_Output;
-
- public static String Final_Archive_Error_s;
-
- public static String Incompatible_VM_Warning;
-
- public static String Marker_Delete_Error;
-
- public static String No_SDK_Setup_Error;
-
- public static String Nothing_To_Compile;
-
- public static String Output_Missing;
-
- public static String Package_s_Doesnt_Exist_Error;
-
- public static String Preparing_Generated_Files;
-
- public static String Project_Has_Errors;
-
- public static String Refreshing_Res;
-
- public static String Removing_Generated_Classes;
-
- public static String Requires_1_5_Error;
-
- public static String Requires_Class_Compatibility_s;
-
- public static String Requires_Compiler_Compliance_s;
-
- public static String Requires_Source_Compatibility_s;
-
- public static String s_Contains_Xml_Error;
-
- public static String s_Doesnt_Declare_Package_Error;
-
- public static String s_File_Missing;
-
- public static String s_Missing_Repackaging;
-
- public static String s_Modified_Manually_Recreating_s;
-
- public static String s_Modified_Recreating_s;
-
- public static String s_Removed_Recreating_s;
-
- public static String s_Removed_s_Needs_Updating;
-
- public static String Start_Full_Apk_Build;
-
- public static String Start_Full_Pre_Compiler;
-
- public static String Skip_Post_Compiler;
-
- public static String Start_Full_Post_Compiler;
-
- public static String Start_Inc_Apk_Build;
-
- public static String Start_Inc_Pre_Compiler;
-
- public static String Unparsed_AAPT_Errors;
-
- public static String Unparsed_AIDL_Errors;
-
- public static String Xml_Error;
-
- public static String Proguard_Exec_Error;
-
- static {
- // initialize resource bundle
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
-
- private Messages() {
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NativeLibInJarException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NativeLibInJarException.java
deleted file mode 100644
index 18f4ae7aa..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/NativeLibInJarException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.build.ApkBuilder.JarStatus;
-
-/**
- * Exception throw when native libraries are detected in jar file.
- *
- */
-public final class NativeLibInJarException extends Exception {
- private static final long serialVersionUID = 1L;
-
- private final JarStatus mStatus;
- private final String mLibName;
- private final String[] mConsoleMsgs;
-
- NativeLibInJarException(JarStatus status, String message, String libName,
- String[] consoleMsgs) {
- super(message);
- mStatus = status;
- mLibName = libName;
- mConsoleMsgs = consoleMsgs;
- }
-
- /**
- * Returns the {@link JarStatus} object containing the information about the libraries that
- * were found.
- */
- public JarStatus getStatus() {
- return mStatus;
- }
-
- /**
- * Returns the name of the jar file containing the native libraries.
- */
- public String getJarName() {
- return mLibName;
- }
-
- /**
- * Returns additional information that should be shown to the user.
- */
- public String[] getAdditionalInfo() {
- return mConsoleMsgs;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardExecException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardExecException.java
deleted file mode 100644
index 3eb688b3e..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardExecException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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;
-
-/**
- * Exception thrown when the execution of proguard fails.
- *
- */
-public final class ProguardExecException extends Exception {
- private static final long serialVersionUID = 1L;
-
- ProguardExecException(String message, Throwable cause) {
- super(message, cause);
- }
-}
-
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardResultException.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardResultException.java
deleted file mode 100644
index 54246b337..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ProguardResultException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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;
-
-/**
- * Exception thrown when aapt reports an error in the resources.
- *
- */
-public final class ProguardResultException extends ExecResultException {
- private static final long serialVersionUID = 1L;
-
- ProguardResultException(int errorCode, String[] output) {
- super(errorCode, output);
- }
-
- @Override
- public String getLabel() {
- return "Proguard";
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java
deleted file mode 100644
index 1d3c7bd3a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations.NonNull;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.sdklib.build.RenderScriptProcessor.CommandLineLauncher;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-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.Path;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A {@link SourceProcessor} for RenderScript files.
- */
-public class RenderScriptLauncher implements CommandLineLauncher {
-
- /**
- * Single line llvm-rs-cc error: {@code <path>:<line>:<col>: <error>}
- */
- private static Pattern sLlvmPattern1 = Pattern.compile("^(.+?):(\\d+):(\\d+):\\s(.+)$"); //$NON-NLS-1$
-
- @NonNull
- private final IProject mProject;
- @NonNull
- private final IFolder mSourceOutFolder;
- @NonNull
- private final IFolder mResOutFolder;
- @NonNull
- private final IProgressMonitor mMonitor;
- private final boolean mVerbose;
-
- public RenderScriptLauncher(
- @NonNull IProject project,
- @NonNull IFolder sourceOutFolder,
- @NonNull IFolder resOutFolder,
- @NonNull IProgressMonitor monitor,
- boolean verbose) {
- mProject = project;
- mSourceOutFolder = sourceOutFolder;
- mResOutFolder = resOutFolder;
- mMonitor = monitor;
- mVerbose = verbose;
- }
-
- @Override
- public void launch(File executable, List<String> arguments, Map<String, String> envVariableMap)
- throws IOException, InterruptedException {
- // do the exec
- try {
- if (mVerbose) {
- StringBuilder sb = new StringBuilder(executable.getAbsolutePath());
- for (String c : arguments) {
- sb.append(' ').append(c);
- }
- String cmd_line = sb.toString();
- AdtPlugin.printToConsole(mProject, cmd_line);
- }
-
- String[] commandArray = new String[1 + arguments.size()];
- commandArray[0] = executable.getAbsolutePath();
- System.arraycopy(arguments.toArray(), 0, commandArray, 1, arguments.size());
-
- ProcessBuilder processBuilder = new ProcessBuilder(commandArray);
- Map<String, String> processEnvs = processBuilder.environment();
- for (Map.Entry<String, String> entry : envVariableMap.entrySet()) {
- processEnvs.put(entry.getKey(), entry.getValue());
- }
-
- Process p = processBuilder.start();
-
- // list to store each line of stderr
- ArrayList<String> stdErr = new ArrayList<String>();
-
- // get the output and return code from the process
- int returnCode = BuildHelper.grabProcessOutput(mProject, p, stdErr);
-
- if (stdErr.size() > 0) {
- // attempt to parse the error output
- boolean parsingError = parseLlvmOutput(stdErr);
-
- // If the process failed and we couldn't parse the output
- // we print a message, mark the project and exit
- if (returnCode != 0) {
-
- if (parsingError || mVerbose) {
- // display the message in the console.
- if (parsingError) {
- AdtPlugin.printErrorToConsole(mProject, stdErr.toArray());
-
- // mark the project
- BaseProjectHelper.markResource(mProject,
- AdtConstants.MARKER_RENDERSCRIPT,
- "Unparsed Renderscript error! Check the console for output.",
- IMarker.SEVERITY_ERROR);
- } else {
- AdtPlugin.printToConsole(mProject, stdErr.toArray());
- }
- }
- return;
- }
- } else if (returnCode != 0) {
- // no stderr output but exec failed.
- String msg = String.format("Error executing Renderscript: Return code %1$d",
- returnCode);
-
- BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_AIDL,
- msg, IMarker.SEVERITY_ERROR);
-
- return;
- }
- } catch (IOException e) {
- // mark the project and exit
- String msg = String.format(
- "Error executing Renderscript. Please check %1$s is present at %2$s",
- executable.getName(), executable.getAbsolutePath());
- AdtPlugin.log(IStatus.ERROR, msg);
- BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_RENDERSCRIPT, msg,
- IMarker.SEVERITY_ERROR);
- throw e;
- } catch (InterruptedException e) {
- // mark the project and exit
- String msg = String.format(
- "Error executing Renderscript. Please check %1$s is present at %2$s",
- executable.getName(), executable.getAbsolutePath());
- AdtPlugin.log(IStatus.ERROR, msg);
- BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_RENDERSCRIPT, msg,
- IMarker.SEVERITY_ERROR);
- throw e;
- }
-
- try {
- mSourceOutFolder.refreshLocal(IResource.DEPTH_ONE, mMonitor);
- mResOutFolder.refreshLocal(IResource.DEPTH_ONE, mMonitor);
- } catch (CoreException e) {
- AdtPlugin.log(e, "failed to refresh folders");
- }
-
- return;
- }
-
- /**
- * Parse the output of llvm-rs-cc and mark the file with any errors.
- * @param lines The output to parse.
- * @return true if the parsing failed, false if success.
- */
- private boolean parseLlvmOutput(ArrayList<String> lines) {
- // nothing to parse? just return false;
- if (lines.size() == 0) {
- return false;
- }
-
- // get the root folder for the project as we're going to ignore everything that's
- // not in the project
- String rootPath = mProject.getLocation().toOSString();
- int rootPathLength = rootPath.length();
-
- Matcher m;
-
- boolean parsing = false;
-
- for (int i = 0; i < lines.size(); i++) {
- String p = lines.get(i);
-
- m = sLlvmPattern1.matcher(p);
- if (m.matches()) {
- // get the file path. This may, or may not be the main file being compiled.
- String filePath = m.group(1);
- if (filePath.startsWith(rootPath) == false) {
- // looks like the error in a non-project file. Keep parsing, but
- // we'll return true
- parsing = true;
- continue;
- }
-
- // get the actual file.
- filePath = filePath.substring(rootPathLength);
- // remove starting separator since we want the path to be relative
- if (filePath.startsWith(File.separator)) {
- filePath = filePath.substring(1);
- }
-
- // get the file
- IFile f = mProject.getFile(new Path(filePath));
-
- String lineStr = m.group(2);
- // ignore group 3 for now, this is the col number
- String msg = m.group(4);
-
- // get the line number
- int line = 0;
- try {
- line = Integer.parseInt(lineStr);
- } catch (NumberFormatException e) {
- // looks like the string we extracted wasn't a valid
- // file number. Parsing failed and we return true
- return true;
- }
-
- // mark the file
- BaseProjectHelper.markResource(f, AdtConstants.MARKER_RENDERSCRIPT, msg, line,
- IMarker.SEVERITY_ERROR);
-
- // success, go to the next line
- continue;
- }
-
- // invalid line format, flag as error, and keep going
- parsing = true;
- }
-
- return parsing;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RsSourceChangeHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RsSourceChangeHandler.java
deleted file mode 100644
index 715895a0c..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RsSourceChangeHandler.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2013 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.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.sdklib.build.RenderScriptChecker;
-
-import org.eclipse.core.resources.IFile;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class RsSourceChangeHandler implements SourceChangeHandler {
-
- private final RenderScriptChecker mChecker;
- private boolean mIsCheckerLoaded = false;
-
- private boolean mMustCompile = false;
-
- public RsSourceChangeHandler(@NonNull RenderScriptChecker checker) {
- mChecker = checker;
- }
-
- @Override
- public boolean handleGeneratedFile(IFile file, int kind) {
- if (mMustCompile) {
- return false;
- }
-
- if (!mIsCheckerLoaded) {
- try {
- mChecker.loadDependencies();
- } catch (IOException e) {
- // failed to load the dependency files, force a compilation, log the error.
- AdtPlugin.log(e, "Failed to read dependency files");
- mMustCompile = true;
- return false;
- }
- }
-
- Set<File> oldOutputs = mChecker.getOldOutputs();
- // mustCompile is always false here.
- mMustCompile = oldOutputs.contains(file.getLocation().toFile());
- return mMustCompile;
- }
-
- @Override
- public void handleSourceFile(IFile file, int kind) {
- if (mMustCompile) {
- return;
- }
-
- String ext = file.getFileExtension();
- if (SdkConstants.EXT_RS.equals(ext) ||
- SdkConstants.EXT_FS.equals(ext) ||
- SdkConstants.EXT_RSH.equals(ext)) {
- mMustCompile = true;
- }
- }
-
- public boolean mustCompile() {
- return mMustCompile;
- }
-
- @NonNull
- public RenderScriptChecker getChecker() {
- return mChecker;
- }
-
- public void prepareFullBuild() {
- mMustCompile = true;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceChangeHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceChangeHandler.java
deleted file mode 100644
index 12a055106..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceChangeHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 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 org.eclipse.core.resources.IFile;
-
-public interface SourceChangeHandler {
-
- boolean handleGeneratedFile(IFile file, int kind);
- void handleSourceFile(IFile file, int kind);
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceFileData.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceFileData.java
deleted file mode 100644
index d06bf1613..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceFileData.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2011 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 org.eclipse.core.resources.IFile;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Data for Android-specific source files. It contains a list of output files and a list
- * of dependencies.
- * The source file itself is a implied dependency and is not meant to be in the dependency list.
- */
-public class SourceFileData {
-
- private final IFile mSourceFile;
- private final List<IFile> mOutputFiles = new ArrayList<IFile>();
- private final List<IFile> mDependencyFiles = new ArrayList<IFile>();
-
- public SourceFileData(IFile sourceFile) {
- this(sourceFile, null, null);
- }
-
- SourceFileData(IFile sourceFile,
- List<IFile> outputFiles, List<IFile> dependencyFiles) {
- mSourceFile = sourceFile;
- if (outputFiles != null) {
- mOutputFiles.addAll(outputFiles);
- }
- if (dependencyFiles != null) {
- mDependencyFiles.addAll(dependencyFiles);
- }
- }
-
- SourceFileData(IFile sourceFile, IFile outputFile) {
- mSourceFile = sourceFile;
- if (outputFile != null) {
- mOutputFiles.add(outputFile);
- }
- }
-
- /**
- * Returns the source file as an {@link IFile}
- */
- public IFile getSourceFile() {
- return mSourceFile;
- }
-
- /**
- * Returns whether the given file is a dependency for this source file.
- * <p/>Note that the source file itself is not tested against. Therefore if
- * {@code file.equals(getSourceFile()} returns {@code true}, this method will return
- * {@code false}.
- * @param file the file to check against
- * @return true if the given file is a dependency for this source file.
- */
- public boolean dependsOn(IFile file) {
- return mDependencyFiles.contains(file);
- }
-
- /**
- * Returns whether the given file is an ouput of this source file.
- * @param file the file to test.
- * @return true if the file is an output file.
- */
- public boolean generated(IFile file) {
- return mOutputFiles.contains(file);
- }
-
- void setOutputFiles(List<IFile> outputFiles) {
- mOutputFiles.clear();
- if (outputFiles != null) {
- mOutputFiles.addAll(outputFiles);
- }
- }
-
- void setOutputFile(IFile outputFile) {
- mOutputFiles.clear();
- if (outputFile != null) {
- mOutputFiles.add(outputFile);
- }
- }
-
- void setDependencyFiles(List<IFile> depFiles) {
- mDependencyFiles.clear();
- if (depFiles != null) {
- mDependencyFiles.addAll(depFiles);
- }
- }
-
- public List<IFile> getDependencyFiles() {
- return mDependencyFiles;
- }
-
- /**
- * Shortcut access to the first output file. This is useful for generator that only output
- * one file.
- */
- public IFile getOutput() {
- if (mOutputFiles.size() > 0) {
- return mOutputFiles.get(0);
- }
-
- return null;
- }
-
- public List<IFile> getOutputFiles() {
- return Collections.unmodifiableList(mOutputFiles);
- }
-
- @Override
- public String toString() {
- return "NonJavaFileBundle [mSourceFile=" + mSourceFile + ", mGeneratedFiles="
- + mOutputFiles + ", mDependencies=" + mDependencyFiles + "]";
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java
deleted file mode 100644
index 1fc3e4e53..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/SourceProcessor.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2011 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.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-
-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.IProgressMonitor;
-import org.eclipse.jdt.core.IJavaProject;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Base class to handle generated java code.
- *
- * It provides management for modified source file list, deleted source file list, reconciliation
- * of previous lists, storing the current state of the build.
- *
- */
-public abstract class SourceProcessor {
-
- public final static int COMPILE_STATUS_NONE = 0;
- public final static int COMPILE_STATUS_CODE = 0x1;
- public final static int COMPILE_STATUS_RES = 0x2;
-
- /** List of all source files, their dependencies, and their output. */
- private final Map<IFile, SourceFileData> mFiles = new HashMap<IFile, SourceFileData>();
-
- private final IJavaProject mJavaProject;
- private BuildToolInfo mBuildToolInfo;
- private final IFolder mGenFolder;
- private final DefaultSourceChangeHandler mDeltaVisitor;
-
- /** List of source files pending compilation at the next build */
- private final List<IFile> mToCompile = new ArrayList<IFile>();
-
- /** List of removed source files pending cleaning at the next build. */
- private final List<IFile> mRemoved = new ArrayList<IFile>();
-
- private int mLastCompilationStatus = COMPILE_STATUS_NONE;
-
- /**
- * Quotes a path inside "". If the platform is not windows, the path is returned as is.
- * @param path the path to quote
- * @return the quoted path.
- */
- public static String quote(String path) {
- if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) {
- if (path.endsWith(File.separator)) {
- path = path.substring(0, path.length() -1);
- }
- return "\"" + path + "\"";
- }
-
- return path;
- }
-
- protected SourceProcessor(
- @NonNull IJavaProject javaProject,
- @NonNull BuildToolInfo buildToolInfo,
- @NonNull IFolder genFolder,
- @NonNull DefaultSourceChangeHandler deltaVisitor) {
- mJavaProject = javaProject;
- mBuildToolInfo = buildToolInfo;
- mGenFolder = genFolder;
- mDeltaVisitor = deltaVisitor;
-
- mDeltaVisitor.init(this);
-
- IProject project = javaProject.getProject();
-
- // get all the source files
- buildSourceFileList();
-
- // load the known dependencies
- loadOutputAndDependencies();
-
- boolean mustCompile = loadState(project);
-
- // if we stored that we have to compile some files, we build the list that will compile them
- // all. For now we have to reuse the full list since we don't know which files needed
- // compilation.
- if (mustCompile) {
- mToCompile.addAll(mFiles.keySet());
- }
- }
-
- protected SourceProcessor(
- @NonNull IJavaProject javaProject,
- @NonNull BuildToolInfo buildToolInfo,
- @NonNull IFolder genFolder) {
- this(javaProject, buildToolInfo, genFolder, new DefaultSourceChangeHandler());
- }
-
- public void setBuildToolInfo(BuildToolInfo buildToolInfo) {
- mBuildToolInfo = buildToolInfo;
- }
-
-
- /**
- * Returns whether the given file is an output of this processor by return the source
- * file that generated it.
- * @param file the file to test.
- * @return the source file that generated the given file or null.
- */
- IFile isOutput(IFile file) {
- for (SourceFileData data : mFiles.values()) {
- if (data.generated(file)) {
- return data.getSourceFile();
- }
- }
-
- return null;
- }
-
- /**
- * Returns whether the given file is a dependency for other files by returning a list
- * of file depending on the given file.
- * @param file the file to test.
- * @return a list of files that depend on the given file or an empty list if there
- * are no matches.
- */
- List<IFile> isDependency(IFile file) {
- ArrayList<IFile> files = new ArrayList<IFile>();
- for (SourceFileData data : mFiles.values()) {
- if (data.dependsOn(file)) {
- files.add(data.getSourceFile());
- }
- }
-
- return files;
- }
-
- void addData(SourceFileData data) {
- mFiles.put(data.getSourceFile(), data);
- }
-
- SourceFileData getFileData(IFile file) {
- return mFiles.get(file);
- }
-
- Collection<SourceFileData> getAllFileData() {
- return mFiles.values();
- }
-
- public final DefaultSourceChangeHandler getChangeHandler() {
- return mDeltaVisitor;
- }
-
- final IJavaProject getJavaProject() {
- return mJavaProject;
- }
-
- final BuildToolInfo getBuildToolInfo() {
- return mBuildToolInfo;
- }
-
- final IFolder getGenFolder() {
- return mGenFolder;
- }
-
- final List<IFile> getToCompile() {
- return mToCompile;
- }
-
- final List<IFile> getRemovedFile() {
- return mRemoved;
- }
-
- final void addFileToCompile(IFile file) {
- mToCompile.add(file);
- }
-
- public final void prepareFullBuild(IProject project) {
- mDeltaVisitor.reset();
-
- mToCompile.clear();
- mRemoved.clear();
-
- // get all the source files
- buildSourceFileList();
-
- mToCompile.addAll(mFiles.keySet());
-
- saveState(project);
- }
-
- public final void doneVisiting(IProject project) {
- // merge the previous file modification lists and the new one.
- mergeFileModifications(mDeltaVisitor);
-
- mDeltaVisitor.reset();
-
- saveState(project);
- }
-
- /**
- * Returns the extension of the source files handled by this processor.
- * @return
- */
- protected abstract Set<String> getExtensions();
-
- protected abstract String getSavePropertyName();
-
- /**
- * Compiles the source files and return a status bitmask of the type of file that was generated.
- *
- */
- public final int compileFiles(BaseBuilder builder,
- IProject project, IAndroidTarget projectTarget,
- List<IPath> sourceFolders, List<File> libraryProjectsOut, IProgressMonitor monitor)
- throws CoreException {
-
- mLastCompilationStatus = COMPILE_STATUS_NONE;
-
- if (mToCompile.size() == 0 && mRemoved.size() == 0) {
- return mLastCompilationStatus;
- }
-
- // if a source file is being removed before we managed to compile it, it'll be in
- // both list. We *need* to remove it from the compile list or it'll never go away.
- for (IFile sourceFile : mRemoved) {
- int pos = mToCompile.indexOf(sourceFile);
- if (pos != -1) {
- mToCompile.remove(pos);
- }
- }
-
- // list of files that have failed compilation.
- List<IFile> stillNeedCompilation = new ArrayList<IFile>();
-
- doCompileFiles(mToCompile, builder, project, projectTarget, sourceFolders,
- stillNeedCompilation, libraryProjectsOut, monitor);
-
- mToCompile.clear();
- mToCompile.addAll(stillNeedCompilation);
-
- // Remove the files created from source files that have been removed.
- for (IFile sourceFile : mRemoved) {
- // look if we already know the output
- SourceFileData data = getFileData(sourceFile);
- if (data != null) {
- doRemoveFiles(data);
- }
- }
-
- // remove the associated file data.
- for (IFile removedFile : mRemoved) {
- mFiles.remove(removedFile);
- }
-
- mRemoved.clear();
-
- // store the build state. If there are any files that failed to compile, we will
- // force a full aidl compile on the next project open. (unless a full compilation succeed
- // before the project is closed/re-opened.)
- saveState(project);
-
- return mLastCompilationStatus;
- }
-
- protected abstract void doCompileFiles(
- List<IFile> filesToCompile, BaseBuilder builder,
- IProject project, IAndroidTarget projectTarget,
- List<IPath> sourceFolders, List<IFile> notCompiledOut,
- List<File> libraryProjectsOut, IProgressMonitor monitor) throws CoreException;
-
- /**
- * Adds a compilation status. It can be any of (in combination too):
- * <p/>
- * {@link #COMPILE_STATUS_CODE} means this processor created source code files.
- * {@link #COMPILE_STATUS_RES} means this process created resources.
- */
- protected void setCompilationStatus(int status) {
- mLastCompilationStatus |= status;
- }
-
- protected void doRemoveFiles(SourceFileData data) throws CoreException {
- List<IFile> outputFiles = data.getOutputFiles();
- for (IFile outputFile : outputFiles) {
- if (outputFile.exists()) {
- outputFile.getLocation().toFile().delete();
- }
- }
- }
-
- public final boolean loadState(IProject project) {
- return ProjectHelper.loadBooleanProperty(project, getSavePropertyName(),
- true /*defaultValue*/);
- }
-
- public final void saveState(IProject project) {
- // TODO: Optimize by saving only the files that need compilation
- ProjectHelper.saveStringProperty(project, getSavePropertyName(),
- Boolean.toString(mToCompile.size() > 0));
- }
-
- protected abstract void loadOutputAndDependencies();
-
-
- protected IPath getSourceFolderFor(IFile file) {
- // find the source folder for the class so that we can infer the package from the
- // difference between the file and its source folder.
- List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(getJavaProject());
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-
- for (IPath sourceFolderPath : sourceFolders) {
- IFolder sourceFolder = root.getFolder(sourceFolderPath);
- // we don't look in the 'gen' source folder as there will be no source in there.
- if (sourceFolder.exists() && sourceFolder.equals(getGenFolder()) == false) {
- // look for the source file parent, until we find this source folder.
- IResource parent = file;
- while ((parent = parent.getParent()) != null) {
- if (parent.equals(sourceFolder)) {
- return sourceFolderPath;
- }
- }
- }
- }
-
- return null;
- }
-
- /**
- * Goes through the build paths and fills the list of files to compile.
- *
- * @param project The project.
- * @param sourceFolderPathList The list of source folder paths.
- */
- private final void buildSourceFileList() {
- mFiles.clear();
-
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(mJavaProject);
-
- for (IPath sourceFolderPath : sourceFolderPathList) {
- IFolder sourceFolder = root.getFolder(sourceFolderPath);
- // we don't look in the 'gen' source folder as there will be no source in there.
- if (sourceFolder.exists() && sourceFolder.equals(getGenFolder()) == false) {
- scanFolderForSourceFiles(sourceFolder, sourceFolder);
- }
- }
- }
-
- /**
- * Scans a folder and fills the list of files to compile.
- * @param sourceFolder the root source folder.
- * @param folder The folder to scan.
- */
- private void scanFolderForSourceFiles(IFolder sourceFolder, IFolder folder) {
- try {
- IResource[] members = folder.members();
- for (IResource r : members) {
- // get the type of the resource
- switch (r.getType()) {
- case IResource.FILE: {
- // if this a file, check that the file actually exist
- // and that it's the type of of file that's used in this processor
- String extension = r.exists() ? r.getFileExtension() : null;
- if (extension != null &&
- getExtensions().contains(extension.toLowerCase(Locale.US))) {
- mFiles.put((IFile) r, new SourceFileData((IFile) r));
- }
- break;
- }
- case IResource.FOLDER:
- // recursively go through children
- scanFolderForSourceFiles(sourceFolder, (IFolder)r);
- break;
- default:
- // this would mean it's a project or the workspace root
- // which is unlikely to happen. we do nothing
- break;
- }
- }
- } catch (CoreException e) {
- // Couldn't get the members list for some reason. Just return.
- }
- }
-
-
- /**
- * Merge the current list of source file to compile/remove with the one coming from the
- * delta visitor
- * @param visitor the delta visitor.
- */
- private void mergeFileModifications(DefaultSourceChangeHandler visitor) {
- Set<IFile> toRemove = visitor.getRemovedFiles();
- Set<IFile> toCompile = visitor.getFilesToCompile();
-
- // loop through the new toRemove list, and add it to the old one,
- // plus remove any file that was still to compile and that are now
- // removed
- for (IFile r : toRemove) {
- if (mRemoved.indexOf(r) == -1) {
- mRemoved.add(r);
- }
-
- int index = mToCompile.indexOf(r);
- if (index != -1) {
- mToCompile.remove(index);
- }
- }
-
- // now loop through the new files to compile and add it to the list.
- // Also look for them in the remove list, this would mean that they
- // were removed, then added back, and we shouldn't remove them, just
- // recompile them.
- for (IFile r : toCompile) {
- if (mToCompile.indexOf(r) == -1) {
- mToCompile.add(r);
- }
-
- int index = mRemoved.indexOf(r);
- if (index != -1) {
- mRemoved.remove(index);
- }
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
deleted file mode 100644
index f387ab5a9..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
+++ /dev/null
@@ -1,67 +0,0 @@
-Start_Full_Apk_Build=Starting full Package build.
-Start_Full_Pre_Compiler=Starting full Pre Compiler.
-Skip_Post_Compiler=Skipping over Post Compiler.
-Start_Full_Post_Compiler=Starting full Post Compiler.
-Start_Inc_Apk_Build=Starting incremental Package build: Checking resource changes.
-Start_Inc_Pre_Compiler=Starting incremental Pre Compiler: Checking resource changes.
-Xml_Error=Error in an XML file: aborting build.
-s_Missing_Repackaging=%1$s missing. Repackaging.
-Project_Has_Errors=Project contains error(s). Package Builder aborted.
-Failed_To_Get_Output=Failed to get project output folder\!
-Output_Missing=Output folder missing\! Make sure your project is configured properly.
-s_File_Missing=%1$s file missing\!
-Unparsed_AAPT_Errors=Unparsed aapt error(s)\! Check the console for output.
-Unparsed_AIDL_Errors=Unparsed aidl error\! Check the console for output.
-AAPT_Exec_Error_s=Error executing aapt. Please check aapt is present at %1$s
-AAPT_Exec_Error_d=Error executing aapt: Return code %1$d
-AAPT_Exec_Error_Other_s=Error executing aapt: %1$s
-Dalvik_Error_d=Conversion to Dalvik format failed with error %1$d
-DX_Jar_Error=Dx.jar is not found inside the plugin. Reinstall ADT\!
-Dalvik_Error_s=Conversion to Dalvik format failed: %1$s
-Incompatible_VM_Warning=Note: You may be using an incompatible virtual machine or class library.
-Requires_1_5_Error=This program requires JDK 1.5 compatibility.
-Final_Archive_Error_s=Error generating final archive: %1$s
-Marker_Delete_Error=Failed to delete marker '%1$s' for %2$s
-Couldnt_Locate_s_Error=Could not locate '%1$s'. This will not be added to the package.
-Compiler_Compliance_Error=Compiler compliance level not compatible: Build aborted.
-No_SDK_Setup_Error=SDK directory has not been setup. Please go to the Android preferences and enter the location of the SDK.
-s_Contains_Xml_Error=%1$s contains XML error: Build aborted.
-s_Doesnt_Declare_Package_Error=%1$s does not declare a Java package: Build aborted.
-Checking_Package_Change=Checking Java package value did not change...
-Package_s_Doesnt_Exist_Error=Package '%1$s' does not exist\!
-Preparing_Generated_Files=Preparing generated java files for update/creation.
-AAPT_Error='aapt' error. Pre Compiler Build aborted.
-Nothing_To_Compile=Nothing to pre compile\!
-Removing_Generated_Classes=Removing generated java classes.
-Delete_Obsolete_Error=Failed to delete obsolete %1$s, please delete it manually
-DexWrapper_Dex_Loader=Dex Loader
-AIDL_Java_Conflict=%1$s is in the way of %2$s, remove it or rename of one the files.
-AIDL_Exec_Error_d=Error executing aidl: Return code %1$d
-AIDL_Exec_Error_s=Error executing aidl. Please check aidl is present at %1$s
-s_Removed_Recreating_s=%1$s was removed\! Recreating %1$s\!
-s_Modified_Manually_Recreating_s=%1$s was modified manually\! Reverting to generated version\!
-s_Modified_Recreating_s='%1$s' was modified.
-Added_s_s_Needs_Updating=New resource file: '%1$s', %2$s needs to be updated.
-s_Removed_s_Needs_Updating='%1$s' was removed, %2$s needs to be updated.
-Requires_Compiler_Compliance_s=Android requires compiler compliance level 5.0 or 6.0. Found '%1$s' instead. Please use Android Tools > Fix Project Properties.
-Requires_Source_Compatibility_s=Android requires source compatibility set to 5.0 or 6.0. Found '%1$s' instead. Please use Android Tools > Fix Project Properties.
-Requires_Class_Compatibility_s=Android requires .class compatibility set to 5.0 or 6.0. Found '%1$s' instead. Please use Android Tools > Fix Project Properties.
-Refreshing_Res=Refreshing resource folders.
-DexWrapper_s_does_not_exists=%1$s does not exist or is not a file
-DexWrapper_Failed_to_load_s=Failed to load %1$s
-DexWrapper_Unable_To_Execute_Dex_s=Unable to execute dex: %1$s
-DexWrapper_SecuryEx_Unable_To_Find_API=SecurityException: Unable to find API for dex.jar
-DexWrapper_SecuryEx_Unable_To_Find_Method=SecurityException: Unable to find method for dex.jar
-DexWrapper_SecuryEx_Unable_To_Find_Field=SecurityException: Unable to find field for dex.jar
-ApkBuilder_UnableBuild_Dex_Not_loaded=Unable to build: the file dx.jar was not loaded from the SDK folder\!
-ApkBuilder_Using_Default_Key=Using default debug key to sign package
-ApkBuilder_Using_s_To_Sign=Using '%1$s' to sign package
-ApkBuilder_Signing_Key_Creation_s=Signing Key Creation:
-ApkBuilder_Unable_To_Gey_Key=Unable to get debug signature key
-ApkBuilder_Certificate_Expired_on_s=Debug certificate expired on %1$s\!
-ApkBuilder_Packaging_s=Packaging %1$s
-ApkBuilder_JAVA_HOME_is_s=The Java VM Home used is: %1$s
-ApkBuilder_Update_or_Execute_manually_s=Update it if necessary, or manually execute the following command:
-ApkBuilder_s_Conflict_with_file_s=%1$s conflicts with another file already put at %2$s
-ApkBuilder_Packaging_s_into_s=Packaging %1$s into %2$s
-Proguard_Exec_Error=Error executing Proguard. Please check Proguard is present at %1$s
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
deleted file mode 100644
index 162591406..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/BaseBuilder.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2007 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.builders;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.io.IFileWrapper;
-import com.android.io.IAbstractFile;
-import com.android.io.StreamException;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.repository.FullRevision;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IJavaProject;
-import org.xml.sax.SAXException;
-
-import java.util.ArrayList;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Base builder for XML files. This class allows for basic XML parsing with
- * error checking and marking the files for errors/warnings.
- */
-public abstract class BaseBuilder extends IncrementalProjectBuilder {
-
- protected static final boolean DEBUG_LOG = "1".equals( //$NON-NLS-1$
- System.getenv("ANDROID_BUILD_DEBUG")); //$NON-NLS-1$
-
- /** SAX Parser factory. */
- private SAXParserFactory mParserFactory;
-
- /**
- * The build tool to use to build. This is guaranteed to be non null after a call to
- * {@link #abortOnBadSetup(IJavaProject, ProjectState)} since this will throw if it can't be
- * queried.
- */
- protected BuildToolInfo mBuildToolInfo;
-
- /**
- * Base Resource Delta Visitor to handle XML error
- */
- protected static class BaseDeltaVisitor implements XmlErrorListener {
-
- /** The Xml builder used to validate XML correctness. */
- protected BaseBuilder mBuilder;
-
- /**
- * XML error flag. if true, we keep parsing the ResourceDelta but the
- * compilation will not happen (we're putting markers)
- */
- public boolean mXmlError = false;
-
- public BaseDeltaVisitor(BaseBuilder builder) {
- mBuilder = builder;
- }
-
- /**
- * 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
- * @return The segments of the source folder, or null if no match was found
- */
- protected static String[] findMatchingSourceFolder(ArrayList<IPath> sourceFolders,
- String[] pathSegments) {
-
- for (IPath p : sourceFolders) {
- // check if we are inside one of those source class path
-
- // get the segments
- String[] srcSegments = p.segments();
-
- // compare segments. We want the path of the resource
- // we're visiting to be
- boolean valid = true;
- int segmentCount = pathSegments.length;
-
- for (int i = 0 ; i < segmentCount; i++) {
- String s1 = pathSegments[i];
- String s2 = srcSegments[i];
-
- if (s1.equalsIgnoreCase(s2) == false) {
- valid = false;
- break;
- }
- }
-
- if (valid) {
- // this folder, or one of this children is a source
- // folder!
- // we return its segments
- return srcSegments;
- }
- }
-
- return null;
- }
-
- /**
- * Sent when an XML error is detected.
- * @see XmlErrorListener
- */
- @Override
- public void errorFound() {
- mXmlError = true;
- }
- }
-
- protected static class AbortBuildException extends Exception {
- private static final long serialVersionUID = 1L;
- }
-
- public BaseBuilder() {
- super();
- mParserFactory = SAXParserFactory.newInstance();
-
- // FIXME when the compiled XML support for namespace is in, set this to true.
- mParserFactory.setNamespaceAware(false);
- }
-
- /**
- * Checks an Xml file for validity. Errors/warnings will be marked on the
- * file
- * @param resource the resource to check
- * @param visitor a valid resource delta visitor
- */
- protected final void checkXML(IResource resource, BaseDeltaVisitor visitor) {
-
- // first make sure this is an xml file
- if (resource instanceof IFile) {
- IFile file = (IFile)resource;
-
- // remove previous markers
- removeMarkersFromResource(file, AdtConstants.MARKER_XML);
-
- // create the error handler
- XmlErrorHandler reporter = new XmlErrorHandler(file, visitor);
- try {
- // parse
- getParser().parse(file.getContents(), reporter);
- } catch (Exception e1) {
- }
- }
- }
-
- /**
- * Returns the SAXParserFactory, instantiating it first if it's not already
- * created.
- * @return the SAXParserFactory object
- * @throws ParserConfigurationException
- * @throws SAXException
- */
- protected final SAXParser getParser() throws ParserConfigurationException,
- SAXException {
- return mParserFactory.newSAXParser();
- }
-
- /**
- * Adds a marker to the current project. This methods catches thrown {@link CoreException},
- * and returns null instead.
- *
- * @param markerId The id of the marker to add.
- * @param message the message associated with the mark
- * @param severity the severity of the marker.
- * @return the marker that was created (or null if failure)
- * @see IMarker
- */
- protected final IMarker markProject(String markerId, String message, int severity) {
- return BaseProjectHelper.markResource(getProject(), markerId, message, severity);
- }
-
- /**
- * Removes markers from a resource and only the resource (not its children).
- * @param file The file from which to delete the markers.
- * @param markerId The id of the markers to remove. If null, all marker of
- * type <code>IMarker.PROBLEM</code> will be removed.
- */
- public final void removeMarkersFromResource(IResource resource, String markerId) {
- try {
- if (resource.exists()) {
- resource.deleteMarkers(markerId, true, IResource.DEPTH_ZERO);
- }
- } catch (CoreException ce) {
- String msg = String.format(Messages.Marker_Delete_Error, markerId, resource.toString());
- AdtPlugin.printErrorToConsole(getProject(), msg);
- }
- }
-
- /**
- * Removes markers from a container and its children.
- * @param folder The container from which to delete the markers.
- * @param markerId The id of the markers to remove. If null, all marker of
- * type <code>IMarker.PROBLEM</code> will be removed.
- */
- protected final void removeMarkersFromContainer(IContainer folder, String markerId) {
- try {
- if (folder.exists()) {
- folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
- }
- } catch (CoreException ce) {
- String msg = String.format(Messages.Marker_Delete_Error, markerId, folder.toString());
- AdtPlugin.printErrorToConsole(getProject(), msg);
- }
- }
-
- /**
- * Get the stderr output of a process and return when the process is done.
- * @param process The process to get the ouput from
- * @param stdErr The array to store the stderr output
- * @return the process return code.
- * @throws InterruptedException
- */
- protected final int grabProcessOutput(final Process process,
- final ArrayList<String> stdErr) throws InterruptedException {
- return BuildHelper.grabProcessOutput(getProject(), process, stdErr);
- }
-
-
-
- /**
- * Saves a String property into the persistent storage of the project.
- * @param propertyName the name of the property. The id of the plugin is added to this string.
- * @param value the value to save
- * @return true if the save succeeded.
- */
- protected boolean saveProjectStringProperty(String propertyName, String value) {
- IProject project = getProject();
- return ProjectHelper.saveStringProperty(project, propertyName, value);
- }
-
-
- /**
- * Loads a String property from the persistent storage of the project.
- * @param propertyName the name of the property. The id of the plugin is added to this string.
- * @return the property value or null if it was not found.
- */
- protected String loadProjectStringProperty(String propertyName) {
- IProject project = getProject();
- return ProjectHelper.loadStringProperty(project, propertyName);
- }
-
- /**
- * Saves a property into the persistent storage of the project.
- * @param propertyName the name of the property. The id of the plugin is added to this string.
- * @param value the value to save
- * @return true if the save succeeded.
- */
- protected boolean saveProjectBooleanProperty(String propertyName, boolean value) {
- IProject project = getProject();
- return ProjectHelper.saveStringProperty(project, propertyName, Boolean.toString(value));
- }
-
- /**
- * Loads a boolean property from the persistent storage of the project.
- * @param propertyName the name of the property. The id of the plugin is added to this string.
- * @param defaultValue The default value to return if the property was not found.
- * @return the property value or the default value if the property was not found.
- */
- protected boolean loadProjectBooleanProperty(String propertyName, boolean defaultValue) {
- IProject project = getProject();
- return ProjectHelper.loadBooleanProperty(project, propertyName, defaultValue);
- }
-
- /**
- * Aborts the build if the SDK/project setups are broken. This does not
- * display any errors.
- *
- * @param javaProject The {@link IJavaProject} being compiled.
- * @param projectState the project state, optional. will be queried if null.
- * @throws CoreException
- */
- protected void abortOnBadSetup(@NonNull IJavaProject javaProject,
- @Nullable ProjectState projectState) throws AbortBuildException, CoreException {
- IProject iProject = javaProject.getProject();
- // check if we have finished loading the project target.
- Sdk sdk = Sdk.getCurrent();
- if (sdk == null) {
- throw new AbortBuildException();
- }
-
- if (projectState == null) {
- projectState = Sdk.getProjectState(javaProject.getProject());
- }
-
- // get the target for the project
- IAndroidTarget target = projectState.getTarget();
-
- if (target == null) {
- throw new AbortBuildException();
- }
-
- // check on the target data.
- if (sdk.checkAndLoadTargetData(target, javaProject) != LoadStatus.LOADED) {
- throw new AbortBuildException();
- }
-
- mBuildToolInfo = projectState.getBuildToolInfo();
- if (mBuildToolInfo == null) {
- mBuildToolInfo = sdk.getLatestBuildTool();
-
- if (mBuildToolInfo == null) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, iProject,
- "No \"Build Tools\" package available; use SDK Manager to install one.");
- throw new AbortBuildException();
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, iProject,
- String.format("Using default Build Tools revision %s",
- mBuildToolInfo.getRevision())
- );
- }
- }
-
- // abort if there are TARGET or ADT type markers
- stopOnMarker(iProject, AdtConstants.MARKER_TARGET, IResource.DEPTH_ZERO,
- false /*checkSeverity*/);
- stopOnMarker(iProject, AdtConstants.MARKER_ADT, IResource.DEPTH_ZERO,
- false /*checkSeverity*/);
- }
-
- protected void stopOnMarker(IProject project, String markerType, int depth,
- boolean checkSeverity)
- throws AbortBuildException {
- try {
- IMarker[] markers = project.findMarkers(markerType, false /*includeSubtypes*/, depth);
-
- if (markers.length > 0) {
- if (checkSeverity == false) {
- throw new AbortBuildException();
- } else {
- for (IMarker marker : markers) {
- int severity = marker.getAttribute(IMarker.SEVERITY, -1 /*defaultValue*/);
- if (severity == IMarker.SEVERITY_ERROR) {
- throw new AbortBuildException();
- }
- }
- }
- }
- } catch (CoreException e) {
- // don't stop, something's really screwed up and the build will break later with
- // a better error message.
- }
- }
-
- /**
- * Handles a {@link StreamException} by logging the info and marking the project.
- * This should generally be followed by exiting the build process.
- *
- * @param e the exception
- */
- protected void handleStreamException(StreamException e) {
- IAbstractFile file = e.getFile();
-
- String msg;
-
- IResource target = getProject();
- if (file instanceof IFileWrapper) {
- target = ((IFileWrapper) file).getIFile();
-
- if (e.getError() == StreamException.Error.OUTOFSYNC) {
- msg = "File is Out of sync";
- } else {
- msg = "Error reading file. Read log for details";
- }
-
- } else {
- if (e.getError() == StreamException.Error.OUTOFSYNC) {
- msg = String.format("Out of sync file: %s", file.getOsLocation());
- } else {
- msg = String.format("Error reading file %s. Read log for details",
- file.getOsLocation());
- }
- }
-
- AdtPlugin.logAndPrintError(e, getProject().getName(), msg);
- BaseProjectHelper.markResource(target, AdtConstants.MARKER_ADT, msg,
- IMarker.SEVERITY_ERROR);
- }
-
- /**
- * Handles a generic {@link Throwable} by logging the info and marking the project.
- * This should generally be followed by exiting the build process.
- *
- * @param t the {@link Throwable}.
- * @param message the message to log and to associate with the marker.
- */
- protected void handleException(Throwable t, String message) {
- AdtPlugin.logAndPrintError(t, getProject().getName(), message);
- markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
- }
-
- /**
- * Recursively delete all the derived resources from a root resource. The root resource is not
- * deleted.
- * @param rootResource the root resource
- * @param monitor a progress monitor.
- * @throws CoreException
- *
- */
- protected void removeDerivedResources(IResource rootResource, IProgressMonitor monitor)
- throws CoreException {
- removeDerivedResources(rootResource, false, monitor);
- }
-
- /**
- * delete a resource and its children. returns true if the root resource was deleted. All
- * sub-folders *will* be deleted if they were emptied (not if they started empty).
- * @param rootResource the root resource
- * @param deleteRoot whether to delete the root folder.
- * @param monitor a progress monitor.
- * @throws CoreException
- */
- private void removeDerivedResources(IResource rootResource, boolean deleteRoot,
- IProgressMonitor monitor) throws CoreException {
- if (rootResource.exists()) {
- // if it's a folder, delete derived member.
- if (rootResource.getType() == IResource.FOLDER) {
- IFolder folder = (IFolder)rootResource;
- IResource[] members = folder.members();
- boolean wasNotEmpty = members.length > 0;
- for (IResource member : members) {
- removeDerivedResources(member, true /*deleteRoot*/, monitor);
- }
-
- // if the folder had content that is now all removed, delete the folder.
- if (deleteRoot && wasNotEmpty && folder.members().length == 0) {
- rootResource.getLocation().toFile().delete();
- }
- }
-
- // if the root resource is derived, delete it.
- if (rootResource.isDerived()) {
- rootResource.getLocation().toFile().delete();
- }
- }
- }
-
- protected void launchJob(Job newJob) {
- newJob.setPriority(Job.BUILD);
- newJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
- newJob.schedule();
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSet.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSet.java
deleted file mode 100644
index 4f5b47f6d..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSet.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.build.builders;
-
-import com.android.annotations.NonNull;
-
-import org.apache.tools.ant.types.selectors.SelectorUtils;
-import org.eclipse.core.runtime.IPath;
-
-/**
- * Collection of file path or path patterns to be checked for changes.
- *
- * All paths should be relative to the project they belong to.
- * Patterns can use Ant-type glob patterns.
- *
- * This is an immutable class that does not store any info beyond the list of paths. This is to
- * be used in conjunction with {@link PatternBasedDeltaVisitor}.
- */
-class ChangedFileSet {
-
- private final String mLogName;
-
- private final String[] mInputs;
- private String mOutput;
-
- ChangedFileSet(String logName, String... inputs) {
- mLogName = logName;
- mInputs = inputs;
- }
-
- public void setOutput(@NonNull String output) {
- mOutput = output;
- }
-
- public boolean isInput(@NonNull String path, @NonNull IPath iPath) {
- for (String i : mInputs) {
- if (SelectorUtils.matchPath(i, path)) {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean isOutput(@NonNull String path, @NonNull IPath iPath) {
- if (mOutput != null) {
- return SelectorUtils.matchPath(mOutput, path);
- }
-
- return false;
- }
-
- public String getLogName() {
- return mLogName;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSetHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSetHelper.java
deleted file mode 100644
index 9fc19a7a6..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ChangedFileSetHelper.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.build.builders;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IPath;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Helper class to generate {@link ChangedFileSet} for given projects.
- *
- * Also contains non project specific {@link ChangedFileSet} such as {@link #MANIFEST}
- * and {@link #NATIVE_LIBS}
- */
-class ChangedFileSetHelper {
-
- final static ChangedFileSet MANIFEST;
- final static ChangedFileSet NATIVE_LIBS;
-
- static {
- MANIFEST = new ChangedFileSet("manifest", //$NON-NLS-1$
- SdkConstants.FN_ANDROID_MANIFEST_XML);
-
- // FIXME: move compiled native libs to bin/libs/
- NATIVE_LIBS = new ChangedFileSet(
- "nativeLibs",
- SdkConstants.FD_NATIVE_LIBS + "/*/*.so", //$NON-NLS-1$
- SdkConstants.FD_NATIVE_LIBS + "/*/" + SdkConstants.FN_GDBSERVER); //$NON-NLS-1$
- }
-
- /**
- * Returns a ChangedFileSet for Java resources inside a given project's source folders.
- * @param project the project.
- * @return a ChangedFileSet
- */
- static ChangedFileSet getJavaResCfs(@NonNull IProject project) {
-
- // get the source folder for the given project.
- IPath projectPath = project.getFullPath();
-
- // get the source folders.
- List<IPath> srcPaths = BaseProjectHelper.getSourceClasspaths(project);
- List<String> paths = new ArrayList<String>(srcPaths.size());
-
- // create a pattern for each of them.
- for (IPath path : srcPaths) {
- paths.add(path.makeRelativeTo(projectPath).toString() + "/**"); //$NON-NLS-1$
- }
-
- // custom ChangedFileSet to ignore .java files.
- return new JavaResChangedSet("javaRes", //$NON-NLS-1$
- paths.toArray(new String[paths.size()]));
- }
-
- /**
- * Returns a {@link ChangedFileSet} for all the resources (included assets), and the output
- * file (compiled resources
- * @param project the project
- * @return a ChangeFileSet
- */
- static ChangedFileSet getResCfs(@NonNull IProject project) {
- // generated res is inside the project's android output folder
- String path = getRelativeAndroidOut(project);
-
- ChangedFileSet set = new ChangedFileSet(
- "resources", //$NON-NLS-1$
- SdkConstants.FD_RES + "/**", //$NON-NLS-1$
- SdkConstants.FD_ASSETS + "/**", //$NON-NLS-1$
- path + '/' + AdtConstants.WS_BIN_RELATIVE_BC + "/**"); //$NON-NLS-1$
-
- // output file is based on the project's android output folder
- set.setOutput(path + '/' + AdtConstants.FN_RESOURCES_AP_);
-
- return set;
- }
-
- /**
- * Returns a {@link ChangedFileSet} for all the resources (included assets), and the output
- * file (compiled resources
- * @param project the project
- * @return a ChangeFileSet
- */
- static ChangedFileSet getMergedManifestCfs(@NonNull IProject project) {
- // input path is inside the project's android output folder
- String path = getRelativeAndroidOut(project);
-
- ChangedFileSet set = new ChangedFileSet(
- "mergedManifest", //$NON-NLS-1$
- path + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML);
-
- return set;
- }
-
- /**
- * Returns a {@link ChangedFileSet} for the generated R.txt file
- * @param project the project
- * @return a ChangeFileSet
- */
- static ChangedFileSet getTextSymbols(@NonNull IProject project) {
- // input path is inside the project's android output folder
- String path = getRelativeAndroidOut(project);
-
- ChangedFileSet set = new ChangedFileSet(
- "textSymbols", //$NON-NLS-1$
- path + '/' + SdkConstants.FN_RESOURCE_TEXT);
-
- return set;
- }
-
- /**
- * Returns a {@link ChangedFileSet} for a project's javac output.
- * @param project the project
- * @return a ChangedFileSet
- */
- static ChangedFileSet getByteCodeCfs(@NonNull IProject project) {
- // input pattern is based on the project's Java compiler's output folder
- String path = getRelativeJavaCOut(project);
-
- ChangedFileSet set = new ChangedFileSet("compiledCode", //$NON-NLS-1$
- path + "/**/*" + SdkConstants.DOT_CLASS); //$NON-NLS-1$
-
- return set;
- }
-
- /**
- * Returns a {@link ChangedFileSet} for a project's complete resources, including
- * generated resources and crunch cache.
- * @param project the project
- * @return a ChangeFileSet
- */
- static ChangedFileSet getFullResCfs(@NonNull IProject project) {
- // generated res are in the project's android output folder
- String path = getRelativeAndroidOut(project);
-
- ChangedFileSet set = new ChangedFileSet("libResources", //$NON-NLS-1$
- SdkConstants.FD_RES + "/**", //$NON-NLS-1$
- path + '/' + SdkConstants.FD_RES + "/**"); //$NON-NLS-1$
-
- return set;
- }
-
- /**
- * Returns a {@link ChangedFileSet} for a project's whole code, including
- * compiled bytecode, 3rd party libs, and the output file containing the Dalvik
- * bytecode file.
- * @param project the project
- * @return a ChangeFileSet
- */
- static ChangedFileSet getCodeCfs(@NonNull IProject project) {
- // input pattern is based on the project's Java compiler's output folder
- String path = getRelativeJavaCOut(project);
-
- ChangedFileSet set = new ChangedFileSet("classAndJars", //$NON-NLS-1$
- path + "/**/*" + SdkConstants.DOT_CLASS, //$NON-NLS-1$
- SdkConstants.FD_NATIVE_LIBS + "/*" + SdkConstants.DOT_JAR); //$NON-NLS-1$
-
- // output file is based on the project's android output folder
- path = getRelativeAndroidOut(project);
- set.setOutput(path + '/' + SdkConstants.FN_APK_CLASSES_DEX);
-
- return set;
- }
-
- private static String getRelativePath(@NonNull IProject project, @NonNull IResource resource) {
- return resource.getFullPath().makeRelativeTo(project.getFullPath()).toString();
- }
-
- private static String getRelativeAndroidOut(@NonNull IProject project) {
- IFolder folder = BaseProjectHelper.getAndroidOutputFolder(project);
- return getRelativePath(project, folder);
- }
-
- private static String getRelativeJavaCOut(@NonNull IProject project) {
- IFolder folder = BaseProjectHelper.getJavaOutputFolder(project);
- return getRelativePath(project, folder);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/JavaResChangedSet.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/JavaResChangedSet.java
deleted file mode 100644
index 6b257efbf..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/JavaResChangedSet.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.build.builders;
-
-import com.android.annotations.NonNull;
-import com.android.sdklib.build.ApkBuilder;
-
-import org.eclipse.core.runtime.IPath;
-
-/**
- * Custom {@link ChangedFileSet} for java resources.
- *
- * This builds the set of inputs to be all the source folders of the given project,
- * and excludes files that won't be packaged.
- * This exclusion can't be easily described as a glob-pattern so it's overriding the default
- * behavior instead.
- *
- */
-class JavaResChangedSet extends ChangedFileSet {
-
- JavaResChangedSet(String logName, String... inputs) {
- super(logName, inputs);
- }
-
- @Override
- public boolean isInput(@NonNull String path, @NonNull IPath iPath) {
- if (!ApkBuilder.checkFileForPackaging(iPath.lastSegment(), iPath.getFileExtension())) {
- return false;
- }
- return super.isInput(path, iPath);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PatternBasedDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PatternBasedDeltaVisitor.java
deleted file mode 100644
index b52ede90c..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PatternBasedDeltaVisitor.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.build.builders;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-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;
-import org.eclipse.core.runtime.IStatus;
-
-import java.util.ArrayList;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delta visitor checking changed files against given glob-patterns.
- *
- * The visitor is given {@link ChangedFileSet} objects which contains patterns to detect change
- * in input and output files. (Output files are only tested if the delta indicate the file
- * was removed).
- *
- * After the visitor has visited the whole delta, it can be queried to see which ChangedFileSet
- * recognized a file change. (ChangedFileSet are immutable and do not record this info).
- */
-class PatternBasedDeltaVisitor implements IResourceDeltaVisitor {
-
- private final static boolean DEBUG_LOG = "1".equals( //$NON-NLS-1$
- System.getenv("ANDROID_VISITOR_DEBUG")); //$NON-NLS-1$
-
- private final IProject mMainProject;
- private final IProject mDeltaProject;
-
- private final List<ChangedFileSet> mSets = new ArrayList<ChangedFileSet>();
- private final Map<ChangedFileSet, Boolean> mResults =
- new IdentityHashMap<ChangedFileSet, Boolean>();
-
- private final String mLogName;
-
- PatternBasedDeltaVisitor(IProject mainProject, IProject deltaProject, String logName) {
- mMainProject = mainProject;
- mDeltaProject = deltaProject;
- mLogName = logName;
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s (%s): Delta for %s", //$NON-NLS-1$
- mMainProject.getName(), mLogName, mDeltaProject.getName());
- }
- }
-
- void addSet(ChangedFileSet bundle) {
- mSets.add(bundle);
- }
-
- boolean checkSet(ChangedFileSet bundle) {
- Boolean r = mResults.get(bundle);
- if (r != null) {
- return r.booleanValue();
- }
-
- return false;
- }
-
- @Override
- public boolean visit(IResourceDelta delta) throws CoreException {
- IResource resource = delta.getResource();
-
- if (resource.getType() == IResource.FOLDER) {
- // always visit the subfolders, unless the folder is not to be included
- return BuildHelper.checkFolderForPackaging((IFolder)resource);
-
- } else if (resource.getType() == IResource.FILE) {
- IPath path = resource.getFullPath().makeRelativeTo(mDeltaProject.getFullPath());
- String pathStr = path.toString();
-
- // FIXME: no need to loop through all the sets once they have all said they need something (return false below and above)
- for (ChangedFileSet set : mSets) {
- // FIXME: should ignore sets that have already returned true.
-
- if (set.isInput(pathStr, path)) {
- mResults.put(set, Boolean.TRUE);
-
- if (DEBUG_LOG) {
- String cfs_logName = set.getLogName();
-
- if (cfs_logName != null) {
- AdtPlugin.log(IStatus.INFO, "%s (%s:%s): %s", //$NON-NLS-1$
- mMainProject.getName(), mLogName, cfs_logName,
- resource.getFullPath().toString());
- } else {
- AdtPlugin.log(IStatus.INFO, "%s (%s): %s", //$NON-NLS-1$
- mMainProject.getName(), mLogName,
- resource.getFullPath().toString());
- }
- }
-
- } else if (delta.getKind() == IResourceDelta.REMOVED &&
- set.isOutput(pathStr, path)) {
- mResults.put(set, Boolean.TRUE);
-
- if (DEBUG_LOG) {
- String cfs_logName = set.getLogName();
-
- if (cfs_logName != null) {
- AdtPlugin.log(IStatus.INFO, "%s (%s:%s): %s", //$NON-NLS-1$
- mMainProject.getName(), mLogName, cfs_logName,
- resource.getFullPath().toString());
- } else {
- AdtPlugin.log(IStatus.INFO, "%s (%s): %s", //$NON-NLS-1$
- mMainProject.getName(), mLogName,
- resource.getFullPath().toString());
- }
- }
- }
- }
- }
-
- return true;
- }
-}
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
deleted file mode 100644
index 8aacb44ef..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2007 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.builders;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-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.AaptExecException;
-import com.android.ide.eclipse.adt.internal.build.AaptParser;
-import com.android.ide.eclipse.adt.internal.build.AaptResultException;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper;
-import com.android.ide.eclipse.adt.internal.build.BuildHelper.ResourceMarker;
-import com.android.ide.eclipse.adt.internal.build.DexException;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-import com.android.ide.eclipse.adt.internal.build.NativeLibInJarException;
-import com.android.ide.eclipse.adt.internal.lint.LintDeltaProcessor;
-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.ApkInstallManager;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.LibraryClasspathContainerInitializer;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.io.IFileWrapper;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.build.ApkBuilder;
-import com.android.sdklib.build.ApkCreationException;
-import com.android.sdklib.build.DuplicateFileException;
-import com.android.sdklib.build.IArchiveBuilder;
-import com.android.sdklib.build.SealedApkException;
-import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException;
-import com.android.xml.AndroidManifest;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jdt.core.IJavaModelMarker;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.regex.Pattern;
-
-public class PostCompilerBuilder extends BaseBuilder {
-
- /** This ID is used in plugin.xml and in each project's .project file.
- * It cannot be changed even if the class is renamed/moved */
- public static final String ID = "com.android.ide.eclipse.adt.ApkBuilder"; //$NON-NLS-1$
-
- private static final String PROPERTY_CONVERT_TO_DEX = "convertToDex"; //$NON-NLS-1$
- private static final String PROPERTY_PACKAGE_RESOURCES = "packageResources"; //$NON-NLS-1$
- private static final String PROPERTY_BUILD_APK = "buildApk"; //$NON-NLS-1$
-
- /** Flag to pass to PostCompiler builder that sets if it runs or not.
- * Set this flag whenever calling build if PostCompiler is to run
- */
- public final static String POST_C_REQUESTED = "RunPostCompiler"; //$NON-NLS-1$
-
- /**
- * Dex conversion flag. This is set to true if one of the changed/added/removed
- * file is a .class file. Upon visiting all the delta resource, if this
- * flag is true, then we know we'll have to make the "classes.dex" file.
- */
- private boolean mConvertToDex = false;
-
- /**
- * Package resources flag. This is set to true if one of the changed/added/removed
- * file is a resource file. Upon visiting all the delta resource, if
- * this flag is true, then we know we'll have to repackage the resources.
- */
- private boolean mPackageResources = false;
-
- /**
- * Final package build flag.
- */
- private boolean mBuildFinalPackage = false;
-
- private AndroidPrintStream mOutStream = null;
- private AndroidPrintStream mErrStream = null;
-
-
- private ResourceMarker mResourceMarker = new ResourceMarker() {
- @Override
- public void setWarning(IResource resource, String message) {
- BaseProjectHelper.markResource(resource, AdtConstants.MARKER_PACKAGING,
- message, IMarker.SEVERITY_WARNING);
- }
- };
-
-
- public PostCompilerBuilder() {
- super();
- }
-
- @Override
- protected void clean(IProgressMonitor monitor) throws CoreException {
- super.clean(monitor);
-
- // Get the project.
- IProject project = getProject();
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s CLEAN(POST)", project.getName());
- }
-
- // Clear the project of the generic markers
- removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE);
- removeMarkersFromContainer(project, AdtConstants.MARKER_PACKAGING);
-
- // also remove the files in the output folder (but not the Eclipse output folder).
- IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(project);
- IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(project);
-
- if (javaOutput.equals(androidOutput) == false) {
- // get the content
- IResource[] members = androidOutput.members();
- for (IResource member : members) {
- if (member.equals(javaOutput) == false) {
- member.delete(true /*force*/, monitor);
- }
- }
- }
- }
-
- // build() returns a list of project from which this project depends for future compilation.
- @Override
- protected IProject[] build(
- int kind,
- @SuppressWarnings("rawtypes") Map args,
- IProgressMonitor monitor)
- throws CoreException {
- // get a project object
- IProject project = getProject();
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s BUILD(POST)", project.getName());
- }
-
- // Benchmarking start
- long startBuildTime = 0;
- if (BuildHelper.BENCHMARK_FLAG) {
- // End JavaC Timer
- String msg = "BENCHMARK ADT: Ending Compilation \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$
- (System.nanoTime() - BuildHelper.sStartJavaCTime)/Math.pow(10, 6) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
- msg = "BENCHMARK ADT: Starting PostCompilation"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
- startBuildTime = System.nanoTime();
- }
-
- // list of referenced projects. This is a mix of java projects and library projects
- // and is computed below.
- IProject[] allRefProjects = null;
-
- try {
- // get the project info
- ProjectState projectState = Sdk.getProjectState(project);
-
- // this can happen if the project has no project.properties.
- if (projectState == null) {
- return null;
- }
-
- boolean isLibrary = projectState.isLibrary();
-
- // get the libraries
- List<IProject> libProjects = projectState.getFullLibraryProjects();
-
- IJavaProject javaProject = JavaCore.create(project);
-
- // get the list of referenced projects.
- List<IProject> javaProjects = ProjectHelper.getReferencedProjects(project);
- List<IJavaProject> referencedJavaProjects = BuildHelper.getJavaProjects(
- javaProjects);
-
- // mix the java project and the library projects
- final int size = libProjects.size() + javaProjects.size();
- ArrayList<IProject> refList = new ArrayList<IProject>(size);
- refList.addAll(libProjects);
- refList.addAll(javaProjects);
- allRefProjects = refList.toArray(new IProject[size]);
-
- // get the android output folder
- IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project);
- IFolder resOutputFolder = androidOutputFolder.getFolder(SdkConstants.FD_RES);
-
- // First thing we do is go through the resource delta to not
- // lose it if we have to abort the build for any reason.
- if (args.containsKey(POST_C_REQUESTED)
- && AdtPrefs.getPrefs().getBuildSkipPostCompileOnFileSave()) {
- // Skip over flag setting
- } else if (kind == FULL_BUILD) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Start_Full_Apk_Build);
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s full build!", project.getName());
- }
-
- // Full build: we do all the steps.
- mPackageResources = true;
- mConvertToDex = true;
- mBuildFinalPackage = true;
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Start_Inc_Apk_Build);
-
- // go through the resources and see if something changed.
- IResourceDelta delta = getDelta(project);
- if (delta == null) {
- // no delta? Same as full build: we do all the steps.
- mPackageResources = true;
- mConvertToDex = true;
- mBuildFinalPackage = true;
- } else {
-
- if (ResourceManager.isAutoBuilding() && AdtPrefs.getPrefs().isLintOnSave()) {
- // Check for errors on save/build, if enabled
- LintDeltaProcessor.create().process(delta);
- }
-
- PatternBasedDeltaVisitor dv = new PatternBasedDeltaVisitor(
- project, project,
- "POST:Main");
-
- ChangedFileSet manifestCfs = ChangedFileSetHelper.getMergedManifestCfs(project);
- dv.addSet(manifestCfs);
-
- ChangedFileSet resCfs = ChangedFileSetHelper.getResCfs(project);
- dv.addSet(resCfs);
-
- ChangedFileSet androidCodeCfs = ChangedFileSetHelper.getCodeCfs(project);
- dv.addSet(androidCodeCfs);
-
- ChangedFileSet javaResCfs = ChangedFileSetHelper.getJavaResCfs(project);
- dv.addSet(javaResCfs);
- dv.addSet(ChangedFileSetHelper.NATIVE_LIBS);
-
- delta.accept(dv);
-
- // save the state
- mPackageResources |= dv.checkSet(manifestCfs) || dv.checkSet(resCfs);
-
- mConvertToDex |= dv.checkSet(androidCodeCfs);
-
- mBuildFinalPackage |= dv.checkSet(javaResCfs) ||
- dv.checkSet(ChangedFileSetHelper.NATIVE_LIBS);
- }
-
- // check the libraries
- if (libProjects.size() > 0) {
- for (IProject libProject : libProjects) {
- delta = getDelta(libProject);
- if (delta != null) {
- PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
- project, libProject,
- "POST:Lib");
-
- ChangedFileSet libResCfs = ChangedFileSetHelper.getFullResCfs(
- libProject);
- visitor.addSet(libResCfs);
- visitor.addSet(ChangedFileSetHelper.NATIVE_LIBS);
- // FIXME: add check on the library.jar?
-
- delta.accept(visitor);
-
- mPackageResources |= visitor.checkSet(libResCfs);
- mBuildFinalPackage |= visitor.checkSet(
- ChangedFileSetHelper.NATIVE_LIBS);
- }
- }
- }
-
- // also go through the delta for all the referenced projects
- final int referencedCount = referencedJavaProjects.size();
- for (int i = 0 ; i < referencedCount; i++) {
- IJavaProject referencedJavaProject = referencedJavaProjects.get(i);
- delta = getDelta(referencedJavaProject.getProject());
- if (delta != null) {
- IProject referencedProject = referencedJavaProject.getProject();
- PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
- project, referencedProject,
- "POST:RefedProject");
-
- ChangedFileSet javaResCfs = ChangedFileSetHelper.getJavaResCfs(referencedProject);
- visitor.addSet(javaResCfs);
-
- ChangedFileSet bytecodeCfs = ChangedFileSetHelper.getByteCodeCfs(referencedProject);
- visitor.addSet(bytecodeCfs);
-
- delta.accept(visitor);
-
- // save the state
- mConvertToDex |= visitor.checkSet(bytecodeCfs);
- mBuildFinalPackage |= visitor.checkSet(javaResCfs);
- }
- }
- }
-
- // store the build status in the persistent storage
- saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
- saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
- saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
-
- // Top level check to make sure the build can move forward. Only do this after recording
- // delta changes.
- abortOnBadSetup(javaProject, projectState);
-
- // Get the output stream. Since the builder is created for the life of the
- // project, they can be kept around.
- if (mOutStream == null) {
- mOutStream = new AndroidPrintStream(project, null /*prefix*/,
- AdtPlugin.getOutStream());
- mErrStream = new AndroidPrintStream(project, null /*prefix*/,
- AdtPlugin.getOutStream());
- }
-
- // remove older packaging markers.
- removeMarkersFromContainer(javaProject.getProject(), AdtConstants.MARKER_PACKAGING);
-
- // finished with the common init and tests. Special case of the library.
- if (isLibrary) {
- // check the jar output file is present, if not create it.
- IFile jarIFile = androidOutputFolder.getFile(
- project.getName().toLowerCase() + SdkConstants.DOT_JAR);
- if (mConvertToDex == false && jarIFile.exists() == false) {
- mConvertToDex = true;
- }
-
- // also update the crunch cache always since aapt does it smartly only
- // on the files that need it.
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s running crunch!", project.getName());
- }
- BuildHelper helper = new BuildHelper(
- projectState,
- mBuildToolInfo,
- mOutStream, mErrStream,
- false /*jumbo mode doesn't matter here*/,
- false /*dex merger doesn't matter here*/,
- true /*debugMode*/,
- AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE,
- mResourceMarker);
- updateCrunchCache(project, helper);
-
- // refresh recursively bin/res folder
- resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
-
- if (mConvertToDex) { // in this case this means some class files changed and
- // we need to update the jar file.
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s updating jar!", project.getName());
- }
-
- // resource to the AndroidManifest.xml file
- IFile manifestFile = project.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
- String appPackage = AndroidManifest.getPackage(new IFileWrapper(manifestFile));
-
- IFolder javaOutputFolder = BaseProjectHelper.getJavaOutputFolder(project);
-
- 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);
-
- // Also update the projects. The only way to force recompile them is to
- // reset the library container.
- List<ProjectState> parentProjects = projectState.getParentProjects();
- LibraryClasspathContainerInitializer.updateProject(parentProjects);
- }
-
- return allRefProjects;
- }
-
- // Check to see if we're going to launch or export. If not, we can skip
- // the packaging and dexing process.
- if (!args.containsKey(POST_C_REQUESTED)
- && AdtPrefs.getPrefs().getBuildSkipPostCompileOnFileSave()) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Skip_Post_Compiler);
- return allRefProjects;
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Start_Full_Post_Compiler);
- }
-
- // first thing we do is check that the SDK directory has been setup.
- String osSdkFolder = AdtPlugin.getOsSdkFolder();
-
- if (osSdkFolder.length() == 0) {
- // this has already been checked in the precompiler. Therefore,
- // while we do have to cancel the build, we don't have to return
- // any error or throw anything.
- return allRefProjects;
- }
-
- // do some extra check, in case the output files are not present. This
- // will force to recreate them.
- IResource tmp = null;
-
- if (mPackageResources == false) {
- // check the full resource package
- tmp = androidOutputFolder.findMember(AdtConstants.FN_RESOURCES_AP_);
- if (tmp == null || tmp.exists() == false) {
- mPackageResources = true;
- }
- }
-
- // check classes.dex is present. If not we force to recreate it.
- if (mConvertToDex == false) {
- tmp = androidOutputFolder.findMember(SdkConstants.FN_APK_CLASSES_DEX);
- if (tmp == null || tmp.exists() == false) {
- mConvertToDex = true;
- }
- }
-
- // also check the final file(s)!
- String finalPackageName = ProjectHelper.getApkFilename(project, null /*config*/);
- if (mBuildFinalPackage == false) {
- tmp = androidOutputFolder.findMember(finalPackageName);
- if (tmp == null || (tmp instanceof IFile &&
- tmp.exists() == false)) {
- String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
- mBuildFinalPackage = true;
- }
- }
-
- // at this point we know if we need to recreate the temporary apk
- // or the dex file, but we don't know if we simply need to recreate them
- // because they are missing
-
- // refresh the output directory first
- IContainer ic = androidOutputFolder.getParent();
- if (ic != null) {
- ic.refreshLocal(IResource.DEPTH_ONE, monitor);
- }
-
- // we need to test all three, as we may need to make the final package
- // but not the intermediary ones.
- if (mPackageResources || mConvertToDex || mBuildFinalPackage) {
- String forceJumboStr = projectState.getProperty(
- AdtConstants.DEX_OPTIONS_FORCEJUMBO);
- Boolean jumbo = Boolean.valueOf(forceJumboStr);
-
- String dexMergerStr = projectState.getProperty(
- AdtConstants.DEX_OPTIONS_DISABLE_MERGER);
- Boolean dexMerger = Boolean.valueOf(dexMergerStr);
-
- BuildHelper helper = new BuildHelper(
- projectState,
- mBuildToolInfo,
- mOutStream, mErrStream,
- jumbo.booleanValue(),
- dexMerger.booleanValue(),
- true /*debugMode*/,
- AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE,
- mResourceMarker);
-
- IPath androidBinLocation = androidOutputFolder.getLocation();
- if (androidBinLocation == null) {
- markProject(AdtConstants.MARKER_PACKAGING, Messages.Output_Missing,
- IMarker.SEVERITY_ERROR);
- return allRefProjects;
- }
- String osAndroidBinPath = androidBinLocation.toOSString();
-
- // resource to the AndroidManifest.xml file
- IFile manifestFile = androidOutputFolder.getFile(
- SdkConstants.FN_ANDROID_MANIFEST_XML);
-
- if (manifestFile == null || manifestFile.exists() == false) {
- // mark project and exit
- String msg = String.format(Messages.s_File_Missing,
- SdkConstants.FN_ANDROID_MANIFEST_XML);
- markProject(AdtConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR);
- return allRefProjects;
- }
-
- // Remove the old .apk.
- // This make sure that if the apk is corrupted, then dx (which would attempt
- // to open it), will not fail.
- String osFinalPackagePath = osAndroidBinPath + File.separator + finalPackageName;
- File finalPackage = new File(osFinalPackagePath);
-
- // if delete failed, this is not really a problem, as the final package generation
- // handle already present .apk, and if that one failed as well, the user will be
- // notified.
- finalPackage.delete();
-
- // Check if we need to package the resources.
- if (mPackageResources) {
- // also update the crunch cache always since aapt does it smartly only
- // on the files that need it.
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s running crunch!", project.getName());
- }
- if (updateCrunchCache(project, helper) == false) {
- return allRefProjects;
- }
-
- // refresh recursively bin/res folder
- resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s packaging resources!", project.getName());
- }
- // remove some aapt_package only markers.
- removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_PACKAGE);
-
- try {
- helper.packageResources(manifestFile, libProjects, null /*resfilter*/,
- 0 /*versionCode */, osAndroidBinPath,
- AdtConstants.FN_RESOURCES_AP_);
- } catch (AaptExecException e) {
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
- e.getMessage(), IMarker.SEVERITY_ERROR);
- return allRefProjects;
- } catch (AaptResultException e) {
- // attempt to parse the error output
- String[] aaptOutput = e.getOutput();
- boolean parsingError = AaptParser.parseOutput(aaptOutput, project);
-
- // if we couldn't parse the output we display it in the console.
- if (parsingError) {
- AdtPlugin.printErrorToConsole(project, (Object[]) aaptOutput);
-
- // if the exec failed, and we couldn't parse the error output (and
- // therefore not all files that should have been marked, were marked),
- // we put a generic marker on the project and abort.
- BaseProjectHelper.markResource(project,
- AdtConstants.MARKER_PACKAGING,
- Messages.Unparsed_AAPT_Errors,
- IMarker.SEVERITY_ERROR);
- }
- }
-
- // build has been done. reset the state of the builder
- mPackageResources = false;
-
- // and store it
- saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
- }
-
- String classesDexPath = osAndroidBinPath + File.separator +
- SdkConstants.FN_APK_CLASSES_DEX;
-
- // then we check if we need to package the .class into classes.dex
- if (mConvertToDex) {
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s running dex!", project.getName());
- }
- try {
- Collection<String> dxInputPaths = helper.getCompiledCodePaths();
-
- helper.executeDx(javaProject, dxInputPaths, classesDexPath);
- } catch (DexException e) {
- String message = e.getMessage();
-
- AdtPlugin.printErrorToConsole(project, message);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
- message, IMarker.SEVERITY_ERROR);
-
- Throwable cause = e.getCause();
-
- if (cause instanceof NoClassDefFoundError
- || cause instanceof NoSuchMethodError) {
- AdtPlugin.printErrorToConsole(project, Messages.Incompatible_VM_Warning,
- Messages.Requires_1_5_Error);
- }
-
- // dx failed, we return
- return allRefProjects;
- }
-
- // build has been done. reset the state of the builder
- mConvertToDex = false;
-
- // and store it
- saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
- }
-
- // now we need to make the final package from the intermediary apk
- // and classes.dex.
- // This is the default package with all the resources.
-
- try {
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s making final package!", project.getName());
- }
- helper.finalDebugPackage(
- osAndroidBinPath + File.separator + AdtConstants.FN_RESOURCES_AP_,
- classesDexPath, osFinalPackagePath, libProjects, mResourceMarker);
- } catch (KeytoolException e) {
- String eMessage = e.getMessage();
-
- // mark the project with the standard message
- String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
- IMarker.SEVERITY_ERROR);
-
- // output more info in the console
- AdtPlugin.printErrorToConsole(project,
- msg,
- String.format(Messages.ApkBuilder_JAVA_HOME_is_s, e.getJavaHome()),
- Messages.ApkBuilder_Update_or_Execute_manually_s,
- e.getCommandLine());
-
- AdtPlugin.log(e, msg);
-
- return allRefProjects;
- } catch (ApkCreationException e) {
- String eMessage = e.getMessage();
-
- // mark the project with the standard message
- String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
- IMarker.SEVERITY_ERROR);
-
- AdtPlugin.log(e, msg);
- } catch (AndroidLocationException e) {
- String eMessage = e.getMessage();
-
- // mark the project with the standard message
- String msg = String.format(Messages.Final_Archive_Error_s, eMessage);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
- IMarker.SEVERITY_ERROR);
- AdtPlugin.log(e, msg);
- } catch (NativeLibInJarException e) {
- String msg = e.getMessage();
-
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
- msg, IMarker.SEVERITY_ERROR);
-
- AdtPlugin.printErrorToConsole(project, (Object[]) e.getAdditionalInfo());
- } catch (CoreException e) {
- // mark project and return
- String msg = String.format(Messages.Final_Archive_Error_s, e.getMessage());
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg,
- IMarker.SEVERITY_ERROR);
- AdtPlugin.log(e, msg);
- } catch (DuplicateFileException e) {
- String msg1 = String.format(
- "Found duplicate file for APK: %1$s\nOrigin 1: %2$s\nOrigin 2: %3$s",
- e.getArchivePath(), e.getFile1(), e.getFile2());
- String msg2 = String.format(Messages.Final_Archive_Error_s, msg1);
- AdtPlugin.printErrorToConsole(project, msg2);
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING, msg2,
- IMarker.SEVERITY_ERROR);
- }
-
- // we are done.
-
- // refresh the bin folder content with no recursion.
- androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);
-
- // build has been done. reset the state of the builder
- mBuildFinalPackage = false;
-
- // and store it
- saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
-
- // reset the installation manager to force new installs of this project
- ApkInstallManager.getInstance().resetInstallationFor(project);
-
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
- "Build Success!");
- }
- } catch (AbortBuildException e) {
- return allRefProjects;
- } catch (Exception exception) {
- // try to catch other exception to actually display an error. This will be useful
- // if we get an NPE or something so that we can at least notify the user that something
- // went wrong.
-
- // first check if this is a CoreException we threw to cancel the build.
- if (exception instanceof CoreException) {
- if (((CoreException)exception).getStatus().getSeverity() == IStatus.CANCEL) {
- // Project is already marked with an error. Nothing to do
- return allRefProjects;
- }
- }
-
- String msg = exception.getMessage();
- if (msg == null) {
- msg = exception.getClass().getCanonicalName();
- }
-
- msg = String.format("Unknown error: %1$s", msg);
- AdtPlugin.logAndPrintError(exception, project.getName(), msg);
- markProject(AdtConstants.MARKER_PACKAGING, msg, IMarker.SEVERITY_ERROR);
- }
-
- // Benchmarking end
- if (BuildHelper.BENCHMARK_FLAG) {
- String msg = "BENCHMARK ADT: Ending PostCompilation. \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$
- ((System.nanoTime() - startBuildTime)/Math.pow(10, 6)) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
- // End Overall Timer
- msg = "BENCHMARK ADT: Done with everything! \n BENCHMARK ADT: Time Elapsed: " + //$NON-NLS-1$
- (System.nanoTime() - BuildHelper.sStartOverallTime)/Math.pow(10, 6) + "ms"; //$NON-NLS-1$
- AdtPlugin.printBuildToConsole(BuildVerbosity.ALWAYS, project, msg);
- }
-
- return allRefProjects;
- }
-
- private static class JarBuilder implements IArchiveBuilder {
-
- private static Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class"); //$NON-NLS-1$
- private static String BUILD_CONFIG_CLASS = "BuildConfig.class"; //$NON-NLS-1$
-
- private final byte[] buffer = new byte[1024];
- private final JarOutputStream mOutputStream;
- private final String mAppPackage;
-
- JarBuilder(JarOutputStream outputStream, String appPackage) {
- mOutputStream = outputStream;
- mAppPackage = appPackage.replace('.', '/');
- }
-
- public void addFile(IFile file, IFolder rootFolder) throws ApkCreationException {
- // we only package class file from the output folder
- if (SdkConstants.EXT_CLASS.equals(file.getFileExtension()) == false) {
- return;
- }
-
- IPath packageApp = file.getParent().getFullPath().makeRelativeTo(
- rootFolder.getFullPath());
-
- String name = file.getName();
- // Ignore the library's R/Manifest/BuildConfig classes.
- if (mAppPackage.equals(packageApp.toString()) &&
- (BUILD_CONFIG_CLASS.equals(name) ||
- R_PATTERN.matcher(name).matches())) {
- return;
- }
-
- IPath path = file.getFullPath().makeRelativeTo(rootFolder.getFullPath());
- try {
- addFile(file.getContents(), file.getLocalTimeStamp(), path.toString());
- } catch (ApkCreationException e) {
- throw e;
- } catch (Exception e) {
- throw new ApkCreationException(e, "Failed to add %s", file);
- }
- }
-
- @Override
- public void addFile(File file, String archivePath) throws ApkCreationException,
- SealedApkException, DuplicateFileException {
- try {
- FileInputStream inputStream = new FileInputStream(file);
- long lastModified = file.lastModified();
- addFile(inputStream, lastModified, archivePath);
- } catch (ApkCreationException e) {
- throw e;
- } catch (Exception e) {
- throw new ApkCreationException(e, "Failed to add %s", file);
- }
- }
-
- private void addFile(InputStream content, long lastModified, String archivePath)
- throws IOException, ApkCreationException {
- // create the jar entry
- JarEntry entry = new JarEntry(archivePath);
- entry.setTime(lastModified);
-
- try {
- // add the entry to the jar archive
- mOutputStream.putNextEntry(entry);
-
- // read the content of the entry from the input stream, and write
- // it into the archive.
- int count;
- while ((count = content.read(buffer)) != -1) {
- mOutputStream.write(buffer, 0, count);
- }
- } finally {
- try {
- if (content != null) {
- content.close();
- }
- } catch (Exception e) {
- throw new ApkCreationException(e, "Failed to close stream");
- }
- }
- }
- }
-
- /**
- * Updates the crunch cache if needed and return true if the build must continue.
- */
- private boolean updateCrunchCache(IProject project, BuildHelper helper) {
- try {
- helper.updateCrunchCache();
- } catch (AaptExecException e) {
- BaseProjectHelper.markResource(project, AdtConstants.MARKER_PACKAGING,
- e.getMessage(), IMarker.SEVERITY_ERROR);
- return false;
- } catch (AaptResultException e) {
- // attempt to parse the error output
- String[] aaptOutput = e.getOutput();
- boolean parsingError = AaptParser.parseOutput(aaptOutput, project);
- // if we couldn't parse the output we display it in the console.
- if (parsingError) {
- AdtPlugin.printErrorToConsole(project, (Object[]) aaptOutput);
- }
- }
-
- 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) {
-
- JarOutputStream jos = null;
- try {
- Manifest manifest = new Manifest();
- Attributes mainAttributes = manifest.getMainAttributes();
- mainAttributes.put(Attributes.Name.CLASS_PATH, "Android ADT"); //$NON-NLS-1$
- mainAttributes.putValue("Created-By", "1.0 (Android)"); //$NON-NLS-1$ //$NON-NLS-2$
- jos = new JarOutputStream(
- new FileOutputStream(jarIFile.getLocation().toFile()), manifest);
-
- JarBuilder jarBuilder = new JarBuilder(jos, appPackage);
-
- // write the class files
- writeClassFilesIntoJar(jarBuilder, javaOutputFolder, javaOutputFolder);
-
- // now write the standard Java resources from the output folder
- ApkBuilder.addSourceFolder(jarBuilder, javaOutputFolder.getLocation().toFile());
-
- saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex);
- } catch (Exception e) {
- AdtPlugin.log(e, "Failed to write jar file %s", jarIFile.getLocation().toOSString());
- } finally {
- if (jos != null) {
- try {
- jos.close();
- } catch (IOException e) {
- // pass
- }
- }
- }
- }
-
- private void writeClassFilesIntoJar(JarBuilder builder, IFolder folder, IFolder rootFolder)
- throws CoreException, IOException, ApkCreationException {
- IResource[] members = folder.members();
- for (IResource member : members) {
- if (member.getType() == IResource.FOLDER) {
- writeClassFilesIntoJar(builder, (IFolder) member, rootFolder);
- } else if (member.getType() == IResource.FILE) {
- IFile file = (IFile) member;
- builder.addFile(file, rootFolder);
- }
- }
- }
-
- @Override
- protected void startupOnInitialize() {
- super.startupOnInitialize();
-
- // load the build status. We pass true as the default value to
- // force a recompile in case the property was not found
- mConvertToDex = loadProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, true);
- mPackageResources = loadProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, true);
- mBuildFinalPackage = loadProjectBooleanProperty(PROPERTY_BUILD_APK, true);
- }
-
- @Override
- protected void abortOnBadSetup(
- @NonNull IJavaProject javaProject,
- @Nullable ProjectState projectState) throws AbortBuildException, CoreException {
- super.abortOnBadSetup(javaProject, projectState);
-
- IProject iProject = getProject();
-
- // do a (hopefully quick) search for Precompiler type markers. Those are always only
- // errors.
- stopOnMarker(iProject, AdtConstants.MARKER_AAPT_COMPILE, IResource.DEPTH_INFINITE,
- false /*checkSeverity*/);
- stopOnMarker(iProject, AdtConstants.MARKER_AIDL, IResource.DEPTH_INFINITE,
- false /*checkSeverity*/);
- stopOnMarker(iProject, AdtConstants.MARKER_RENDERSCRIPT, IResource.DEPTH_INFINITE,
- false /*checkSeverity*/);
- stopOnMarker(iProject, AdtConstants.MARKER_ANDROID, IResource.DEPTH_ZERO,
- false /*checkSeverity*/);
-
- // do a search for JDT markers. Those can be errors or warnings
- stopOnMarker(iProject, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
- IResource.DEPTH_INFINITE, true /*checkSeverity*/);
- stopOnMarker(iProject, IJavaModelMarker.BUILDPATH_PROBLEM_MARKER,
- IResource.DEPTH_INFINITE, true /*checkSeverity*/);
- }
-}
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
deleted file mode 100644
index 0d9ee4897..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java
+++ /dev/null
@@ -1,1401 +0,0 @@
-/*
- * Copyright (C) 2007 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.builders;
-
-import com.android.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.AaptParser;
-import com.android.ide.eclipse.adt.internal.build.AidlProcessor;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-import com.android.ide.eclipse.adt.internal.build.RenderScriptLauncher;
-import com.android.ide.eclipse.adt.internal.build.RsSourceChangeHandler;
-import com.android.ide.eclipse.adt.internal.build.SourceProcessor;
-import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder.AbortBuildException;
-import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient;
-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.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.IdeScanningContext;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
-import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
-import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.ide.eclipse.adt.io.IFileWrapper;
-import com.android.ide.eclipse.adt.io.IFolderWrapper;
-import com.android.io.StreamException;
-import com.android.manifmerger.ManifestMerger;
-import com.android.manifmerger.MergerLog;
-import com.android.sdklib.AndroidVersion;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.build.RenderScriptChecker;
-import com.android.sdklib.build.RenderScriptProcessor;
-import com.android.sdklib.internal.build.BuildConfigGenerator;
-import com.android.sdklib.internal.build.SymbolLoader;
-import com.android.sdklib.internal.build.SymbolWriter;
-import com.android.sdklib.internal.project.ProjectProperties;
-import com.android.sdklib.io.FileOp;
-import com.android.sdklib.repository.FullRevision;
-import com.android.utils.ILogger;
-import com.android.utils.Pair;
-import com.android.xml.AndroidManifest;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-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.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-/**
- * Pre Java Compiler.
- * This incremental builder performs 2 tasks:
- * <ul>
- * <li>compiles the resources located in the res/ folder, along with the
- * AndroidManifest.xml file into the R.java class.</li>
- * <li>compiles any .aidl files into a corresponding java file.</li>
- * </ul>
- *
- */
-public class PreCompilerBuilder extends BaseBuilder {
-
- /** This ID is used in plugin.xml and in each project's .project file.
- * It cannot be changed even if the class is renamed/moved */
- public static final String ID = "com.android.ide.eclipse.adt.PreCompilerBuilder"; //$NON-NLS-1$
-
- /** Flag to pass to PreCompiler builder that the build is a release build.
- */
- public final static String RELEASE_REQUESTED = "android.releaseBuild"; //$NON-NLS-1$
-
- private static final String PROPERTY_PACKAGE = "manifestPackage"; //$NON-NLS-1$
- private static final String PROPERTY_MERGE_MANIFEST = "mergeManifest"; //$NON-NLS-1$
- private static final String PROPERTY_COMPILE_RESOURCES = "compileResources"; //$NON-NLS-1$
- private static final String PROPERTY_COMPILE_BUILDCONFIG = "createBuildConfig"; //$NON-NLS-1$
- private static final String PROPERTY_BUILDCONFIG_MODE = "buildConfigMode"; //$NON-NLS-1$
-
- private static final boolean MANIFEST_MERGER_ENABLED_DEFAULT = false;
- private static final String MANIFEST_MERGER_PROPERTY = "manifestmerger.enabled"; //$NON-NLS-1$
-
- /** Merge Manifest Flag. Computed from resource delta, reset after action is taken.
- * Stored persistently in the project. */
- private boolean mMustMergeManifest = false;
- /** Resource compilation Flag. Computed from resource delta, reset after action is taken.
- * Stored persistently in the project. */
- private boolean mMustCompileResources = false;
- /** BuildConfig Flag. Computed from resource delta, reset after action is taken.
- * Stored persistently in the project. */
- private boolean mMustCreateBuildConfig = false;
- /** BuildConfig last more Flag. Computed from resource delta, reset after action is taken.
- * Stored persistently in the project. */
- private boolean mLastBuildConfigMode;
-
- /** cache of the java package defined in the manifest */
- private String mManifestPackage;
-
- /** Output folder for generated Java File. Created on the Builder init
- * @see #startupOnInitialize()
- */
- private IFolder mGenFolder;
-
- /**
- * Progress monitor used at the end of every build to refresh the content of the 'gen' folder
- * and set the generated files as derived.
- */
- private DerivedProgressMonitor mDerivedProgressMonitor;
-
- private AidlProcessor mAidlProcessor;
- private RsSourceChangeHandler mRenderScriptSourceChangeHandler;
-
- /**
- * Progress monitor waiting the end of the process to set a persistent value
- * in a file. This is typically used in conjunction with <code>IResource.refresh()</code>,
- * since this call is asynchronous, and we need to wait for it to finish for the file
- * to be known by eclipse, before we can call <code>resource.setPersistentProperty</code> on
- * a new file.
- */
- private static class DerivedProgressMonitor implements IProgressMonitor {
- private boolean mCancelled = false;
- private boolean mDone = false;
- private final IFolder mGenFolder;
-
- public DerivedProgressMonitor(IFolder genFolder) {
- mGenFolder = genFolder;
- }
-
- void reset() {
- mDone = false;
- }
-
- @Override
- public void beginTask(String name, int totalWork) {
- }
-
- @Override
- public void done() {
- if (mDone == false) {
- mDone = true;
- processChildrenOf(mGenFolder);
- }
- }
-
- private void processChildrenOf(IFolder folder) {
- IResource[] list;
- try {
- list = folder.members();
- } catch (CoreException e) {
- return;
- }
-
- for (IResource member : list) {
- if (member.exists()) {
- if (member.getType() == IResource.FOLDER) {
- processChildrenOf((IFolder) member);
- }
-
- try {
- member.setDerived(true, new NullProgressMonitor());
- } catch (CoreException e) {
- // This really shouldn't happen since we check that the resource
- // exist.
- // Worst case scenario, the resource isn't marked as derived.
- }
- }
- }
- }
-
- @Override
- public void internalWorked(double work) {
- }
-
- @Override
- public boolean isCanceled() {
- return mCancelled;
- }
-
- @Override
- public void setCanceled(boolean value) {
- mCancelled = value;
- }
-
- @Override
- public void setTaskName(String name) {
- }
-
- @Override
- public void subTask(String name) {
- }
-
- @Override
- public void worked(int work) {
- }
- }
-
- public PreCompilerBuilder() {
- super();
- }
-
- // build() returns a list of project from which this project depends for future compilation.
- @Override
- protected IProject[] build(
- int kind,
- @SuppressWarnings("rawtypes") Map args,
- IProgressMonitor monitor)
- throws CoreException {
- // get a project object
- IProject project = getProject();
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s BUILD(PRE)", project.getName());
- }
-
- // For the PreCompiler, only the library projects are considered Referenced projects,
- // as only those projects have an impact on what is generated by this builder.
- IProject[] result = null;
-
- IFolder resOutFolder = null;
-
- try {
- assert mDerivedProgressMonitor != null;
-
- mDerivedProgressMonitor.reset();
-
- // get the project info
- ProjectState projectState = Sdk.getProjectState(project);
-
- // this can happen if the project has no project.properties.
- if (projectState == null) {
- return null;
- }
-
- boolean isLibrary = projectState.isLibrary();
-
- IAndroidTarget projectTarget = projectState.getTarget();
-
- // get the libraries
- List<IProject> libProjects = projectState.getFullLibraryProjects();
- result = libProjects.toArray(new IProject[libProjects.size()]);
-
- IJavaProject javaProject = JavaCore.create(project);
-
- // Top level check to make sure the build can move forward.
- abortOnBadSetup(javaProject, projectState);
-
- // now we need to get the classpath list
- List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(javaProject);
-
- IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project);
-
- resOutFolder = getResOutFolder(androidOutputFolder);
-
- setupSourceProcessors(javaProject, projectState, sourceFolderPathList,
- androidOutputFolder);
-
- PreCompilerDeltaVisitor dv = null;
- String javaPackage = null;
- String minSdkVersion = null;
-
- if (kind == FULL_BUILD) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Start_Full_Pre_Compiler);
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s full build!", project.getName());
- }
-
- // do some clean up.
- doClean(project, monitor);
-
- mMustMergeManifest = true;
- mMustCompileResources = true;
- mMustCreateBuildConfig = true;
-
- mAidlProcessor.prepareFullBuild(project);
- mRenderScriptSourceChangeHandler.prepareFullBuild();
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Start_Inc_Pre_Compiler);
-
- // Go through the resources and see if something changed.
- // Even if the mCompileResources flag is true from a previously aborted
- // build, we need to go through the Resource delta to get a possible
- // list of aidl files to compile/remove.
- IResourceDelta delta = getDelta(project);
- if (delta == null) {
- mMustCompileResources = true;
-
- mAidlProcessor.prepareFullBuild(project);
- mRenderScriptSourceChangeHandler.prepareFullBuild();
- } else {
- dv = new PreCompilerDeltaVisitor(this, sourceFolderPathList,
- mAidlProcessor.getChangeHandler(),
- mRenderScriptSourceChangeHandler);
- delta.accept(dv);
-
- // Check to see if Manifest.xml, Manifest.java, or R.java have changed:
- mMustCompileResources |= dv.getCompileResources();
- mMustMergeManifest |= dv.hasManifestChanged();
-
- // Notify the ResourceManager:
- ResourceManager resManager = ResourceManager.getInstance();
-
- if (ResourceManager.isAutoBuilding()) {
- ProjectResources projectResources = resManager.getProjectResources(project);
-
- IdeScanningContext context = new IdeScanningContext(projectResources,
- project, true);
-
- boolean wasCleared = projectResources.ensureInitialized();
-
- if (!wasCleared) {
- resManager.processDelta(delta, context);
- }
-
- // Check whether this project or its dependencies (libraries) have
- // resources that need compilation
- if (wasCleared || context.needsFullAapt()) {
- mMustCompileResources = true;
-
- // Must also call markAaptRequested on the project to not just
- // store "aapt required" on this project, but also on any projects
- // depending on this project if it's a library project
- ResourceManager.markAaptRequested(project);
- }
-
- // Update error markers in the source editor
- if (!mMustCompileResources) {
- context.updateMarkers(false /* async */);
- }
- } // else: already processed the deltas in ResourceManager's IRawDeltaListener
-
- mAidlProcessor.doneVisiting(project);
-
- // get the java package from the visitor
- javaPackage = dv.getManifestPackage();
- minSdkVersion = dv.getMinSdkVersion();
- }
- }
-
- // Has anyone marked this project as needing aapt? Typically done when
- // one of the library projects this project depends on has changed
- mMustCompileResources |= ResourceManager.isAaptRequested(project);
-
- // if the main manifest didn't change, then we check for the library
- // ones (will trigger manifest merging too)
- if (libProjects.size() > 0) {
- for (IProject libProject : libProjects) {
- IResourceDelta delta = getDelta(libProject);
- if (delta != null) {
- PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
- project, libProject,
- "PRE:LibManifest"); //$NON-NLS-1$
- visitor.addSet(ChangedFileSetHelper.MANIFEST);
-
- ChangedFileSet textSymbolCFS = null;
- if (isLibrary == false) {
- textSymbolCFS = ChangedFileSetHelper.getTextSymbols(
- libProject);
- visitor.addSet(textSymbolCFS);
- }
-
- delta.accept(visitor);
-
- mMustMergeManifest |= visitor.checkSet(ChangedFileSetHelper.MANIFEST);
-
- if (textSymbolCFS != null) {
- mMustCompileResources |= visitor.checkSet(textSymbolCFS);
- }
-
- // no need to test others if we have all flags at true.
- if (mMustMergeManifest &&
- (mMustCompileResources || textSymbolCFS == null)) {
- break;
- }
- }
- }
- }
-
- // store the build status in the persistent storage
- saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest);
- saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
- saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);
-
- // if there was some XML errors, we just return w/o doing
- // anything since we've put some markers in the files anyway.
- if (dv != null && dv.mXmlError) {
- AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);
-
- return result;
- }
-
- if (projectState.getRenderScriptSupportMode()) {
- FullRevision minBuildToolsRev = new FullRevision(19,0,3);
- if (mBuildToolInfo.getRevision().compareTo(minBuildToolsRev) == -1) {
- String msg = "RenderScript support mode requires Build-Tools 19.0.3 or later.";
- AdtPlugin.printErrorToConsole(project, msg);
- markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
- return result;
- }
- }
-
- // get the manifest file
- IFile manifestFile = ProjectHelper.getManifest(project);
-
- if (manifestFile == null) {
- String msg = String.format(Messages.s_File_Missing,
- SdkConstants.FN_ANDROID_MANIFEST_XML);
- AdtPlugin.printErrorToConsole(project, msg);
- markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
- return result;
-
- // TODO: document whether code below that uses manifest (which is now guaranteed
- // to be null) will actually be executed or not.
- }
-
- // lets check the XML of the manifest first, if that hasn't been done by the
- // resource delta visitor yet.
- if (dv == null || dv.getCheckedManifestXml() == false) {
- BasicXmlErrorListener errorListener = new BasicXmlErrorListener();
- try {
- ManifestData parser = AndroidManifestHelper.parseUnchecked(
- new IFileWrapper(manifestFile),
- true /*gather data*/,
- errorListener);
-
- if (errorListener.mHasXmlError == true) {
- // There was an error in the manifest, its file has been marked
- // by the XmlErrorHandler. The stopBuild() call below will abort
- // this with an exception.
- String msg = String.format(Messages.s_Contains_Xml_Error,
- SdkConstants.FN_ANDROID_MANIFEST_XML);
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
- markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
- return result;
- }
-
- // Get the java package from the parser.
- // This can be null if the parsing failed because the resource is out of sync,
- // in which case the error will already have been logged anyway.
- if (parser != null) {
- javaPackage = parser.getPackage();
- minSdkVersion = parser.getMinSdkVersionString();
- }
- } catch (StreamException e) {
- handleStreamException(e);
-
- return result;
- } catch (ParserConfigurationException e) {
- String msg = String.format(
- "Bad parser configuration for %s: %s",
- manifestFile.getFullPath(),
- e.getMessage());
-
- handleException(e, msg);
- return result;
-
- } catch (SAXException e) {
- String msg = String.format(
- "Parser exception for %s: %s",
- manifestFile.getFullPath(),
- e.getMessage());
-
- handleException(e, msg);
- return result;
- } catch (IOException e) {
- String msg = String.format(
- "I/O error for %s: %s",
- manifestFile.getFullPath(),
- e.getMessage());
-
- handleException(e, msg);
- return result;
- }
- }
-
- int minSdkValue = -1;
-
- if (minSdkVersion != null) {
- try {
- minSdkValue = Integer.parseInt(minSdkVersion);
- } catch (NumberFormatException e) {
- // it's ok, it means minSdkVersion contains a (hopefully) valid codename.
- }
-
- AndroidVersion targetVersion = projectTarget.getVersion();
-
- // remove earlier marker from the manifest
- removeMarkersFromResource(manifestFile, AdtConstants.MARKER_ADT);
-
- if (minSdkValue != -1) {
- String codename = targetVersion.getCodename();
- if (codename != null) {
- // integer minSdk when the target is a preview => fatal error
- String msg = String.format(
- "Platform %1$s is a preview and requires application manifest to set %2$s to '%1$s'",
- codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_ERROR);
- return result;
- } else if (minSdkValue > targetVersion.getApiLevel()) {
- // integer minSdk is too high for the target => warning
- String msg = String.format(
- "Attribute %1$s (%2$d) is higher than the project target API level (%3$d)",
- AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
- minSdkValue, targetVersion.getApiLevel());
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_WARNING);
- }
- } else {
- // looks like the min sdk is a codename, check it matches the codename
- // of the platform
- String codename = targetVersion.getCodename();
- if (codename == null) {
- // platform is not a preview => fatal error
- String msg = String.format(
- "Manifest attribute '%1$s' is set to '%2$s'. Integer is expected.",
- AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_ERROR);
- return result;
- } else if (codename.equals(minSdkVersion) == false) {
- // platform and manifest codenames don't match => fatal error.
- String msg = String.format(
- "Value of manifest attribute '%1$s' does not match platform codename '%2$s'",
- AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, codename);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_ERROR);
- return result;
- }
-
- // if we get there, the minSdkVersion is a codename matching the target
- // platform codename. In this case we set minSdkValue to the previous API
- // level, as it's used by source processors.
- minSdkValue = targetVersion.getApiLevel();
- }
- } else if (projectTarget.getVersion().isPreview()) {
- // else the minSdkVersion is not set but we are using a preview target.
- // Display an error
- String codename = projectTarget.getVersion().getCodename();
- String msg = String.format(
- "Platform %1$s is a preview and requires application manifests to set %2$s to '%1$s'",
- codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT, msg,
- IMarker.SEVERITY_ERROR);
- return result;
- }
-
- if (javaPackage == null || javaPackage.length() == 0) {
- // looks like the AndroidManifest file isn't valid.
- String msg = String.format(Messages.s_Doesnt_Declare_Package_Error,
- SdkConstants.FN_ANDROID_MANIFEST_XML);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_ERROR);
-
- return result;
- } else if (javaPackage.indexOf('.') == -1) {
- // The application package name does not contain 2+ segments!
- String msg = String.format(
- "Application package '%1$s' must have a minimum of 2 segments.",
- SdkConstants.FN_ANDROID_MANIFEST_XML);
- AdtPlugin.printErrorToConsole(project, msg);
- BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
- msg, IMarker.SEVERITY_ERROR);
-
- return result;
- }
-
- // at this point we have the java package. We need to make sure it's not a different
- // package than the previous one that were built.
- if (javaPackage.equals(mManifestPackage) == false) {
- // The manifest package has changed, the user may want to update
- // the launch configuration
- if (mManifestPackage != null) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Checking_Package_Change);
-
- FixLaunchConfig flc = new FixLaunchConfig(project, mManifestPackage,
- javaPackage);
- flc.start();
- }
-
- // record the new manifest package, and save it.
- mManifestPackage = javaPackage;
- saveProjectStringProperty(PROPERTY_PACKAGE, mManifestPackage);
-
- // force a clean
- doClean(project, monitor);
- mMustMergeManifest = true;
- mMustCompileResources = true;
- mMustCreateBuildConfig = true;
- mAidlProcessor.prepareFullBuild(project);
- mRenderScriptSourceChangeHandler.prepareFullBuild();
-
- saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest);
- saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
- saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);
- }
-
- try {
- handleBuildConfig(args);
- } catch (IOException e) {
- handleException(e, "Failed to create BuildConfig class");
- return result;
- }
-
- // merge the manifest
- if (mMustMergeManifest) {
- boolean enabled = MANIFEST_MERGER_ENABLED_DEFAULT;
- String propValue = projectState.getProperty(MANIFEST_MERGER_PROPERTY);
- if (propValue != null) {
- enabled = Boolean.valueOf(propValue);
- }
-
- if (mergeManifest(androidOutputFolder, libProjects, enabled) == false) {
- return result;
- }
- }
-
- List<File> libProjectsOut = new ArrayList<File>(libProjects.size());
- for (IProject libProject : libProjects) {
- libProjectsOut.add(
- BaseProjectHelper.getAndroidOutputFolder(libProject)
- .getLocation().toFile());
- }
-
- // run the source processors
- int processorStatus = SourceProcessor.COMPILE_STATUS_NONE;
-
-
- try {
- processorStatus |= mAidlProcessor.compileFiles(this,
- project, projectTarget, sourceFolderPathList,
- libProjectsOut, monitor);
- } catch (Throwable t) {
- handleException(t, "Failed to run aidl. Check workspace log for detail.");
- return result;
- }
-
- try {
- processorStatus |= compileRs(minSdkValue, projectState, androidOutputFolder,
- resOutFolder, monitor);
- } catch (Throwable t) {
- handleException(t, "Failed to run renderscript. Check workspace log for detail.");
- return result;
- }
-
- // if a processor created some resources file, force recompilation of the resources.
- if ((processorStatus & SourceProcessor.COMPILE_STATUS_RES) != 0) {
- mMustCompileResources = true;
- // save the current state before attempting the compilation
- saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
- }
-
- // handle the resources, after the processors are run since some (renderscript)
- // generate resources.
- boolean compiledTheResources = mMustCompileResources;
- if (mMustCompileResources) {
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s compiling resources!", project.getName());
- }
-
- IFile proguardFile = null;
- if (projectState.getProperty(ProjectProperties.PROPERTY_PROGUARD_CONFIG) != null) {
- proguardFile = androidOutputFolder.getFile(AdtConstants.FN_AAPT_PROGUARD);
- }
-
- handleResources(project, javaPackage, projectTarget, manifestFile, resOutFolder,
- libProjects, isLibrary, proguardFile);
- }
-
- if (processorStatus == SourceProcessor.COMPILE_STATUS_NONE &&
- compiledTheResources == false) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Nothing_To_Compile);
- }
- } catch (AbortBuildException e) {
- return result;
- } finally {
- // refresh the 'gen' source folder. Once this is done with the custom progress
- // monitor to mark all new files as derived
- mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
- if (resOutFolder != null) {
- resOutFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
- }
- }
-
- return result;
- }
-
- private IFolder getResOutFolder(IFolder androidOutputFolder) {
- return androidOutputFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_BC);
- }
-
- @Override
- protected void clean(IProgressMonitor monitor) throws CoreException {
- super.clean(monitor);
-
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s CLEAN(PRE)", getProject().getName());
- }
-
- doClean(getProject(), monitor);
- if (mGenFolder != null) {
- mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
- }
- }
-
- private void doClean(IProject project, IProgressMonitor monitor) throws CoreException {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Removing_Generated_Classes);
-
- // remove all the derived resources from the 'gen' source folder.
- if (mGenFolder != null && mGenFolder.exists()) {
- // gen folder should not be derived, but previous version could set it to derived
- // so we make sure this isn't the case (or it'll get deleted by the clean)
- mGenFolder.setDerived(false, monitor);
-
- removeDerivedResources(mGenFolder, monitor);
- }
-
- // Clear the project of the generic markers
- removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_COMPILE);
- removeMarkersFromContainer(project, AdtConstants.MARKER_XML);
- removeMarkersFromContainer(project, AdtConstants.MARKER_AIDL);
- removeMarkersFromContainer(project, AdtConstants.MARKER_RENDERSCRIPT);
- removeMarkersFromContainer(project, AdtConstants.MARKER_MANIFMERGER);
- removeMarkersFromContainer(project, AdtConstants.MARKER_ANDROID);
-
- // Also clean up lint
- EclipseLintClient.clearMarkers(project);
-
- // clean the project repo
- ProjectResources res = ResourceManager.getInstance().getProjectResources(project);
- res.clear();
- }
-
- @Override
- protected void startupOnInitialize() {
- try {
- super.startupOnInitialize();
-
- IProject project = getProject();
-
- // load the previous IFolder and java package.
- mManifestPackage = loadProjectStringProperty(PROPERTY_PACKAGE);
-
- // get the source folder in which all the Java files are created
- mGenFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
- mDerivedProgressMonitor = new DerivedProgressMonitor(mGenFolder);
-
- // Load the current compile flags. We ask for true if not found to force a recompile.
- mMustMergeManifest = loadProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, true);
- mMustCompileResources = loadProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, true);
- mMustCreateBuildConfig = loadProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, true);
- Boolean v = ProjectHelper.loadBooleanProperty(project, PROPERTY_BUILDCONFIG_MODE);
- if (v == null) {
- // no previous build config mode? force regenerate
- mMustCreateBuildConfig = true;
- } else {
- mLastBuildConfigMode = v;
- }
-
- } catch (Throwable throwable) {
- AdtPlugin.log(throwable, "Failed to finish PrecompilerBuilder#startupOnInitialize()");
- }
- }
-
- private void setupSourceProcessors(@NonNull IJavaProject javaProject,
- @NonNull ProjectState projectState,
- @NonNull List<IPath> sourceFolderPathList,
- @NonNull IFolder androidOutputFolder) {
- if (mAidlProcessor == null) {
- mAidlProcessor = new AidlProcessor(javaProject, mBuildToolInfo, mGenFolder);
- } else {
- mAidlProcessor.setBuildToolInfo(mBuildToolInfo);
- }
-
- List<File> sourceFolders = Lists.newArrayListWithCapacity(sourceFolderPathList.size());
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-
- for (IPath path : sourceFolderPathList) {
- IResource resource = root.findMember(path);
- if (resource != null && resource.exists() && resource.getType() == IResource.FOLDER) {
- IPath fullPath = resource.getLocation();
- if (fullPath != null) {
- sourceFolders.add(fullPath.toFile());
- }
- }
- }
-
- RenderScriptChecker checker = new RenderScriptChecker(sourceFolders,
- androidOutputFolder.getLocation().toFile());
- mRenderScriptSourceChangeHandler = new RsSourceChangeHandler(checker);
- }
-
- private int compileRs(int minSdkValue,
- @NonNull ProjectState projectState,
- @NonNull IFolder androidOutputFolder,
- @NonNull IFolder resOutFolder,
- @NonNull IProgressMonitor monitor)
- throws IOException, InterruptedException {
- if (!mRenderScriptSourceChangeHandler.mustCompile()) {
- return SourceProcessor.COMPILE_STATUS_NONE;
- }
-
- RenderScriptChecker checker = mRenderScriptSourceChangeHandler.getChecker();
-
- List<File> inputs = checker.findInputFiles();
- List<File> importFolders = checker.getSourceFolders();
- File buildFolder = androidOutputFolder.getLocation().toFile();
-
-
- // get the renderscript target
- int rsTarget = minSdkValue == -1 ? 11 : minSdkValue;
- String rsTargetStr = projectState.getProperty(ProjectProperties.PROPERTY_RS_TARGET);
- if (rsTargetStr != null) {
- try {
- rsTarget = Integer.parseInt(rsTargetStr);
- } catch (NumberFormatException e) {
- handleException(e, String.format(
- "Property %s is not an integer.",
- ProjectProperties.PROPERTY_RS_TARGET));
- return SourceProcessor.COMPILE_STATUS_NONE;
- }
- }
-
- RenderScriptProcessor processor = new RenderScriptProcessor(
- inputs,
- importFolders,
- buildFolder,
- mGenFolder.getLocation().toFile(),
- resOutFolder.getLocation().toFile(),
- new File(buildFolder, SdkConstants.FD_RS_OBJ),
- new File(buildFolder, SdkConstants.FD_RS_LIBS),
- mBuildToolInfo,
- rsTarget,
- false /*debugBuild, always false for now*/,
- 3,
- projectState.getRenderScriptSupportMode());
-
- // clean old dependency files fiest
- checker.cleanDependencies();
-
- // then clean old output files
- processor.cleanOldOutput(checker.getOldOutputs());
-
- RenderScriptLauncher launcher = new RenderScriptLauncher(
- getProject(),
- mGenFolder,
- resOutFolder,
- monitor,
- AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE /*verbose*/);
-
- // and run the build
- processor.build(launcher);
-
- return SourceProcessor.COMPILE_STATUS_CODE | SourceProcessor.COMPILE_STATUS_RES;
- }
-
- @SuppressWarnings("deprecation")
- private void handleBuildConfig(@SuppressWarnings("rawtypes") Map args)
- throws IOException, CoreException {
- boolean debugMode = !args.containsKey(RELEASE_REQUESTED);
-
- BuildConfigGenerator generator = new BuildConfigGenerator(
- mGenFolder.getLocation().toOSString(), mManifestPackage, debugMode);
-
- if (mMustCreateBuildConfig == false) {
- // check the file is present.
- IFolder folder = getGenManifestPackageFolder();
- if (folder.exists(new Path(BuildConfigGenerator.BUILD_CONFIG_NAME)) == false) {
- mMustCreateBuildConfig = true;
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
- String.format("Class %1$s is missing!",
- BuildConfigGenerator.BUILD_CONFIG_NAME));
- } else if (debugMode != mLastBuildConfigMode) {
- // else if the build mode changed, force creation
- mMustCreateBuildConfig = true;
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
- String.format("Different build mode, must update %1$s!",
- BuildConfigGenerator.BUILD_CONFIG_NAME));
- }
- }
-
- if (mMustCreateBuildConfig) {
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s generating BuilderConfig!", getProject().getName());
- }
-
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
- String.format("Generating %1$s...", BuildConfigGenerator.BUILD_CONFIG_NAME));
- generator.generate();
-
- mMustCreateBuildConfig = false;
- saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);
- saveProjectBooleanProperty(PROPERTY_BUILDCONFIG_MODE, mLastBuildConfigMode = debugMode);
- }
- }
-
- private boolean mergeManifest(IFolder androidOutFolder, List<IProject> libProjects,
- boolean enabled) throws CoreException {
- if (DEBUG_LOG) {
- AdtPlugin.log(IStatus.INFO, "%s merging manifests!", getProject().getName());
- }
-
- IFile outFile = androidOutFolder.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
- IFile manifest = getProject().getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
-
- // remove existing markers from the manifest.
- // FIXME: only remove from manifest once the markers are put there.
- removeMarkersFromResource(getProject(), AdtConstants.MARKER_MANIFMERGER);
-
- // If the merging is not enabled or if there's no library then we simply copy the
- // manifest over.
- if (enabled == false || libProjects.size() == 0) {
- try {
- new FileOp().copyFile(manifest.getLocation().toFile(),
- outFile.getLocation().toFile());
-
- outFile.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
-
- saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest = false);
- } catch (IOException e) {
- handleException(e, "Failed to copy Manifest");
- return false;
- }
- } else {
- final ArrayList<String> errors = new ArrayList<String>();
-
- // TODO change MergerLog.wrapSdkLog by a custom IMergerLog that will create
- // and maintain error markers.
- ManifestMerger merger = new ManifestMerger(
- MergerLog.wrapSdkLog(new ILogger() {
- @Override
- public void warning(@NonNull String warningFormat, Object... args) {
- AdtPlugin.printToConsole(getProject(), String.format(warningFormat, args));
- }
-
- @Override
- public void info(@NonNull String msgFormat, Object... args) {
- AdtPlugin.printToConsole(getProject(), String.format(msgFormat, args));
- }
-
- @Override
- public void verbose(@NonNull String msgFormat, Object... args) {
- info(msgFormat, args);
- }
-
- @Override
- public void error(@Nullable Throwable t, @Nullable String errorFormat,
- Object... args) {
- errors.add(String.format(errorFormat, args));
- }
- }),
- new AdtManifestMergeCallback());
-
- File[] libManifests = new File[libProjects.size()];
- int libIndex = 0;
- for (IProject lib : libProjects) {
- libManifests[libIndex++] = lib.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML)
- .getLocation().toFile();
- }
-
- if (merger.process(
- outFile.getLocation().toFile(),
- manifest.getLocation().toFile(),
- libManifests,
- null /*injectAttributes*/, null /*packageOverride*/) == false) {
- if (errors.size() > 1) {
- StringBuilder sb = new StringBuilder();
- for (String s : errors) {
- sb.append(s).append('\n');
- }
-
- markProject(AdtConstants.MARKER_MANIFMERGER, sb.toString(),
- IMarker.SEVERITY_ERROR);
-
- } else if (errors.size() == 1) {
- markProject(AdtConstants.MARKER_MANIFMERGER, errors.get(0),
- IMarker.SEVERITY_ERROR);
- } else {
- markProject(AdtConstants.MARKER_MANIFMERGER, "Unknown error merging manifest",
- IMarker.SEVERITY_ERROR);
- }
- return false;
- }
-
- outFile.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
- saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest = false);
- }
-
- return true;
- }
-
- /**
- * Handles resource changes and regenerate whatever files need regenerating.
- * @param project the main project
- * @param javaPackage the app package for the main project
- * @param projectTarget the target of the main project
- * @param manifest the {@link IFile} representing the project manifest
- * @param libProjects the library dependencies
- * @param isLibrary if the project is a library project
- * @throws CoreException
- * @throws AbortBuildException
- */
- private void handleResources(IProject project, String javaPackage, IAndroidTarget projectTarget,
- IFile manifest, IFolder resOutFolder, List<IProject> libProjects, boolean isLibrary,
- IFile proguardFile) throws CoreException, AbortBuildException {
- // get the resource folder
- IFolder resFolder = project.getFolder(AdtConstants.WS_RESOURCES);
-
- // get the file system path
- IPath outputLocation = mGenFolder.getLocation();
- IPath resLocation = resFolder.getLocation();
- IPath manifestLocation = manifest == null ? null : manifest.getLocation();
-
- // those locations have to exist for us to do something!
- if (outputLocation != null && resLocation != null
- && manifestLocation != null) {
- String osOutputPath = outputLocation.toOSString();
- String osResPath = resLocation.toOSString();
- String osManifestPath = manifestLocation.toOSString();
-
- // remove the aapt markers
- removeMarkersFromResource(manifest, AdtConstants.MARKER_AAPT_COMPILE);
- removeMarkersFromContainer(resFolder, AdtConstants.MARKER_AAPT_COMPILE);
-
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.Preparing_Generated_Files);
-
- // we need to figure out where to store the R class.
- // get the parent folder for R.java and update mManifestPackageSourceFolder
- IFolder mainPackageFolder = getGenManifestPackageFolder();
-
- // handle libraries
- ArrayList<IFolder> libResFolders = Lists.newArrayList();
- ArrayList<Pair<File, String>> libRFiles = Lists.newArrayList();
- if (libProjects != null) {
- for (IProject lib : libProjects) {
- IFolder libResFolder = lib.getFolder(SdkConstants.FD_RES);
- if (libResFolder.exists()) {
- libResFolders.add(libResFolder);
- }
-
- try {
- // get the package of the library, and if it's different form the
- // main project, generate the R class for it too.
- String libJavaPackage = AndroidManifest.getPackage(new IFolderWrapper(lib));
- if (libJavaPackage.equals(javaPackage) == false) {
-
- IFolder libOutput = BaseProjectHelper.getAndroidOutputFolder(lib);
- File libOutputFolder = libOutput.getLocation().toFile();
-
- libRFiles.add(Pair.of(
- new File(libOutputFolder, "R.txt"),
- libJavaPackage));
-
- }
- } catch (Exception e) {
- }
- }
- }
-
- String proguardFilePath = proguardFile != null ?
- proguardFile.getLocation().toOSString(): null;
-
- File resOutFile = resOutFolder.getLocation().toFile();
- String resOutPath = resOutFile.isDirectory() ? resOutFile.getAbsolutePath() : null;
-
- execAapt(project, projectTarget, osOutputPath, resOutPath, osResPath, osManifestPath,
- mainPackageFolder, libResFolders, libRFiles, isLibrary, proguardFilePath);
- }
- }
-
- /**
- * Executes AAPT to generate R.java/Manifest.java
- * @param project the main project
- * @param projectTarget the main project target
- * @param osOutputPath the OS output path for the generated file. This is the source folder, not
- * the package folder.
- * @param osResPath the OS path to the res folder for the main project
- * @param osManifestPath the OS path to the manifest of the main project
- * @param packageFolder the IFolder that will contain the generated file. Unlike
- * <var>osOutputPath</var> this is the direct parent of the generated files.
- * If <var>customJavaPackage</var> is not null, this must match the new destination triggered
- * by its value.
- * @param libResFolders the list of res folders for the library.
- * @param libRFiles a list of R files for the libraries.
- * @param isLibrary if the project is a library project
- * @param proguardFile an optional path to store proguard information
- * @throws AbortBuildException
- */
- @SuppressWarnings("deprecation")
- private void execAapt(IProject project, IAndroidTarget projectTarget, String osOutputPath,
- String osBcOutPath, String osResPath, String osManifestPath, IFolder packageFolder,
- ArrayList<IFolder> libResFolders, List<Pair<File, String>> libRFiles,
- boolean isLibrary, String proguardFile)
- throws AbortBuildException {
-
- // We actually need to delete the manifest.java as it may become empty and
- // in this case aapt doesn't generate an empty one, but instead doesn't
- // touch it.
- IFile manifestJavaFile = packageFolder.getFile(SdkConstants.FN_MANIFEST_CLASS);
- manifestJavaFile.getLocation().toFile().delete();
-
- // launch aapt: create the command line
- ArrayList<String> array = new ArrayList<String>();
-
- String aaptPath = mBuildToolInfo.getPath(BuildToolInfo.PathId.AAPT);
-
- array.add(aaptPath);
- array.add("package"); //$NON-NLS-1$
- array.add("-m"); //$NON-NLS-1$
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
- array.add("-v"); //$NON-NLS-1$
- }
-
- if (isLibrary) {
- array.add("--non-constant-id"); //$NON-NLS-1$
- }
-
- if (libResFolders.size() > 0) {
- array.add("--auto-add-overlay"); //$NON-NLS-1$
- }
-
- // If a library or has libraries, generate a text version of the R symbols.
- File outputFolder = BaseProjectHelper.getAndroidOutputFolder(project).getLocation()
- .toFile();
-
- if (isLibrary || !libRFiles.isEmpty()) {
- array.add("--output-text-symbols"); //$NON-NLS-1$
- array.add(outputFolder.getAbsolutePath());
- }
-
- array.add("-J"); //$NON-NLS-1$
- array.add(osOutputPath);
- array.add("-M"); //$NON-NLS-1$
- array.add(osManifestPath);
- if (osBcOutPath != null) {
- array.add("-S"); //$NON-NLS-1$
- array.add(osBcOutPath);
- }
- array.add("-S"); //$NON-NLS-1$
- array.add(osResPath);
- for (IFolder libResFolder : libResFolders) {
- array.add("-S"); //$NON-NLS-1$
- array.add(libResFolder.getLocation().toOSString());
- }
-
- array.add("-I"); //$NON-NLS-1$
- array.add(projectTarget.getPath(IAndroidTarget.ANDROID_JAR));
-
- // use the proguard file
- if (proguardFile != null && proguardFile.length() > 0) {
- array.add("-G");
- array.add(proguardFile);
- }
-
- if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
- StringBuilder sb = new StringBuilder();
- for (String c : array) {
- sb.append(c);
- sb.append(' ');
- }
- String cmd_line = sb.toString();
- AdtPlugin.printToConsole(project, cmd_line);
- }
-
- // launch
- try {
- // launch the command line process
- Process process = Runtime.getRuntime().exec(
- array.toArray(new String[array.size()]));
-
- // list to store each line of stderr
- ArrayList<String> stdErr = new ArrayList<String>();
-
- // get the output and return code from the process
- int returnCode = grabProcessOutput(process, stdErr);
-
- // attempt to parse the error output
- boolean parsingError = AaptParser.parseOutput(stdErr, project);
-
- // if we couldn't parse the output we display it in the console.
- if (parsingError) {
- if (returnCode != 0) {
- AdtPlugin.printErrorToConsole(project, stdErr.toArray());
- } else {
- AdtPlugin.printBuildToConsole(BuildVerbosity.NORMAL,
- project, stdErr.toArray());
- }
- }
-
- if (returnCode != 0) {
- // if the exec failed, and we couldn't parse the error output
- // (and therefore not all files that should have been marked,
- // were marked), we put a generic marker on the project and abort.
- if (parsingError) {
- markProject(AdtConstants.MARKER_ADT,
- Messages.Unparsed_AAPT_Errors, IMarker.SEVERITY_ERROR);
- } else if (stdErr.size() == 0) {
- // no parsing error because sdterr was empty. We still need to put
- // a marker otherwise there's no user visible feedback.
- markProject(AdtConstants.MARKER_ADT,
- String.format(Messages.AAPT_Exec_Error_d, returnCode),
- IMarker.SEVERITY_ERROR);
- }
-
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- Messages.AAPT_Error);
-
- // abort if exec failed.
- throw new AbortBuildException();
- }
-
- // now if the project has libraries, R needs to be created for each libraries
- // unless this is a library.
- if (isLibrary == false && !libRFiles.isEmpty()) {
- File rFile = new File(outputFolder, SdkConstants.FN_RESOURCE_TEXT);
- // if the project has no resources, the file could not exist.
- if (rFile.isFile()) {
- // Load the full symbols from the full R.txt file.
- SymbolLoader fullSymbolValues = new SymbolLoader(rFile);
- fullSymbolValues.load();
-
- Multimap<String, SymbolLoader> libMap = ArrayListMultimap.create();
-
- // First pass processing the libraries, collecting them by packageName,
- // and ignoring the ones that have the same package name as the application
- // (since that R class was already created).
-
- for (Pair<File, String> lib : libRFiles) {
- String libPackage = lib.getSecond();
- File rText = lib.getFirst();
-
- if (rText.isFile()) {
- // load the lib symbols
- SymbolLoader libSymbols = new SymbolLoader(rText);
- libSymbols.load();
-
- // store these symbols by associating them with the package name.
- libMap.put(libPackage, libSymbols);
- }
- }
-
- // now loop on all the package names, merge all the symbols to write,
- // and write them
- for (String packageName : libMap.keySet()) {
- Collection<SymbolLoader> symbols = libMap.get(packageName);
-
- SymbolWriter writer = new SymbolWriter(osOutputPath, packageName,
- fullSymbolValues);
- for (SymbolLoader symbolLoader : symbols) {
- writer.addSymbolsToWrite(symbolLoader);
- }
- writer.write();
- }
- }
- }
-
- } catch (IOException e1) {
- // something happen while executing the process,
- // mark the project and exit
- String msg;
- String path = array.get(0);
- if (!new File(path).exists()) {
- msg = String.format(Messages.AAPT_Exec_Error_s, path);
- } else {
- String description = e1.getLocalizedMessage();
- if (e1.getCause() != null && e1.getCause() != e1) {
- description = description + ": " + e1.getCause().getLocalizedMessage();
- }
- msg = String.format(Messages.AAPT_Exec_Error_Other_s, description);
- }
-
- markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
- // Add workaround for the Linux problem described here:
- // http://developer.android.com/sdk/installing.html#troubleshooting
- // There are various posts on StackOverflow elsewhere where people are asking
- // about aapt failing to run, so even though this is documented in the
- // Troubleshooting section add an error message to help with this
- // scenario.
- if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX
- && System.getProperty("os.arch").endsWith("64") //$NON-NLS-1$ //$NON-NLS-2$
- && new File(aaptPath).exists()
- && new File("/usr/bin/apt-get").exists()) { //$NON-NLS-1$
- markProject(AdtConstants.MARKER_ADT,
- "Hint: On 64-bit systems, make sure the 32-bit libraries are installed: \"sudo apt-get install ia32-libs\" or on some systems, \"sudo apt-get install lib32z1\"",
- IMarker.SEVERITY_ERROR);
- // Note - this uses SEVERITY_ERROR even though it's really SEVERITY_INFO because
- // we want this error message to show up adjacent to the aapt error message
- // (and Eclipse sorts by priority)
- }
-
- // This interrupts the build.
- throw new AbortBuildException();
- } catch (InterruptedException e) {
- // we got interrupted waiting for the process to end...
- // mark the project and exit
- String msg = String.format(Messages.AAPT_Exec_Error_s, array.get(0));
- markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
-
- // This interrupts the build.
- throw new AbortBuildException();
- } finally {
- // we've at least attempted to run aapt, save the fact that we don't have to
- // run it again, unless there's a new resource change.
- saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES,
- mMustCompileResources = false);
- ResourceManager.clearAaptRequest(project);
- }
- }
-
- /**
- * Creates a relative {@link IPath} from a java package.
- * @param javaPackageName the java package.
- */
- private IPath getJavaPackagePath(String javaPackageName) {
- // convert the java package into path
- String[] segments = javaPackageName.split(AdtConstants.RE_DOT);
-
- StringBuilder path = new StringBuilder();
- for (String s : segments) {
- path.append(AdtConstants.WS_SEP_CHAR);
- path.append(s);
- }
-
- return new Path(path.toString());
- }
-
- /**
- * Returns an {@link IFolder} (located inside the 'gen' source folder), that matches the
- * package defined in the manifest. This {@link IFolder} may not actually exist
- * (aapt will create it anyway).
- * @return the {@link IFolder} that will contain the R class or null if
- * the folder was not found.
- * @throws CoreException
- */
- private IFolder getGenManifestPackageFolder() throws CoreException {
- // get the path for the package
- IPath packagePath = getJavaPackagePath(mManifestPackage);
-
- // get a folder for this path under the 'gen' source folder, and return it.
- // This IFolder may not reference an actual existing folder.
- return mGenFolder.getFolder(packagePath);
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java
deleted file mode 100644
index 57316f568..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerDeltaVisitor.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2007 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.builders;
-
-import com.android.SdkConstants;
-import com.android.ide.common.xml.ManifestData;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-import com.android.ide.eclipse.adt.internal.build.SourceChangeHandler;
-import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder.BaseDeltaVisitor;
-import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
-import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
-import com.android.ide.eclipse.adt.io.IFileWrapper;
-import com.google.common.collect.Lists;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-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 java.util.Arrays;
-import java.util.List;
-
-/**
- * Resource Delta visitor for the pre-compiler.
- * <p/>This delta visitor only cares about files that are the source or the result of actions of the
- * {@link PreCompilerBuilder}:
- * <ul><li>R.java/Manifest.java generated by compiling the resources</li>
- * <li>Any Java files generated by <code>aidl</code></li></ul>.
- *
- * Therefore it looks for the following:
- * <ul><li>Any modification in the resource folder</li>
- * <li>Removed files from the source folder receiving generated Java files</li>
- * <li>Any modification to aidl files.</li>
- *
- */
-class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements IResourceDeltaVisitor {
-
- // Result fields.
- private boolean mChangedManifest = false;
-
- /**
- * Compile flag. This is set to true if one of the changed/added/removed
- * files is Manifest.java, or R.java. All other file changes
- * will be taken care of by ResourceManager.
- */
- private boolean mCompileResources = false;
-
- /** Manifest check/parsing flag. */
- private boolean mCheckedManifestXml = false;
-
- /** Application Package, gathered from the parsing of the manifest */
- private String mJavaPackage = null;
- /** minSDKVersion attribute value, gathered from the parsing of the manifest */
- private String mMinSdkVersion = null;
-
- // Internal usage fields.
- /**
- * In Resource folder flag. This allows us to know if we're in the
- * resource folder.
- */
- private boolean mInRes = false;
-
- /**
- * Current Source folder. This allows us to know if we're in a source
- * folder, and which folder.
- */
- private IFolder mSourceFolder = null;
-
- /** List of source folders. */
- private final List<IPath> mSourceFolders;
- private boolean mIsGenSourceFolder = false;
-
- private final List<SourceChangeHandler> mSourceChangeHandlers = Lists.newArrayList();
- private final IWorkspaceRoot mRoot;
-
- private IFolder mAndroidOutputFolder;
-
- public PreCompilerDeltaVisitor(BaseBuilder builder, List<IPath> sourceFolders,
- SourceChangeHandler... handlers) {
- super(builder);
- mSourceFolders = sourceFolders;
- mRoot = ResourcesPlugin.getWorkspace().getRoot();
-
- mSourceChangeHandlers.addAll(Arrays.asList(handlers));
-
- mAndroidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(builder.getProject());
- }
-
- /**
- * Get whether Manifest.java, Manifest.xml, or R.java have changed
- * @return true if any of Manifest.xml, Manifest.java, or R.java have been modified
- */
- public boolean getCompileResources() {
- return mCompileResources || mChangedManifest;
- }
-
- public boolean hasManifestChanged() {
- return mChangedManifest;
- }
-
- /**
- * Returns whether the manifest file was parsed/checked for error during the resource delta
- * visiting.
- */
- public boolean getCheckedManifestXml() {
- return mCheckedManifestXml;
- }
-
- /**
- * Returns the manifest package if the manifest was checked/parsed.
- * <p/>
- * This can return null in two cases:
- * <ul>
- * <li>The manifest was not part of the resource change delta, and the manifest was
- * not checked/parsed ({@link #getCheckedManifestXml()} returns <code>false</code>)</li>
- * <li>The manifest was parsed ({@link #getCheckedManifestXml()} returns <code>true</code>),
- * but the package declaration is missing</li>
- * </ul>
- * @return the manifest package or null.
- */
- public String getManifestPackage() {
- return mJavaPackage;
- }
-
- /**
- * Returns the minSDkVersion attribute from the manifest if it was checked/parsed.
- * <p/>
- * This can return null in two cases:
- * <ul>
- * <li>The manifest was not part of the resource change delta, and the manifest was
- * not checked/parsed ({@link #getCheckedManifestXml()} returns <code>false</code>)</li>
- * <li>The manifest was parsed ({@link #getCheckedManifestXml()} returns <code>true</code>),
- * but the package declaration is missing</li>
- * </ul>
- * @return the minSdkVersion or null.
- */
- public String getMinSdkVersion() {
- return mMinSdkVersion;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.core.resources.IResourceDeltaVisitor
- * #visit(org.eclipse.core.resources.IResourceDelta)
- */
- @Override
- public boolean visit(IResourceDelta delta) throws CoreException {
- // we are only going to look for changes in res/, source folders and in
- // AndroidManifest.xml 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/, source folders or AndroidManifest.xml
-
- 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 we are at an item directly under the root directory,
- // then we are not yet in a source or resource folder
- mInRes = false;
- mSourceFolder = null;
-
- if (SdkConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) {
- // this is the resource folder that was modified. we want to
- // see its content.
-
- // since we're going to visit its children next, we set the
- // flag
- mInRes = true;
- mSourceFolder = null;
- return true;
- } else if (SdkConstants.FN_ANDROID_MANIFEST_XML.equalsIgnoreCase(segments[1])) {
- // any change in the manifest could trigger a new R.java
- // class, so we don't need to check the delta kind
- if (delta.getKind() != IResourceDelta.REMOVED) {
- // clean the error markers on the file.
- IFile manifestFile = (IFile)resource;
-
- if (manifestFile.exists()) {
- manifestFile.deleteMarkers(AdtConstants.MARKER_XML, true,
- IResource.DEPTH_ZERO);
- manifestFile.deleteMarkers(AdtConstants.MARKER_ANDROID, true,
- IResource.DEPTH_ZERO);
- }
-
- // parse the manifest for data and error
- ManifestData manifestData = AndroidManifestHelper.parse(
- new IFileWrapper(manifestFile), true /*gatherData*/, this);
-
- if (manifestData != null) {
- mJavaPackage = manifestData.getPackage();
- mMinSdkVersion = manifestData.getMinSdkVersionString();
- }
-
- mCheckedManifestXml = true;
- }
- mChangedManifest = true;
-
- // we don't want to go to the children, not like they are
- // any for this resource anyway.
- return false;
- }
- }
-
- // at this point we can either be in the source folder or in the
- // resource folder or in a different folder that contains a source
- // folder.
- // This is due to not all source folder being src/. Some could be
- // something/somethingelse/src/
-
- // so first we test if we already know we are in a source or
- // resource folder.
-
- if (mSourceFolder != null) {
- // if we are in the res folder, we are looking for the following changes:
- // - added/removed/modified aidl files.
- // - missing R.java file
-
- // if the resource is a folder, we just go straight to the children
- if (resource.getType() == IResource.FOLDER) {
- return true;
- }
-
- if (resource.getType() != IResource.FILE) {
- return false;
- }
- IFile file = (IFile)resource;
-
- // get the modification kind
- int kind = delta.getKind();
-
- // we process normal source folder and the 'gen' source folder differently.
- if (mIsGenSourceFolder) {
- // this is the generated java file source folder.
- // - if R.java/Manifest.java are removed/modified, we recompile the resources
- // - if aidl files are removed/modified, we recompile them.
-
- boolean outputWarning = false;
-
- String fileName = resource.getName();
-
- // Special case of R.java/Manifest.java.
- if (SdkConstants.FN_RESOURCE_CLASS.equals(fileName) ||
- SdkConstants.FN_MANIFEST_CLASS.equals(fileName)) {
- // if it was removed, there's a possibility that it was removed due to a
- // package change, or an aidl that was removed, but the only thing
- // that will happen is that we'll have an extra build. Not much of a problem.
- mCompileResources = true;
-
- // we want a warning
- outputWarning = true;
- } else {
- // look to see if this file was generated by a processor.
- for (SourceChangeHandler handler : mSourceChangeHandlers) {
- if (handler.handleGeneratedFile(file, kind)) {
- outputWarning = true;
- break; // there shouldn't be 2 processors that handle the same file.
- }
- }
- }
-
- if (outputWarning) {
- if (kind == IResourceDelta.REMOVED) {
- // We print an error just so that it's red, but it's just a warning really.
- String msg = String.format(Messages.s_Removed_Recreating_s, fileName);
- AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
- } else if (kind == IResourceDelta.CHANGED) {
- // the file was modified manually! we can't allow it.
- String msg = String.format(Messages.s_Modified_Manually_Recreating_s,
- fileName);
- AdtPlugin.printErrorToConsole(mBuilder.getProject(), msg);
- }
- }
- } else {
- // this is another source folder.
- for (SourceChangeHandler handler : mSourceChangeHandlers) {
- handler.handleSourceFile(file, kind);
- }
- }
-
- // no children.
- return false;
- } else if (mInRes) {
- // if we are in the res folder, we are looking for the following
- // changes:
- // - added/removed/modified xml files.
- // - added/removed files of any other type
-
- // if the resource is a folder, we just go straight to the
- // children
- if (resource.getType() == IResource.FOLDER) {
- return true;
- }
-
- // get the extension of the resource
- String ext = resource.getFileExtension();
- int kind = delta.getKind();
-
- String p = resource.getProjectRelativePath().toString();
- String message = null;
- switch (kind) {
- case IResourceDelta.CHANGED:
- // display verbose message
- message = String.format(Messages.s_Modified_Recreating_s, p);
- break;
- case IResourceDelta.ADDED:
- // display verbose message
- message = String.format(Messages.Added_s_s_Needs_Updating, p,
- SdkConstants.FN_RESOURCE_CLASS);
- break;
- case IResourceDelta.REMOVED:
- // display verbose message
- message = String.format(Messages.s_Removed_s_Needs_Updating, p,
- SdkConstants.FN_RESOURCE_CLASS);
- break;
- }
- if (message != null) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE,
- mBuilder.getProject(), message);
- }
-
- // If it's an XML resource, check the syntax
- if (SdkConstants.EXT_XML.equalsIgnoreCase(ext) && kind != IResourceDelta.REMOVED) {
- // check xml Validity
- mBuilder.checkXML(resource, this);
- }
- // Whether or not to generate R.java for a changed resource is taken care of by the
- // Resource Manager.
- } else if (resource instanceof IFolder) {
- // first check if we are in the android output folder.
- if (resource.equals(mAndroidOutputFolder)) {
- // we want to visit the merged manifest.
- return true;
- }
-
- // in this case we may be inside a folder that contains a source
- // folder, go through the list of known source folders
-
- for (IPath sourceFolderPath : mSourceFolders) {
- // first check if they match exactly.
- if (sourceFolderPath.equals(path)) {
- // this is a source folder!
- mInRes = false;
- mSourceFolder = getFolder(sourceFolderPath); // all non null due to test above
- mIsGenSourceFolder = path.segmentCount() == 2 &&
- path.segment(1).equals(SdkConstants.FD_GEN_SOURCES);
- return true;
- }
-
- // check if we are on the way to a source folder.
- int count = sourceFolderPath.matchingFirstSegments(path);
- if (count == path.segmentCount()) {
- mInRes = false;
- return true;
- }
- }
-
- // if we're here, we are visiting another folder
- // like /$Project/bin/ for instance (we get notified for changes
- // in .class!)
- // This could also be another source folder and we have found
- // R.java in a previous source folder
- // We don't want to visit its children
- return false;
- }
-
- return false;
- }
-
- /**
- * Returns a handle to the folder identified by the given path in this container.
- * <p/>The different with {@link IContainer#getFolder(IPath)} is that this returns a non
- * null object only if the resource actually exists and is a folder (and not a file)
- * @param path the path of the folder to return.
- * @return a handle to the folder if it exists, or null otherwise.
- */
- private IFolder getFolder(IPath path) {
- IResource resource = mRoot.findMember(path);
- if (resource != null && resource.exists() && resource.getType() == IResource.FOLDER) {
- return (IFolder)resource;
- }
-
- return null;
- }
-
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
deleted file mode 100644
index 8e01cca29..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/ResourceManagerBuilder.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2007 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.builders;
-
-import com.android.SdkConstants;
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.internal.build.Messages;
-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;
-import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
-import com.android.sdklib.BuildToolInfo;
-import com.android.sdklib.IAndroidTarget;
-import com.android.utils.Pair;
-
-import org.eclipse.core.resources.IFolder;
-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.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Resource manager builder whose only purpose is to refresh the resource folder
- * so that the other builder use an up to date version.
- */
-public class ResourceManagerBuilder extends BaseBuilder {
-
- public static final String ID = "com.android.ide.eclipse.adt.ResourceManagerBuilder"; //$NON-NLS-1$
-
- public ResourceManagerBuilder() {
- super();
- }
-
- @Override
- protected void clean(IProgressMonitor monitor) throws CoreException {
- super.clean(monitor);
-
- // Get the project.
- IProject project = getProject();
-
- // Clear the project of the generic markers
- removeMarkersFromContainer(project, AdtConstants.MARKER_ADT);
- }
-
- // build() returns a list of project from which this project depends for future compilation.
- @SuppressWarnings("unchecked")
- @Override
- protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
- throws CoreException {
- // Get the project.
- final IProject project = getProject();
- IJavaProject javaProject = JavaCore.create(project);
-
- // Clear the project of the generic markers
- removeMarkersFromContainer(project, AdtConstants.MARKER_ADT);
-
- // check for existing target marker, in which case we abort.
- // (this means: no SDK, no target, or unresolvable target.)
- try {
- abortOnBadSetup(javaProject, null);
- } catch (AbortBuildException e) {
- return null;
- }
-
- // Check the compiler compliance level, displaying the error message
- // since this is the first builder.
- Pair<Integer, String> result = ProjectHelper.checkCompilerCompliance(project);
- String errorMessage = null;
- switch (result.getFirst().intValue()) {
- case ProjectHelper.COMPILER_COMPLIANCE_LEVEL:
- errorMessage = Messages.Requires_Compiler_Compliance_s;
- break;
- case ProjectHelper.COMPILER_COMPLIANCE_SOURCE:
- errorMessage = Messages.Requires_Source_Compatibility_s;
- break;
- case ProjectHelper.COMPILER_COMPLIANCE_CODEGEN_TARGET:
- errorMessage = Messages.Requires_Class_Compatibility_s;
- break;
- }
-
- if (errorMessage != null) {
- errorMessage = String.format(errorMessage,
- result.getSecond() == null ? "(no value)" : result.getSecond());
-
- if (JavaCore.VERSION_1_7.equals(result.getSecond())) {
- // If the user is trying to target 1.7 but compiling with something older,
- // the error message can be a bit misleading; instead point them in the
- // direction of updating the project's build target.
- Sdk currentSdk = Sdk.getCurrent();
- if (currentSdk != null) {
- IAndroidTarget target = currentSdk.getTarget(project.getProject());
- if (target != null && target.getVersion().getApiLevel() < 19) {
- errorMessage = "Using 1.7 requires compiling with Android 4.4 " +
- "(KitKat); currently using " + target.getVersion();
- }
-
- ProjectState projectState = Sdk.getProjectState(project);
- if (projectState != null) {
- BuildToolInfo buildToolInfo = projectState.getBuildToolInfo();
- if (buildToolInfo == null) {
- buildToolInfo = currentSdk.getLatestBuildTool();
- }
- if (buildToolInfo != null && buildToolInfo.getRevision().getMajor() < 19) {
- errorMessage = "Using 1.7 requires using Android Build Tools " +
- "version 19 or later; currently using " +
- buildToolInfo.getRevision();
- }
- }
- }
- }
-
- markProject(AdtConstants.MARKER_ADT, errorMessage, IMarker.SEVERITY_ERROR);
- AdtPlugin.printErrorToConsole(project, errorMessage);
-
- return null;
- }
-
- // Check that the SDK directory has been setup.
- String osSdkFolder = AdtPlugin.getOsSdkFolder();
-
- if (osSdkFolder == null || osSdkFolder.length() == 0) {
- AdtPlugin.printErrorToConsole(project, Messages.No_SDK_Setup_Error);
- markProject(AdtConstants.MARKER_ADT, Messages.No_SDK_Setup_Error,
- IMarker.SEVERITY_ERROR);
-
- return null;
- }
-
- // check the 'gen' source folder is present
- boolean hasGenSrcFolder = false; // whether the project has a 'gen' source folder setup
-
- IClasspathEntry[] classpaths = javaProject.readRawClasspath();
- if (classpaths != null) {
- for (IClasspathEntry e : classpaths) {
- if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
- IPath path = e.getPath();
- if (path.segmentCount() == 2 &&
- path.segment(1).equals(SdkConstants.FD_GEN_SOURCES)) {
- hasGenSrcFolder = true;
- break;
- }
- }
- }
- }
-
- boolean genFolderPresent = false; // whether the gen folder actually exists
- IResource resource = project.findMember(SdkConstants.FD_GEN_SOURCES);
- genFolderPresent = resource != null && resource.exists();
-
- if (hasGenSrcFolder == false && genFolderPresent) {
- // No source folder setup for 'gen' in the project, but there's already a
- // 'gen' resource (file or folder).
- String message;
- if (resource.getType() == IResource.FOLDER) {
- // folder exists already! This is an error. If the folder had been created
- // by the NewProjectWizard, it'd be a source folder.
- message = String.format("%1$s already exists but is not a source folder. Convert to a source folder or rename it.",
- resource.getFullPath().toString());
- } else {
- // resource exists but is not a folder.
- message = String.format(
- "Resource %1$s is in the way. ADT needs a source folder called 'gen' to work. Rename or delete resource.",
- resource.getFullPath().toString());
- }
-
- AdtPlugin.printErrorToConsole(project, message);
- markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
-
- return null;
- } else if (hasGenSrcFolder == false || genFolderPresent == false) {
- // either there is no 'gen' source folder in the project (older SDK),
- // or the folder does not exist (was deleted, or was a fresh svn checkout maybe.)
-
- // In case we are migrating from an older SDK, we go through the current source
- // folders and delete the generated Java files.
- List<IPath> sourceFolders = BaseProjectHelper.getSourceClasspaths(javaProject);
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- for (IPath path : sourceFolders) {
- IResource member = root.findMember(path);
- if (member != null) {
- removeDerivedResources(member, monitor);
- }
- }
-
- // create the new source folder, if needed
- IFolder genFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
- if (genFolderPresent == false) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
- "Creating 'gen' source folder for generated Java files");
- genFolder.create(true /* force */, true /* local */,
- new SubProgressMonitor(monitor, 10));
- }
-
- // add it to the source folder list, if needed only (or it will throw)
- if (hasGenSrcFolder == false) {
- IClasspathEntry[] entries = javaProject.getRawClasspath();
- entries = ProjectHelper.addEntryToClasspath(entries,
- JavaCore.newSourceEntry(genFolder.getFullPath()));
- javaProject.setRawClasspath(entries, new SubProgressMonitor(monitor, 10));
- }
-
- // refresh specifically the gen folder first, as it may break the build
- // if it doesn't arrive in time then refresh the whole project as usual.
- genFolder.refreshLocal(IResource.DEPTH_ZERO, new SubProgressMonitor(monitor, 10));
- project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 10));
-
- // it seems like doing this fails to properly rebuild the project. the Java builder
- // running right after this builder will not see the gen folder, and will not be
- // restarted after this build. Therefore in this particular case, we start another
- // build asynchronously so that it's rebuilt after this build.
- launchJob(new Job("rebuild") {
- @Override
- protected IStatus run(IProgressMonitor m) {
- try {
- project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, m);
- return Status.OK_STATUS;
- } catch (CoreException e) {
- return e.getStatus();
- }
- }
- });
-
- }
-
- // convert older projects which use bin as the eclipse output folder into projects
- // using bin/classes
- IFolder androidOutput = BaseProjectHelper.getAndroidOutputFolder(project);
- IFolder javaOutput = BaseProjectHelper.getJavaOutputFolder(project);
- if (androidOutput.exists() == false || javaOutput == null ||
- javaOutput.getParent().equals(androidOutput) == false) {
- // get what we want as the new java output.
- IFolder newJavaOutput = androidOutput.getFolder(SdkConstants.FD_CLASSES_OUTPUT);
-
- if (androidOutput.exists() == false) {
- androidOutput.create(true /*force*/, true /*local*/, monitor);
- }
-
- if (newJavaOutput.exists() == false) {
- newJavaOutput.create(true /*force*/, true /*local*/, monitor);
- }
-
- // set the java output to this project.
- javaProject.setOutputLocation(newJavaOutput.getFullPath(), monitor);
-
- // need to do a full build. Can't build while we're already building, so launch a
- // job to build it right after this build
- launchJob(new Job("rebuild") {
- @Override
- protected IStatus run(IProgressMonitor jobMonitor) {
- try {
- project.build(IncrementalProjectBuilder.CLEAN_BUILD, jobMonitor);
- return Status.OK_STATUS;
- } catch (CoreException e) {
- return e.getStatus();
- }
- }
- });
- }
-
- // check that we have bin/res/
- IFolder binResFolder = androidOutput.getFolder(SdkConstants.FD_RESOURCES);
- if (binResFolder.exists() == false) {
- binResFolder.create(true /* force */, true /* local */,
- new SubProgressMonitor(monitor, 10));
- project.refreshLocal(IResource.DEPTH_ONE, new SubProgressMonitor(monitor, 10));
- }
-
- // Check the preference to be sure we are supposed to refresh
- // the folders.
- if (AdtPrefs.getPrefs().getBuildForceResResfresh()) {
- AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, Messages.Refreshing_Res);
-
- // refresh the res folder.
- IFolder resFolder = project.getFolder(AdtConstants.WS_RESOURCES);
- resFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
-
- // Also refresh the assets folder to make sure the ApkBuilder
- // will now it's changed and will force a new resource packaging.
- IFolder assetsFolder = project.getFolder(AdtConstants.WS_ASSETS);
- assetsFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
- }
-
- return null;
- }
-}