Merge change I663d4cb7 into eclair
* changes: Update the project creation (from the command line):
This commit is contained in:
@@ -460,7 +460,7 @@ class CommandLineProcessor {
|
||||
stdout("\nValid actions are composed of a verb and an optional direct object:");
|
||||
for (String[] action : mActions) {
|
||||
|
||||
stdout("- %1$6s %2$-7s: %3$s",
|
||||
stdout("- %1$6s %2$-12s: %3$s",
|
||||
action[ACTION_VERB_INDEX],
|
||||
action[ACTION_OBJECT_INDEX],
|
||||
action[ACTION_DESC_INDEX]);
|
||||
|
||||
@@ -28,17 +28,27 @@ import com.android.sdklib.internal.avd.HardwareProperties;
|
||||
import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
|
||||
import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
|
||||
import com.android.sdklib.internal.project.ProjectCreator;
|
||||
import com.android.sdklib.internal.project.ProjectProperties;
|
||||
import com.android.sdklib.internal.project.ProjectCreator.OutputLevel;
|
||||
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
|
||||
import com.android.sdklib.xml.AndroidXPathFactory;
|
||||
import com.android.sdkmanager.internal.repository.AboutPage;
|
||||
import com.android.sdkmanager.internal.repository.SettingsPage;
|
||||
import com.android.sdkuilib.repository.UpdaterWindow;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
/**
|
||||
* Main class for the 'android' application.
|
||||
*/
|
||||
@@ -221,6 +231,10 @@ public class Main {
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
createProject();
|
||||
|
||||
} else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
|
||||
createTestProject();
|
||||
|
||||
} else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
updateProject();
|
||||
@@ -314,9 +328,112 @@ public class Main {
|
||||
packageName,
|
||||
activityName,
|
||||
target,
|
||||
false /* isTestProject*/);
|
||||
null /*pathToMain*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Android test project based on command-line parameters
|
||||
*/
|
||||
private void createTestProject() {
|
||||
|
||||
String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
|
||||
|
||||
// first check the path of the parent project, and make sure it's valid.
|
||||
String pathToMainProject = mSdkCommandLine.getParamTestProjectMain();
|
||||
|
||||
File parentProject = new File(pathToMainProject);
|
||||
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);
|
||||
}
|
||||
|
||||
if (parentProject.isDirectory() == false) {
|
||||
errorAndExit("Main project's directory does not exist: %1$s",
|
||||
pathToMainProject);
|
||||
}
|
||||
|
||||
// now look for a manifest in there
|
||||
File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML);
|
||||
if (manifest.isFile() == false) {
|
||||
errorAndExit("No AndroidManifest.xml file found in the main project directory: %1$s",
|
||||
parentProject.getAbsolutePath());
|
||||
}
|
||||
|
||||
// now query the manifest for the package file.
|
||||
XPath xpath = AndroidXPathFactory.newXPath();
|
||||
String packageName, activityName;
|
||||
|
||||
try {
|
||||
packageName = xpath.evaluate("/manifest/@package",
|
||||
new InputSource(new FileInputStream(manifest)));
|
||||
|
||||
mSdkLog.printf("Found main project package: %1$s\n", packageName);
|
||||
|
||||
// now get the name of the first activity we find
|
||||
activityName = xpath.evaluate("/manifest/application/activity[1]/@android:name",
|
||||
new InputSource(new FileInputStream(manifest)));
|
||||
// xpath will return empty string when there's no match
|
||||
if (activityName == null || activityName.length() == 0) {
|
||||
activityName = null;
|
||||
} else {
|
||||
mSdkLog.printf("Found main project activity: %1$s\n", activityName);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// this shouldn't happen as we test it above.
|
||||
errorAndExit("No AndroidManifest.xml file found in main project.");
|
||||
return; // this is not strictly needed because errorAndExit will stop the execution,
|
||||
// but this makes the java compiler happy, wrt to uninitialized variables.
|
||||
} catch (XPathExpressionException e) {
|
||||
// looks like the main manifest is not valid.
|
||||
errorAndExit("Unable to parse main project manifest to get information.");
|
||||
return; // this is not strictly needed because errorAndExit will stop the execution,
|
||||
// but this makes the java compiler happy, wrt to uninitialized variables.
|
||||
}
|
||||
|
||||
// now get the target hash
|
||||
ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(),
|
||||
PropertyType.DEFAULT);
|
||||
String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET);
|
||||
if (targetHash == null) {
|
||||
errorAndExit("Couldn't find the main project target");
|
||||
}
|
||||
|
||||
// and resolve it.
|
||||
IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
|
||||
if (target == null) {
|
||||
errorAndExit(
|
||||
"Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.",
|
||||
targetHash);
|
||||
}
|
||||
|
||||
mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());
|
||||
|
||||
ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
|
||||
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
||||
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
||||
OutputLevel.NORMAL,
|
||||
mSdkLog);
|
||||
|
||||
String projectName = mSdkCommandLine.getParamName();
|
||||
|
||||
if (projectName != null &&
|
||||
!ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
|
||||
errorAndExit(
|
||||
"Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
|
||||
projectName, ProjectCreator.CHARS_PROJECT_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
creator.createProject(projectDir,
|
||||
projectName,
|
||||
packageName,
|
||||
activityName,
|
||||
target,
|
||||
pathToMainProject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates an existing Android project based on command-line parameters
|
||||
*/
|
||||
|
||||
@@ -31,28 +31,30 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
public final static String VERB_DELETE = "delete";
|
||||
public final static String VERB_UPDATE = "update";
|
||||
|
||||
public static final String OBJECT_AVD = "avd";
|
||||
public static final String OBJECT_AVDS = "avds";
|
||||
public static final String OBJECT_TARGET = "target";
|
||||
public static final String OBJECT_TARGETS = "targets";
|
||||
public static final String OBJECT_PROJECT = "project";
|
||||
public static final String OBJECT_ADB = "adb";
|
||||
public static final String OBJECT_AVD = "avd";
|
||||
public static final String OBJECT_AVDS = "avds";
|
||||
public static final String OBJECT_TARGET = "target";
|
||||
public static final String OBJECT_TARGETS = "targets";
|
||||
public static final String OBJECT_PROJECT = "project";
|
||||
public static final String OBJECT_TEST_PROJECT = "test-project";
|
||||
public static final String OBJECT_ADB = "adb";
|
||||
|
||||
public static final String ARG_ALIAS = "alias";
|
||||
public static final String ARG_ACTIVITY = "activity";
|
||||
public static final String ARG_ALIAS = "alias";
|
||||
public static final String ARG_ACTIVITY = "activity";
|
||||
|
||||
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
|
||||
public static final String KEY_PACKAGE = "package";
|
||||
public static final String KEY_MODE = "mode";
|
||||
public static final String KEY_TARGET_ID = OBJECT_TARGET;
|
||||
public static final String KEY_NAME = "name";
|
||||
public static final String KEY_PATH = "path";
|
||||
public static final String KEY_FILTER = "filter";
|
||||
public static final String KEY_SKIN = "skin";
|
||||
public static final String KEY_SDCARD = "sdcard";
|
||||
public static final String KEY_FORCE = "force";
|
||||
public static final String KEY_RENAME = "rename";
|
||||
public static final String KEY_SUBPROJECTS = "subprojects";
|
||||
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
|
||||
public static final String KEY_PACKAGE = "package";
|
||||
public static final String KEY_MODE = "mode";
|
||||
public static final String KEY_TARGET_ID = OBJECT_TARGET;
|
||||
public static final String KEY_NAME = "name";
|
||||
public static final String KEY_PATH = "path";
|
||||
public static final String KEY_FILTER = "filter";
|
||||
public static final String KEY_SKIN = "skin";
|
||||
public static final String KEY_SDCARD = "sdcard";
|
||||
public static final String KEY_FORCE = "force";
|
||||
public static final String KEY_RENAME = "rename";
|
||||
public static final String KEY_SUBPROJECTS = "subprojects";
|
||||
public static final String KEY_MAIN_PROJECT = "main";
|
||||
|
||||
/**
|
||||
* Action definitions for SdkManager command line.
|
||||
@@ -89,6 +91,11 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
{ VERB_UPDATE, OBJECT_PROJECT,
|
||||
"Updates an Android Project (must have an AndroidManifest.xml)." },
|
||||
|
||||
{ VERB_CREATE, OBJECT_TEST_PROJECT,
|
||||
"Creates a new Android Test Project." },
|
||||
{ VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"Updates an Android Test Project (must have an AndroidManifest.xml)." },
|
||||
|
||||
{ VERB_UPDATE, OBJECT_ADB,
|
||||
"Updates adb to support the USB devices declared in the SDK add-ons." },
|
||||
};
|
||||
@@ -167,6 +174,18 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
|
||||
"Project name", null);
|
||||
|
||||
// --- create test-project ---
|
||||
define(Mode.STRING, true,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of new project", null);
|
||||
define(Mode.STRING, false,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT, "n", KEY_NAME,
|
||||
"Project name", null);
|
||||
define(Mode.STRING, true,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT, "m", KEY_MAIN_PROJECT,
|
||||
"Location path of the project to test, relative to the new project", null);
|
||||
|
||||
// --- update project ---
|
||||
|
||||
define(Mode.STRING, true,
|
||||
@@ -185,6 +204,17 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
VERB_UPDATE, OBJECT_PROJECT,
|
||||
"s", KEY_SUBPROJECTS,
|
||||
"Also update any projects in sub-folders, such as test projects.", false);
|
||||
|
||||
// --- update test project ---
|
||||
|
||||
define(Mode.STRING, true,
|
||||
VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of the project", null);
|
||||
define(Mode.STRING, true,
|
||||
VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"m", KEY_MAIN_PROJECT,
|
||||
"Location path of the project to test", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,4 +285,11 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
public boolean getParamSubProject() {
|
||||
return ((Boolean) getValue(null, OBJECT_PROJECT, KEY_SUBPROJECTS)).booleanValue();
|
||||
}
|
||||
|
||||
// -- some helpers for test-project action flags
|
||||
|
||||
/** Helper to retrieve the --main value. */
|
||||
public String getParamTestProjectMain() {
|
||||
return ((String) getValue(null, OBJECT_TEST_PROJECT, KEY_MAIN_PROJECT));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.android.sdklib.IAndroidTarget;
|
||||
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 org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
@@ -44,8 +45,7 @@ import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
/**
|
||||
* Creates the basic files needed to get an Android project up and running. Also
|
||||
* allows creation of IntelliJ project files.
|
||||
* Creates the basic files needed to get an Android project up and running.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -55,13 +55,22 @@ public class ProjectCreator {
|
||||
private final static String PH_JAVA_FOLDER = "PACKAGE_PATH";
|
||||
/** Package name substitution string used in template files, i.e. "PACKAGE" */
|
||||
private final static String PH_PACKAGE = "PACKAGE";
|
||||
/** Activity name substitution string used in template files, i.e. "ACTIVITY_NAME". */
|
||||
/** Activity name substitution string used in template files, i.e. "ACTIVITY_NAME".
|
||||
* @deprecated This is only used for older templates. For new ones see
|
||||
* {@link #PH_ACTIVITY_ENTRY_NAME}, and {@link #PH_ACTIVITY_CLASS_NAME}. */
|
||||
private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
|
||||
/** Activity name substitution string used in manifest templates, i.e. "ACTIVITY_ENTRY_NAME".*/
|
||||
private final static String PH_ACTIVITY_ENTRY_NAME = "ACTIVITY_ENTRY_NAME";
|
||||
/** Activity name substitution string used in class templates, i.e. "ACTIVITY_CLASS_NAME".*/
|
||||
private final static String PH_ACTIVITY_CLASS_NAME = "ACTIVITY_CLASS_NAME";
|
||||
/** Activity FQ-name substitution string used in class templates, i.e. "ACTIVITY_FQ_NAME".*/
|
||||
private final static String PH_ACTIVITY_FQ_NAME = "ACTIVITY_FQ_NAME";
|
||||
/** Original Activity class name substitution string used in class templates, i.e.
|
||||
* "ACTIVITY_TESTED_CLASS_NAME".*/
|
||||
private final static String PH_ACTIVITY_TESTED_CLASS_NAME = "ACTIVITY_TESTED_CLASS_NAME";
|
||||
/** Project name substitution string used in template files, i.e. "PROJECT_NAME". */
|
||||
private final static String PH_PROJECT_NAME = "PROJECT_NAME";
|
||||
|
||||
private final static String FOLDER_TESTS = "tests";
|
||||
|
||||
/** Pattern for characters accepted in a project name. Since this will be used as a
|
||||
* directory name, we're being a bit conservative on purpose: dot and space cannot be used. */
|
||||
public static final Pattern RE_PROJECT_NAME = Pattern.compile("[a-zA-Z0-9_]+");
|
||||
@@ -135,17 +144,16 @@ public class ProjectCreator {
|
||||
* {@link #RE_PROJECT_NAME} regex.
|
||||
* @param packageName the package of the project. The name must match the
|
||||
* {@link #RE_PACKAGE_NAME} regex.
|
||||
* @param activityName the activity of the project as it will appear in the manifest. Can be
|
||||
* @param activityEntry the activity of the project as it will appear in the manifest. Can be
|
||||
* null if no activity should be created. The name must match the
|
||||
* {@link #RE_ACTIVITY_NAME} regex.
|
||||
* @param target the project target.
|
||||
* @param isTestProject whether the project to create is a test project. Caller should
|
||||
* initially call this will false. The method will call itself back to create
|
||||
* a test project as needed.
|
||||
* @param pathToMainProject if non-null the project will be setup to test a main project
|
||||
* located at the given path.
|
||||
*/
|
||||
public void createProject(String folderPath, String projectName,
|
||||
String packageName, String activityName, IAndroidTarget target,
|
||||
boolean isTestProject) {
|
||||
String packageName, String activityEntry, IAndroidTarget target,
|
||||
String pathToMainProject) {
|
||||
|
||||
// create project folder if it does not exist
|
||||
File projectFolder = new File(folderPath);
|
||||
@@ -185,6 +193,8 @@ public class ProjectCreator {
|
||||
}
|
||||
|
||||
try {
|
||||
boolean isTestProject = pathToMainProject != null;
|
||||
|
||||
// first create the project properties.
|
||||
|
||||
// location of the SDK goes in localProperty
|
||||
@@ -202,9 +212,16 @@ public class ProjectCreator {
|
||||
// create a build.properties file with just the application package
|
||||
ProjectProperties buildProperties = ProjectProperties.create(folderPath,
|
||||
PropertyType.BUILD);
|
||||
buildProperties.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE, packageName);
|
||||
if (isTestProject == true) {
|
||||
buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, "..");
|
||||
|
||||
// only put application.package for older target where the rules file didn't.
|
||||
// grab it through xpath
|
||||
if (target.getVersion().getApiLevel() < 4) {
|
||||
buildProperties.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE, packageName);
|
||||
}
|
||||
|
||||
if (isTestProject) {
|
||||
buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT,
|
||||
pathToMainProject);
|
||||
}
|
||||
|
||||
buildProperties.save();
|
||||
@@ -221,19 +238,76 @@ public class ProjectCreator {
|
||||
// put this path in the place-holder map for project files that needs to list
|
||||
// files manually.
|
||||
keywords.put(PH_JAVA_FOLDER, packagePath);
|
||||
|
||||
keywords.put(PH_PACKAGE, packageName);
|
||||
if (activityName != null) {
|
||||
keywords.put(PH_ACTIVITY_NAME, activityName);
|
||||
|
||||
|
||||
// compute some activity related information
|
||||
String fqActivityName = null, activityPath = null, activityClassName = null;
|
||||
String originalActivityEntry = activityEntry;
|
||||
String originalActivityClassName = null;
|
||||
if (activityEntry != null) {
|
||||
if (isTestProject) {
|
||||
// append Test so that it doesn't collide with the main project activity.
|
||||
activityEntry += "Test";
|
||||
|
||||
// get the classname from the original activity entry.
|
||||
int pos = originalActivityEntry.lastIndexOf('.');
|
||||
if (pos != -1) {
|
||||
originalActivityClassName = originalActivityEntry.substring(pos + 1);
|
||||
} else {
|
||||
originalActivityClassName = originalActivityEntry;
|
||||
}
|
||||
}
|
||||
|
||||
// get the fully qualified name of the activity
|
||||
fqActivityName = AndroidManifest.combinePackageAndClassName(packageName,
|
||||
activityEntry);
|
||||
|
||||
// get the activity path (replace the . to /)
|
||||
activityPath = stripString(fqActivityName.replace(".", File.separator),
|
||||
File.separatorChar);
|
||||
|
||||
// remove the last segment, so that we only have the path to the activity, but
|
||||
// not the activity filename itself.
|
||||
activityPath = activityPath.substring(0,
|
||||
activityPath.lastIndexOf(File.separatorChar));
|
||||
|
||||
// finally, get the class name for the activity
|
||||
activityClassName = fqActivityName.substring(fqActivityName.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
// at this point we have the following for the activity:
|
||||
// activityEntry: this is the manifest entry. For instance .MyActivity
|
||||
// fqActivityName: full-qualified class name: com.foo.MyActivity
|
||||
// activityClassName: only the classname: MyActivity
|
||||
// originalActivityClassName: the classname of the activity being tested (if applicable)
|
||||
|
||||
// Add whatever activity info is needed in the place-holder map.
|
||||
// Older templates only expect ACTIVITY_NAME to be the same (and unmodified for tests).
|
||||
if (target.getVersion().getApiLevel() < 4) { // legacy
|
||||
if (originalActivityEntry != null) {
|
||||
keywords.put(PH_ACTIVITY_NAME, originalActivityEntry);
|
||||
}
|
||||
} else {
|
||||
// newer templates make a difference between the manifest entries, classnames,
|
||||
// as well as the main and test classes.
|
||||
if (activityEntry != null) {
|
||||
keywords.put(PH_ACTIVITY_ENTRY_NAME, activityEntry);
|
||||
keywords.put(PH_ACTIVITY_CLASS_NAME, activityClassName);
|
||||
keywords.put(PH_ACTIVITY_FQ_NAME, fqActivityName);
|
||||
if (originalActivityClassName != null) {
|
||||
keywords.put(PH_ACTIVITY_TESTED_CLASS_NAME, originalActivityClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Take the project name from the command line if there's one
|
||||
if (projectName != null) {
|
||||
keywords.put(PH_PROJECT_NAME, projectName);
|
||||
} else {
|
||||
if (activityName != null) {
|
||||
// Use the activity as project name
|
||||
keywords.put(PH_PROJECT_NAME, activityName);
|
||||
if (activityClassName != null) {
|
||||
// Use the activity class name as project name
|
||||
keywords.put(PH_PROJECT_NAME, activityClassName);
|
||||
} else {
|
||||
// We need a project name. Just pick up the basename of the project
|
||||
// directory.
|
||||
@@ -242,21 +316,21 @@ public class ProjectCreator {
|
||||
}
|
||||
}
|
||||
|
||||
// create the source folder and the java package folders.
|
||||
String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
|
||||
File sourceFolder = createDirs(projectFolder, srcFolderPath);
|
||||
String javaTemplate = "java_file.template";
|
||||
String activityFileName = activityName + ".java";
|
||||
if (isTestProject) {
|
||||
javaTemplate = "java_tests_file.template";
|
||||
activityFileName = activityName + "Test.java";
|
||||
}
|
||||
installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
|
||||
keywords, target);
|
||||
// create the source folder for the activity
|
||||
if (activityClassName != null) {
|
||||
String srcActivityFolderPath = SdkConstants.FD_SOURCES + File.separator + activityPath;
|
||||
File sourceFolder = createDirs(projectFolder, srcActivityFolderPath);
|
||||
|
||||
// create the generate source folder
|
||||
srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath;
|
||||
sourceFolder = createDirs(projectFolder, srcFolderPath);
|
||||
String javaTemplate = isTestProject ? "java_tests_file.template"
|
||||
: "java_file.template";
|
||||
String activityFileName = activityClassName + ".java";
|
||||
|
||||
installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
|
||||
keywords, target);
|
||||
} else {
|
||||
// we should at least create 'src'
|
||||
createDirs(projectFolder, SdkConstants.FD_SOURCES);
|
||||
}
|
||||
|
||||
// create other useful folders
|
||||
File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES);
|
||||
@@ -287,16 +361,6 @@ public class ProjectCreator {
|
||||
installTemplate("build.template",
|
||||
new File(projectFolder, SdkConstants.FN_BUILD_XML),
|
||||
keywords);
|
||||
|
||||
// if this is not a test project, then we create one.
|
||||
if (isTestProject == false) {
|
||||
// create the test project folder.
|
||||
createDirs(projectFolder, FOLDER_TESTS);
|
||||
File testProjectFolder = new File(folderPath, FOLDER_TESTS);
|
||||
|
||||
createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
|
||||
activityName, target, true /*isTestProject*/);
|
||||
}
|
||||
} catch (ProjectCreateException e) {
|
||||
mLog.error(e, null);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -251,8 +251,10 @@ public final class ProjectProperties {
|
||||
writer.write(comment);
|
||||
}
|
||||
String value = entry.getValue();
|
||||
value = value.replaceAll("\\\\", "\\\\\\\\");
|
||||
writer.write(String.format("%s=%s\n", entry.getKey(), value));
|
||||
if (value != null) {
|
||||
value = value.replaceAll("\\\\", "\\\\\\\\");
|
||||
writer.write(String.format("%s=%s\n", entry.getKey(), value));
|
||||
}
|
||||
}
|
||||
|
||||
// close the file to flush
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
package com.android.sdklib.xml;
|
||||
|
||||
/**
|
||||
* Constants for nodes and attributes of the AndroidManifest.xml file.
|
||||
* Helper and Constants for the AndroidManifest.xml file.
|
||||
*
|
||||
*/
|
||||
public final class ManifestConstants {
|
||||
public final class AndroidManifest {
|
||||
|
||||
public final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
|
||||
public final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
|
||||
@@ -42,4 +42,39 @@ public final class ManifestConstants {
|
||||
public final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
|
||||
public final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
|
||||
public final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
|
||||
|
||||
|
||||
/**
|
||||
* Combines a java package, with a class value from the manifest to make a fully qualified
|
||||
* class name
|
||||
* @param javaPackage the java package from the manifest.
|
||||
* @param className the class name from the manifest.
|
||||
* @return the fully qualified class name.
|
||||
*/
|
||||
public static String combinePackageAndClassName(String javaPackage, String className) {
|
||||
if (className == null || className.length() == 0) {
|
||||
return javaPackage;
|
||||
}
|
||||
if (javaPackage == null || javaPackage.length() == 0) {
|
||||
return className;
|
||||
}
|
||||
|
||||
// the class name can be a subpackage (starts with a '.'
|
||||
// char), a simple class name (no dot), or a full java package
|
||||
boolean startWithDot = (className.charAt(0) == '.');
|
||||
boolean hasDot = (className.indexOf('.') != -1);
|
||||
if (startWithDot || hasDot == false) {
|
||||
|
||||
// add the concatenation of the package and class name
|
||||
if (startWithDot) {
|
||||
return javaPackage + className;
|
||||
} else {
|
||||
return javaPackage + '.' + className;
|
||||
}
|
||||
} else {
|
||||
// just add the class as it should be a fully qualified java name.
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,9 @@ package com.android.sdklib.xml;
|
||||
|
||||
import com.android.sdklib.SdkConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
@@ -39,7 +41,8 @@ public class AndroidXPathFactory {
|
||||
private final static AndroidNamespaceContext sThis = new AndroidNamespaceContext(
|
||||
DEFAULT_NS_PREFIX);
|
||||
|
||||
private String mAndroidPrefix;
|
||||
private final String mAndroidPrefix;
|
||||
private final List<String> mAndroidPrefixes = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Returns the default {@link AndroidNamespaceContext}.
|
||||
@@ -54,6 +57,7 @@ public class AndroidXPathFactory {
|
||||
*/
|
||||
public AndroidNamespaceContext(String androidPrefix) {
|
||||
mAndroidPrefix = androidPrefix;
|
||||
mAndroidPrefixes.add(mAndroidPrefix);
|
||||
}
|
||||
|
||||
public String getNamespaceURI(String prefix) {
|
||||
@@ -67,14 +71,18 @@ public class AndroidXPathFactory {
|
||||
}
|
||||
|
||||
public String getPrefix(String namespaceURI) {
|
||||
// This isn't necessary for our use.
|
||||
assert false;
|
||||
if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
|
||||
return mAndroidPrefix;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<?> getPrefixes(String namespaceURI) {
|
||||
// This isn't necessary for our use.
|
||||
assert false;
|
||||
if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
|
||||
return mAndroidPrefixes.iterator();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user