summaryrefslogtreecommitdiffstats
path: root/tools/sdkmanager
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2009-09-28 16:25:45 -0700
committerXavier Ducrohet <xav@android.com>2009-09-28 16:30:13 -0700
commitcc02b85ba63e5029ec279a39f1db82a2c6b55b31 (patch)
tree07598e1fae1fd9b82989915a2ba93d16260cfccc /tools/sdkmanager
parent9e4715e6d94e300605ab845c2e68bddaf8c23c8f (diff)
downloadandroid_development-cc02b85ba63e5029ec279a39f1db82a2c6b55b31.tar.gz
android_development-cc02b85ba63e5029ec279a39f1db82a2c6b55b31.tar.bz2
android_development-cc02b85ba63e5029ec279a39f1db82a2c6b55b31.zip
Add support for 'android update test-project'.
This is only to be used to update the location of the main project. To update other properties, 'update project' can be used. Change-Id: I96ff44295460c7e331953263abccea17108d5a70
Diffstat (limited to 'tools/sdkmanager')
-rw-r--r--tools/sdkmanager/app/src/com/android/sdkmanager/Main.java26
-rw-r--r--tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java8
-rw-r--r--tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java154
3 files changed, 127 insertions, 61 deletions
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
index c691af726..201c2fed4 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -239,6 +239,10 @@ public class Main {
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
updateProject();
+ } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
+ SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
+ updateTestProject();
+
} else if (verb == null && directObject == null) {
showMainWindow();
@@ -345,7 +349,12 @@ public class Main {
if (parentProject.isAbsolute() == false) {
// if the path is not absolute, we need to resolve it based on the
// destination path of the project
- parentProject = new File(projectDir, pathToMainProject);
+ try {
+ parentProject = new File(projectDir, pathToMainProject).getCanonicalFile();
+ } catch (IOException e) {
+ errorAndExit("Unable to resolve Main project's directory: %1$s",
+ pathToMainProject);
+ }
}
if (parentProject.isDirectory() == false) {
@@ -491,6 +500,21 @@ public class Main {
}
/**
+ * Updates an existing test project with a new path to the main project.
+ */
+ private void updateTestProject() {
+ ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
+ mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+ mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+ OutputLevel.NORMAL,
+ mSdkLog);
+
+ String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+ creator.updateTestProject(projectDir, mSdkCommandLine.getParamTestProjectMain());
+ }
+
+ /**
* Adjusts the project location to make it absolute & canonical relative to the
* working directory, if any.
*
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
index 35bbd0dee..27afd481f 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -192,10 +192,10 @@ class SdkCommandLine extends CommandLineProcessor {
VERB_UPDATE, OBJECT_PROJECT,
"p", KEY_PATH,
"Location path of the project", null);
- define(Mode.STRING, true,
+ define(Mode.STRING, false,
VERB_UPDATE, OBJECT_PROJECT,
"t", KEY_TARGET_ID,
- "Target id to set for the project", -1);
+ "Target id to set for the project", null);
define(Mode.STRING, false,
VERB_UPDATE, OBJECT_PROJECT,
"n", KEY_NAME,
@@ -214,7 +214,7 @@ class SdkCommandLine extends CommandLineProcessor {
define(Mode.STRING, true,
VERB_UPDATE, OBJECT_TEST_PROJECT,
"m", KEY_MAIN_PROJECT,
- "Location path of the project to test", null);
+ "Location path of the project to test, relative to the new project", null);
}
@Override
@@ -290,6 +290,6 @@ class SdkCommandLine extends CommandLineProcessor {
/** Helper to retrieve the --main value. */
public String getParamTestProjectMain() {
- return ((String) getValue(null, OBJECT_TEST_PROJECT, KEY_MAIN_PROJECT));
+ return ((String) getValue(null, null, KEY_MAIN_PROJECT));
}
}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
index c4ab013f7..639479584 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
@@ -21,6 +21,7 @@ import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import com.android.sdklib.xml.AndroidManifest;
+import com.android.sdklib.xml.AndroidXPathFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
@@ -31,18 +32,13 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
/**
* Creates the basic files needed to get an Android project up and running.
@@ -385,23 +381,14 @@ public class ProjectCreator {
* @param projectName The project name from --name. Can be null.
*/
public void updateProject(String folderPath, IAndroidTarget target, String projectName) {
- // project folder must exist and be a directory, since this is an update
- File projectFolder = new File(folderPath);
- if (!projectFolder.isDirectory()) {
- mLog.error(null, "Project folder '%1$s' is not a valid directory, this is not an Android project you can update.",
- projectFolder);
+ // since this is an update, check the folder does point to a project
+ File androidManifest = checkProjectFolder(folderPath);
+ if (androidManifest == null) {
return;
}
- // Check AndroidManifest.xml is present
- File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
- if (!androidManifest.isFile()) {
- mLog.error(null,
- "%1$s not found in '%2$s', this is not an Android project you can update.",
- SdkConstants.FN_ANDROID_MANIFEST_XML,
- folderPath);
- return;
- }
+ // get the parent File.
+ File projectFolder = androidManifest.getParentFile();
// Check there's a default.properties with a target *or* --target was specified
ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT);
@@ -483,9 +470,16 @@ public class ProjectCreator {
keywords.put(PH_PROJECT_NAME, projectName);
} else {
extractPackageFromManifest(androidManifest, keywords);
- if (keywords.containsKey(PH_ACTIVITY_NAME)) {
+ if (keywords.containsKey(PH_ACTIVITY_ENTRY_NAME)) {
+ String activity = keywords.get(PH_ACTIVITY_ENTRY_NAME);
+ // keep only the last segment if applicable
+ int pos = activity.lastIndexOf('.');
+ if (pos != -1) {
+ activity = activity.substring(pos + 1);
+ }
+
// Use the activity as project name
- keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
+ keywords.put(PH_PROJECT_NAME, activity);
} else {
// We need a project name. Just pick up the basename of the project
// directory.
@@ -511,6 +505,84 @@ public class ProjectCreator {
}
/**
+ * Updates a test project with a new path to the main (tested) project.
+ * @param folderPath the path of the test project.
+ * @param pathToMainProject the path to the main project, relative to the test project.
+ */
+ public void updateTestProject(final String folderPath, final String pathToMainProject) {
+ // since this is an update, check the folder does point to a project
+ if (checkProjectFolder(folderPath) == null) {
+ return;
+ }
+
+ // check the path to the main project is valid.
+ File mainProject = new File(pathToMainProject);
+ String resolvedPath;
+ if (mainProject.isAbsolute() == false) {
+ mainProject = new File(folderPath, pathToMainProject);
+ try {
+ resolvedPath = mainProject.getCanonicalPath();
+ } catch (IOException e) {
+ mLog.error(e, "Unable to resolve path to main project: %1$s", pathToMainProject);
+ return;
+ }
+ } else {
+ resolvedPath = mainProject.getAbsolutePath();
+ }
+
+ println("Resolved location of main project to: %1$s", resolvedPath);
+
+ // check the main project exists
+ if (checkProjectFolder(resolvedPath) == null) {
+ return;
+ }
+
+ ProjectProperties props = ProjectProperties.create(folderPath, PropertyType.BUILD);
+
+ // set or replace the path to the main project
+ props.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, pathToMainProject);
+ try {
+ props.save();
+ println("Updated %1$s", PropertyType.BUILD.getFilename());
+ } catch (IOException e) {
+ mLog.error(e, "Failed to write %1$s file in '%2$s'",
+ PropertyType.BUILD.getFilename(),
+ folderPath);
+ return;
+ }
+ }
+
+ /**
+ * Checks whether the give <var>folderPath</var> is a valid project folder, and returns
+ * a {@link File} to the AndroidManifest.xml file.
+ * <p/>This checks that the folder exists and contains an AndroidManifest.xml file in it.
+ * <p/>Any error are output using {@link #mLog}.
+ * @param folderPath the folder to check
+ * @return a {@link File} to the AndroidManifest.xml file, or null otherwise.
+ */
+ private File checkProjectFolder(String folderPath) {
+ // project folder must exist and be a directory, since this is an update
+ File projectFolder = new File(folderPath);
+ if (!projectFolder.isDirectory()) {
+ mLog.error(null, "Project folder '%1$s' is not a valid directory, this is not an Android project you can update.",
+ projectFolder);
+ return null;
+ }
+
+ // Check AndroidManifest.xml is present
+ File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
+ if (!androidManifest.isFile()) {
+ mLog.error(null,
+ "%1$s not found in '%2$s', this is not an Android project you can update.",
+ SdkConstants.FN_ANDROID_MANIFEST_XML,
+ folderPath);
+ return null;
+ }
+
+ return androidManifest;
+ }
+
+ /**
* Returns true if any line of the input file contains the requested regexp.
*/
private boolean checkFileContainsRegexp(File file, String regexp) {
@@ -538,7 +610,7 @@ public class ProjectCreator {
* Extracts a "full" package & activity name from an AndroidManifest.xml.
* <p/>
* The keywords dictionary is always filed the package name under the key {@link #PH_PACKAGE}.
- * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_NAME}.
+ * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_ENTRY_NAME}.
* When no activity is found, this key is not created.
*
* @param manifestFile The AndroidManifest.xml file
@@ -548,37 +620,7 @@ public class ProjectCreator {
private boolean extractPackageFromManifest(File manifestFile,
Map<String, String> outKeywords) {
try {
- final String nsPrefix = "android";
- final String nsURI = SdkConstants.NS_RESOURCES;
-
- XPath xpath = XPathFactory.newInstance().newXPath();
-
- xpath.setNamespaceContext(new NamespaceContext() {
- public String getNamespaceURI(String prefix) {
- if (nsPrefix.equals(prefix)) {
- return nsURI;
- }
- return XMLConstants.NULL_NS_URI;
- }
-
- public String getPrefix(String namespaceURI) {
- if (nsURI.equals(namespaceURI)) {
- return nsPrefix;
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public Iterator getPrefixes(String namespaceURI) {
- if (nsURI.equals(namespaceURI)) {
- ArrayList<String> list = new ArrayList<String>();
- list.add(nsPrefix);
- return list.iterator();
- }
- return null;
- }
-
- });
+ XPath xpath = AndroidXPathFactory.newXPath();
InputSource source = new InputSource(new FileReader(manifestFile));
String packageName = xpath.evaluate("/manifest/@package", source);
@@ -592,7 +634,7 @@ public class ProjectCreator {
String expression = String.format("/manifest/application/activity" +
"[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
"intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
- "/@%1$s:name", nsPrefix);
+ "/@%1$s:name", AndroidXPathFactory.DEFAULT_NS_PREFIX);
NodeList activityNames = (NodeList) xpath.evaluate(expression, source,
XPathConstants.NODESET);
@@ -632,9 +674,9 @@ public class ProjectCreator {
if (activityName.length() == 0) {
mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
"No activity will be generated.",
- nsPrefix, manifestFile.getName());
+ AndroidXPathFactory.DEFAULT_NS_PREFIX, manifestFile.getName());
} else {
- outKeywords.put(PH_ACTIVITY_NAME, activityName);
+ outKeywords.put(PH_ACTIVITY_ENTRY_NAME, activityName);
}
outKeywords.put(PH_PACKAGE, packageName);