ADT #1856119: 'android update project' can now update sub-projects.
This commit is contained in:
@@ -85,13 +85,13 @@ public class CommandLineProcessor {
|
|||||||
mLog = logger;
|
mLog = logger;
|
||||||
mActions = actions;
|
mActions = actions;
|
||||||
|
|
||||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE,
|
define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE,
|
||||||
"Verbose mode: errors, warnings and informational messages are printed.",
|
"Verbose mode: errors, warnings and informational messages are printed.",
|
||||||
false);
|
false);
|
||||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT,
|
define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT,
|
||||||
"Silent mode: only errors are printed out.",
|
"Silent mode: only errors are printed out.",
|
||||||
false);
|
false);
|
||||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP,
|
define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP,
|
||||||
"This help.",
|
"This help.",
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
@@ -507,7 +507,7 @@ public class CommandLineProcessor {
|
|||||||
}
|
}
|
||||||
} else if (arg.getDefaultValue() != null) {
|
} else if (arg.getDefaultValue() != null) {
|
||||||
Object v = arg.getDefaultValue();
|
Object v = arg.getDefaultValue();
|
||||||
if (arg.getMode() != MODE.BOOLEAN || v.equals(Boolean.TRUE)) {
|
if (arg.getMode() != Mode.BOOLEAN || v.equals(Boolean.TRUE)) {
|
||||||
value = v.toString();
|
value = v.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -537,7 +537,7 @@ public class CommandLineProcessor {
|
|||||||
* The mode of an argument specifies the type of variable it represents,
|
* The mode of an argument specifies the type of variable it represents,
|
||||||
* whether an extra parameter is required after the flag and how to parse it.
|
* whether an extra parameter is required after the flag and how to parse it.
|
||||||
*/
|
*/
|
||||||
static enum MODE {
|
static enum Mode {
|
||||||
/** Argument value is a Boolean. Default value is a Boolean. */
|
/** Argument value is a Boolean. Default value is a Boolean. */
|
||||||
BOOLEAN {
|
BOOLEAN {
|
||||||
@Override
|
@Override
|
||||||
@@ -628,7 +628,7 @@ public class CommandLineProcessor {
|
|||||||
* An argument accepted by the command-line, also called "a flag".
|
* An argument accepted by the command-line, also called "a flag".
|
||||||
* Arguments must have a short version (one letter), a long version name and a description.
|
* Arguments must have a short version (one letter), a long version name and a description.
|
||||||
* They can have a default value, or it can be null.
|
* They can have a default value, or it can be null.
|
||||||
* Depending on the {@link MODE}, the default value can be a Boolean, an Integer, a String
|
* Depending on the {@link Mode}, the default value can be a Boolean, an Integer, a String
|
||||||
* or a String array (in which case the first item is the current by default.)
|
* or a String array (in which case the first item is the current by default.)
|
||||||
*/
|
*/
|
||||||
static class Arg {
|
static class Arg {
|
||||||
@@ -645,7 +645,7 @@ public class CommandLineProcessor {
|
|||||||
/** A default value. Can be null. */
|
/** A default value. Can be null. */
|
||||||
private final Object mDefaultValue;
|
private final Object mDefaultValue;
|
||||||
/** The argument mode (type + process method). Never null. */
|
/** The argument mode (type + process method). Never null. */
|
||||||
private final MODE mMode;
|
private final Mode mMode;
|
||||||
/** True if this argument is mandatory for this verb/directobject. */
|
/** True if this argument is mandatory for this verb/directobject. */
|
||||||
private final boolean mMandatory;
|
private final boolean mMandatory;
|
||||||
/** Current value. Initially set to the default value. */
|
/** Current value. Initially set to the default value. */
|
||||||
@@ -656,15 +656,15 @@ public class CommandLineProcessor {
|
|||||||
/**
|
/**
|
||||||
* Creates a new argument flag description.
|
* Creates a new argument flag description.
|
||||||
*
|
*
|
||||||
* @param mode The {@link MODE} for the argument.
|
* @param mode The {@link Mode} for the argument.
|
||||||
* @param mandatory True if this argument is mandatory for this action.
|
* @param mandatory True if this argument is mandatory for this action.
|
||||||
* @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
|
* @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
|
||||||
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
||||||
* @param longName The long argument name. Cannot be empty nor null.
|
* @param longName The long argument name. Cannot be empty nor null.
|
||||||
* @param description The description. Cannot be null.
|
* @param description The description. Cannot be null.
|
||||||
* @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
|
* @param defaultValue The default value (or values), which depends on the selected {@link Mode}.
|
||||||
*/
|
*/
|
||||||
public Arg(MODE mode,
|
public Arg(Mode mode,
|
||||||
boolean mandatory,
|
boolean mandatory,
|
||||||
String verb,
|
String verb,
|
||||||
String directObject,
|
String directObject,
|
||||||
@@ -734,7 +734,7 @@ public class CommandLineProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the argument mode (type + process method). Never null. */
|
/** Returns the argument mode (type + process method). Never null. */
|
||||||
public MODE getMode() {
|
public Mode getMode() {
|
||||||
return mMode;
|
return mMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,21 +752,21 @@ public class CommandLineProcessor {
|
|||||||
/**
|
/**
|
||||||
* Internal helper to define a new argument for a give action.
|
* Internal helper to define a new argument for a give action.
|
||||||
*
|
*
|
||||||
* @param mode The {@link MODE} for the argument.
|
* @param mode The {@link Mode} for the argument.
|
||||||
* @param verb The verb name. Can be #INTERNAL_VERB.
|
* @param verb The verb name. Can be #INTERNAL_VERB.
|
||||||
* @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
|
* @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
|
||||||
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
||||||
* @param longName The long argument name. Cannot be empty nor null.
|
* @param longName The long argument name. Cannot be empty nor null.
|
||||||
* @param description The description. Cannot be null.
|
* @param description The description. Cannot be null.
|
||||||
* @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
|
* @param defaultValue The default value (or values), which depends on the selected {@link Mode}.
|
||||||
*/
|
*/
|
||||||
protected void define(MODE mode,
|
protected void define(Mode mode,
|
||||||
boolean mandatory,
|
boolean mandatory,
|
||||||
String verb,
|
String verb,
|
||||||
String directObject,
|
String directObject,
|
||||||
String shortName, String longName,
|
String shortName, String longName,
|
||||||
String description, Object defaultValue) {
|
String description, Object defaultValue) {
|
||||||
assert(mandatory || mode == MODE.BOOLEAN); // a boolean mode cannot be mandatory
|
assert(mandatory || mode == Mode.BOOLEAN); // a boolean mode cannot be mandatory
|
||||||
|
|
||||||
if (directObject == null) {
|
if (directObject == null) {
|
||||||
directObject = NO_VERB_OBJECT;
|
directObject = NO_VERB_OBJECT;
|
||||||
|
|||||||
@@ -337,6 +337,33 @@ class Main {
|
|||||||
creator.updateProject(projectDir,
|
creator.updateProject(projectDir,
|
||||||
target,
|
target,
|
||||||
mSdkCommandLine.getParamName());
|
mSdkCommandLine.getParamName());
|
||||||
|
|
||||||
|
boolean doSubProjects = mSdkCommandLine.getParamSubProject();
|
||||||
|
boolean couldHaveDone = false;
|
||||||
|
|
||||||
|
// If there are any sub-folders with a manifest, try to update them as projects
|
||||||
|
// too. This will take care of updating any underlying test project even if the
|
||||||
|
// user changed the folder name.
|
||||||
|
File[] files = new File(projectDir).listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File dir : files) {
|
||||||
|
if (dir.isDirectory() &&
|
||||||
|
new File(dir, SdkConstants.FN_ANDROID_MANIFEST_XML).isFile()) {
|
||||||
|
if (doSubProjects) {
|
||||||
|
creator.updateProject(dir.getPath(),
|
||||||
|
target,
|
||||||
|
mSdkCommandLine.getParamName());
|
||||||
|
} else {
|
||||||
|
couldHaveDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (couldHaveDone) {
|
||||||
|
mSdkLog.printf("It seems that there are sub-projects. If you want to update them\nplease use the --%1$s parameter.",
|
||||||
|
SdkCommandLine.KEY_SUBPROJECTS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,20 +38,21 @@ public class SdkCommandLine extends CommandLineProcessor {
|
|||||||
public static final String OBJECT_PROJECT = "project";
|
public static final String OBJECT_PROJECT = "project";
|
||||||
public static final String OBJECT_ADB = "adb";
|
public static final String OBJECT_ADB = "adb";
|
||||||
|
|
||||||
public static final String ARG_ALIAS = "alias";
|
public static final String ARG_ALIAS = "alias";
|
||||||
public static final String ARG_ACTIVITY = "activity";
|
public static final String ARG_ACTIVITY = "activity";
|
||||||
|
|
||||||
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
|
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
|
||||||
public static final String KEY_PACKAGE = "package";
|
public static final String KEY_PACKAGE = "package";
|
||||||
public static final String KEY_MODE = "mode";
|
public static final String KEY_MODE = "mode";
|
||||||
public static final String KEY_TARGET_ID = OBJECT_TARGET;
|
public static final String KEY_TARGET_ID = OBJECT_TARGET;
|
||||||
public static final String KEY_NAME = "name";
|
public static final String KEY_NAME = "name";
|
||||||
public static final String KEY_PATH = "path";
|
public static final String KEY_PATH = "path";
|
||||||
public static final String KEY_FILTER = "filter";
|
public static final String KEY_FILTER = "filter";
|
||||||
public static final String KEY_SKIN = "skin";
|
public static final String KEY_SKIN = "skin";
|
||||||
public static final String KEY_SDCARD = "sdcard";
|
public static final String KEY_SDCARD = "sdcard";
|
||||||
public static final String KEY_FORCE = "force";
|
public static final String KEY_FORCE = "force";
|
||||||
public static final String KEY_RENAME = "rename";
|
public static final String KEY_RENAME = "rename";
|
||||||
|
public static final String KEY_SUBPROJECTS = "subprojects";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action definitions for SdkManager command line.
|
* Action definitions for SdkManager command line.
|
||||||
@@ -97,46 +98,46 @@ public class SdkCommandLine extends CommandLineProcessor {
|
|||||||
|
|
||||||
// --- create avd ---
|
// --- create avd ---
|
||||||
|
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_CREATE, OBJECT_AVD, "p", KEY_PATH,
|
VERB_CREATE, OBJECT_AVD, "p", KEY_PATH,
|
||||||
"Location path of the directory where the new AVD will be created", null);
|
"Location path of the directory where the new AVD will be created", null);
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
|
VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
|
||||||
"Name of the new AVD", null);
|
"Name of the new AVD", null);
|
||||||
define(MODE.INTEGER, true,
|
define(Mode.INTEGER, true,
|
||||||
VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
|
VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
|
||||||
"Target id of the new AVD", null);
|
"Target id of the new AVD", null);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_CREATE, OBJECT_AVD, "s", KEY_SKIN,
|
VERB_CREATE, OBJECT_AVD, "s", KEY_SKIN,
|
||||||
"Skin of the new AVD", null);
|
"Skin of the new AVD", null);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_CREATE, OBJECT_AVD, "c", KEY_SDCARD,
|
VERB_CREATE, OBJECT_AVD, "c", KEY_SDCARD,
|
||||||
"Path to a shared SD card image, or size of a new sdcard for the new AVD", null);
|
"Path to a shared SD card image, or size of a new sdcard for the new AVD", null);
|
||||||
define(MODE.BOOLEAN, false,
|
define(Mode.BOOLEAN, false,
|
||||||
VERB_CREATE, OBJECT_AVD, "f", KEY_FORCE,
|
VERB_CREATE, OBJECT_AVD, "f", KEY_FORCE,
|
||||||
"Force creation (override an existing AVD)", false);
|
"Force creation (override an existing AVD)", false);
|
||||||
|
|
||||||
// --- delete avd ---
|
// --- delete avd ---
|
||||||
|
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_DELETE, OBJECT_AVD, "n", KEY_NAME,
|
VERB_DELETE, OBJECT_AVD, "n", KEY_NAME,
|
||||||
"Name of the AVD to delete", null);
|
"Name of the AVD to delete", null);
|
||||||
|
|
||||||
// --- move avd ---
|
// --- move avd ---
|
||||||
|
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_MOVE, OBJECT_AVD, "n", KEY_NAME,
|
VERB_MOVE, OBJECT_AVD, "n", KEY_NAME,
|
||||||
"Name of the AVD to move or rename", null);
|
"Name of the AVD to move or rename", null);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_MOVE, OBJECT_AVD, "r", KEY_RENAME,
|
VERB_MOVE, OBJECT_AVD, "r", KEY_RENAME,
|
||||||
"New name of the AVD to rename", null);
|
"New name of the AVD to rename", null);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_MOVE, OBJECT_AVD, "p", KEY_PATH,
|
VERB_MOVE, OBJECT_AVD, "p", KEY_PATH,
|
||||||
"New location path of the directory where to move the AVD", null);
|
"New location path of the directory where to move the AVD", null);
|
||||||
|
|
||||||
// --- update avd ---
|
// --- update avd ---
|
||||||
|
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_UPDATE, OBJECT_AVD, "n", KEY_NAME,
|
VERB_UPDATE, OBJECT_AVD, "n", KEY_NAME,
|
||||||
"Name of the AVD to update", null);
|
"Name of the AVD to update", null);
|
||||||
|
|
||||||
@@ -145,41 +146,45 @@ public class SdkCommandLine extends CommandLineProcessor {
|
|||||||
/* Disabled for ADT 0.9 / Cupcake SDK 1.5_r1 release. [bug #1795718].
|
/* Disabled for ADT 0.9 / Cupcake SDK 1.5_r1 release. [bug #1795718].
|
||||||
This currently does not work, the alias build rules need to be fixed.
|
This currently does not work, the alias build rules need to be fixed.
|
||||||
|
|
||||||
define(MODE.ENUM, true,
|
define(Mode.ENUM, true,
|
||||||
VERB_CREATE, OBJECT_PROJECT, "m", KEY_MODE,
|
VERB_CREATE, OBJECT_PROJECT, "m", KEY_MODE,
|
||||||
"Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
|
"Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
|
||||||
*/
|
*/
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_CREATE, OBJECT_PROJECT,
|
VERB_CREATE, OBJECT_PROJECT,
|
||||||
"p", KEY_PATH,
|
"p", KEY_PATH,
|
||||||
"Location path of new project", null);
|
"Location path of new project", null);
|
||||||
define(MODE.INTEGER, true,
|
define(Mode.INTEGER, true,
|
||||||
VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
|
VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
|
||||||
"Target id of the new project", null);
|
"Target id of the new project", null);
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_CREATE, OBJECT_PROJECT, "k", KEY_PACKAGE,
|
VERB_CREATE, OBJECT_PROJECT, "k", KEY_PACKAGE,
|
||||||
"Package name", null);
|
"Package name", null);
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_CREATE, OBJECT_PROJECT, "a", KEY_ACTIVITY,
|
VERB_CREATE, OBJECT_PROJECT, "a", KEY_ACTIVITY,
|
||||||
"Activity name", null);
|
"Activity name", null);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
|
VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
|
||||||
"Project name", null);
|
"Project name", null);
|
||||||
|
|
||||||
// --- update project ---
|
// --- update project ---
|
||||||
|
|
||||||
define(MODE.STRING, true,
|
define(Mode.STRING, true,
|
||||||
VERB_UPDATE, OBJECT_PROJECT,
|
VERB_UPDATE, OBJECT_PROJECT,
|
||||||
"p", KEY_PATH,
|
"p", KEY_PATH,
|
||||||
"Location path of the project", null);
|
"Location path of the project", null);
|
||||||
define(MODE.INTEGER, true,
|
define(Mode.INTEGER, true,
|
||||||
VERB_UPDATE, OBJECT_PROJECT,
|
VERB_UPDATE, OBJECT_PROJECT,
|
||||||
"t", KEY_TARGET_ID,
|
"t", KEY_TARGET_ID,
|
||||||
"Target id to set for the project", -1);
|
"Target id to set for the project", -1);
|
||||||
define(MODE.STRING, false,
|
define(Mode.STRING, false,
|
||||||
VERB_UPDATE, OBJECT_PROJECT,
|
VERB_UPDATE, OBJECT_PROJECT,
|
||||||
"n", KEY_NAME,
|
"n", KEY_NAME,
|
||||||
"Project name", null);
|
"Project name", null);
|
||||||
|
define(Mode.BOOLEAN, false,
|
||||||
|
VERB_UPDATE, OBJECT_PROJECT,
|
||||||
|
"s", KEY_SUBPROJECTS,
|
||||||
|
"Also update any projects in sub-folders, such as test projects.", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -234,8 +239,13 @@ public class SdkCommandLine extends CommandLineProcessor {
|
|||||||
return ((String) getValue(null, OBJECT_PROJECT, KEY_PACKAGE));
|
return ((String) getValue(null, OBJECT_PROJECT, KEY_PACKAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper to retrieve the --activity for the new project action. */
|
/** Helper to retrieve the --activity for any project action. */
|
||||||
public String getParamProjectActivity() {
|
public String getParamProjectActivity() {
|
||||||
return ((String) getValue(null, OBJECT_PROJECT, KEY_ACTIVITY));
|
return ((String) getValue(null, OBJECT_PROJECT, KEY_ACTIVITY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper to retrieve the --subprojects for any project action. */
|
||||||
|
public boolean getParamSubProject() {
|
||||||
|
return ((Boolean) getValue(null, OBJECT_PROJECT, KEY_SUBPROJECTS)).booleanValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ public class CommandLineProcessorTest extends TestCase {
|
|||||||
{ "verb1", "action1", "Some action" },
|
{ "verb1", "action1", "Some action" },
|
||||||
{ "verb1", "action2", "Another action" },
|
{ "verb1", "action2", "Another action" },
|
||||||
});
|
});
|
||||||
define(MODE.STRING, false /*mandatory*/,
|
define(Mode.STRING, false /*mandatory*/,
|
||||||
"verb1", "action1", "1", "first", "non-mandatory flag", null);
|
"verb1", "action1", "1", "first", "non-mandatory flag", null);
|
||||||
define(MODE.STRING, true /*mandatory*/,
|
define(Mode.STRING, true /*mandatory*/,
|
||||||
"verb1", "action1", "2", "second", "mandatory flag", null);
|
"verb1", "action1", "2", "second", "mandatory flag", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import javax.xml.xpath.XPathFactory;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class ProjectCreator {
|
public class ProjectCreator {
|
||||||
|
|
||||||
/** Package path substitution string used in template files, i.e. "PACKAGE_PATH" */
|
/** Package path substitution string used in template files, i.e. "PACKAGE_PATH" */
|
||||||
private final static String PH_JAVA_FOLDER = "PACKAGE_PATH";
|
private final static String PH_JAVA_FOLDER = "PACKAGE_PATH";
|
||||||
/** Package name substitution string used in template files, i.e. "PACKAGE" */
|
/** Package name substitution string used in template files, i.e. "PACKAGE" */
|
||||||
@@ -59,9 +59,9 @@ public class ProjectCreator {
|
|||||||
private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
|
private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
|
||||||
/** Project name substitution string used in template files, i.e. "PROJECT_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 PH_PROJECT_NAME = "PROJECT_NAME";
|
||||||
|
|
||||||
private final static String FOLDER_TESTS = "tests";
|
private final static String FOLDER_TESTS = "tests";
|
||||||
|
|
||||||
/** Pattern for characters accepted in a project name. Since this will be used as a
|
/** 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. */
|
* 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_]+");
|
public static final Pattern RE_PROJECT_NAME = Pattern.compile("[a-zA-Z0-9_]+");
|
||||||
@@ -69,7 +69,7 @@ public class ProjectCreator {
|
|||||||
public final static String CHARS_PROJECT_NAME = "a-z A-Z 0-9 _";
|
public final static String CHARS_PROJECT_NAME = "a-z A-Z 0-9 _";
|
||||||
|
|
||||||
/** Pattern for characters accepted in a package name. A package is list of Java identifier
|
/** Pattern for characters accepted in a package name. A package is list of Java identifier
|
||||||
* separated by a dot. We need to have at least one dot (e.g. a two-level package name).
|
* separated by a dot. We need to have at least one dot (e.g. a two-level package name).
|
||||||
* A Java identifier cannot start by a digit. */
|
* A Java identifier cannot start by a digit. */
|
||||||
public static final Pattern RE_PACKAGE_NAME =
|
public static final Pattern RE_PACKAGE_NAME =
|
||||||
Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+");
|
Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+");
|
||||||
@@ -82,7 +82,7 @@ public class ProjectCreator {
|
|||||||
/** List of valid characters for a project name. Used for display purposes. */
|
/** List of valid characters for a project name. Used for display purposes. */
|
||||||
public final static String CHARS_ACTIVITY_NAME = "a-z A-Z 0-9 _";
|
public final static String CHARS_ACTIVITY_NAME = "a-z A-Z 0-9 _";
|
||||||
|
|
||||||
|
|
||||||
public enum OutputLevel {
|
public enum OutputLevel {
|
||||||
/** Silent mode. Project creation will only display errors. */
|
/** Silent mode. Project creation will only display errors. */
|
||||||
SILENT,
|
SILENT,
|
||||||
@@ -100,11 +100,11 @@ public class ProjectCreator {
|
|||||||
private static class ProjectCreateException extends Exception {
|
private static class ProjectCreateException extends Exception {
|
||||||
/** default UID. This will not be serialized anyway. */
|
/** default UID. This will not be serialized anyway. */
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
ProjectCreateException(String message) {
|
ProjectCreateException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectCreateException(Throwable t, String format, Object... args) {
|
ProjectCreateException(Throwable t, String format, Object... args) {
|
||||||
super(format != null ? String.format(format, args) : format, t);
|
super(format != null ? String.format(format, args) : format, t);
|
||||||
}
|
}
|
||||||
@@ -113,23 +113,23 @@ public class ProjectCreator {
|
|||||||
super(String.format(format, args));
|
super(String.format(format, args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final OutputLevel mLevel;
|
private final OutputLevel mLevel;
|
||||||
|
|
||||||
private final ISdkLog mLog;
|
private final ISdkLog mLog;
|
||||||
private final String mSdkFolder;
|
private final String mSdkFolder;
|
||||||
|
|
||||||
public ProjectCreator(String sdkFolder, OutputLevel level, ISdkLog log) {
|
public ProjectCreator(String sdkFolder, OutputLevel level, ISdkLog log) {
|
||||||
mSdkFolder = sdkFolder;
|
mSdkFolder = sdkFolder;
|
||||||
mLevel = level;
|
mLevel = level;
|
||||||
mLog = log;
|
mLog = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new project.
|
* Creates a new project.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The caller should have already checked and sanitized the parameters.
|
* The caller should have already checked and sanitized the parameters.
|
||||||
*
|
*
|
||||||
* @param folderPath the folder of the project to create.
|
* @param folderPath the folder of the project to create.
|
||||||
* @param projectName the name of the project. The name must match the
|
* @param projectName the name of the project. The name must match the
|
||||||
* {@link #RE_PROJECT_NAME} regex.
|
* {@link #RE_PROJECT_NAME} regex.
|
||||||
@@ -137,14 +137,16 @@ public class ProjectCreator {
|
|||||||
* {@link #RE_PACKAGE_NAME} regex.
|
* {@link #RE_PACKAGE_NAME} regex.
|
||||||
* @param activityName the activity of the project as it will appear in the manifest. Can be
|
* @param activityName 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
|
* null if no activity should be created. The name must match the
|
||||||
* {@link #RE_ACTIVITY_NAME} regex.
|
* {@link #RE_ACTIVITY_NAME} regex.
|
||||||
* @param target the project target.
|
* @param target the project target.
|
||||||
* @param isTestProject whether the project to create is a test project.
|
* @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.
|
||||||
*/
|
*/
|
||||||
public void createProject(String folderPath, String projectName,
|
public void createProject(String folderPath, String projectName,
|
||||||
String packageName, String activityName, IAndroidTarget target,
|
String packageName, String activityName, IAndroidTarget target,
|
||||||
boolean isTestProject) {
|
boolean isTestProject) {
|
||||||
|
|
||||||
// create project folder if it does not exist
|
// create project folder if it does not exist
|
||||||
File projectFolder = new File(folderPath);
|
File projectFolder = new File(folderPath);
|
||||||
if (!projectFolder.exists()) {
|
if (!projectFolder.exists()) {
|
||||||
@@ -156,7 +158,7 @@ public class ProjectCreator {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
t = e;
|
t = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (created) {
|
if (created) {
|
||||||
println("Created project directory: %1$s", projectFolder);
|
println("Created project directory: %1$s", projectFolder);
|
||||||
} else {
|
} else {
|
||||||
@@ -176,7 +178,7 @@ public class ProjectCreator {
|
|||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
e = e1;
|
e = e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e != null || error != null) {
|
if (e != null || error != null) {
|
||||||
mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
|
mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
|
||||||
}
|
}
|
||||||
@@ -196,7 +198,7 @@ public class ProjectCreator {
|
|||||||
PropertyType.DEFAULT);
|
PropertyType.DEFAULT);
|
||||||
defaultProperties.setAndroidTarget(target);
|
defaultProperties.setAndroidTarget(target);
|
||||||
defaultProperties.save();
|
defaultProperties.save();
|
||||||
|
|
||||||
// create an empty build.properties
|
// create an empty build.properties
|
||||||
ProjectProperties buildProperties = ProjectProperties.create(folderPath,
|
ProjectProperties buildProperties = ProjectProperties.create(folderPath,
|
||||||
PropertyType.BUILD);
|
PropertyType.BUILD);
|
||||||
@@ -225,16 +227,16 @@ public class ProjectCreator {
|
|||||||
keywords.put(PH_PROJECT_NAME, projectName);
|
keywords.put(PH_PROJECT_NAME, projectName);
|
||||||
} else {
|
} else {
|
||||||
if (activityName != null) {
|
if (activityName != null) {
|
||||||
// Use the activity as project name
|
// Use the activity as project name
|
||||||
keywords.put(PH_PROJECT_NAME, activityName);
|
keywords.put(PH_PROJECT_NAME, activityName);
|
||||||
} else {
|
} else {
|
||||||
// We need a project name. Just pick up the basename of the project
|
// We need a project name. Just pick up the basename of the project
|
||||||
// directory.
|
// directory.
|
||||||
projectName = projectFolder.getName();
|
projectName = projectFolder.getName();
|
||||||
keywords.put(PH_PROJECT_NAME, projectName);
|
keywords.put(PH_PROJECT_NAME, projectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the source folder and the java package folders.
|
// create the source folder and the java package folders.
|
||||||
String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
|
String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
|
||||||
File sourceFolder = createDirs(projectFolder, srcFolderPath);
|
File sourceFolder = createDirs(projectFolder, srcFolderPath);
|
||||||
@@ -270,13 +272,13 @@ public class ProjectCreator {
|
|||||||
/* Make AndroidManifest.xml and build.xml files */
|
/* Make AndroidManifest.xml and build.xml files */
|
||||||
String manifestTemplate = "AndroidManifest.template";
|
String manifestTemplate = "AndroidManifest.template";
|
||||||
if (isTestProject) {
|
if (isTestProject) {
|
||||||
manifestTemplate = "AndroidManifest.tests.template";
|
manifestTemplate = "AndroidManifest.tests.template";
|
||||||
}
|
}
|
||||||
|
|
||||||
installTemplate(manifestTemplate,
|
installTemplate(manifestTemplate,
|
||||||
new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML),
|
new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML),
|
||||||
keywords, target);
|
keywords, target);
|
||||||
|
|
||||||
installTemplate("build.template",
|
installTemplate("build.template",
|
||||||
new File(projectFolder, SdkConstants.FN_BUILD_XML),
|
new File(projectFolder, SdkConstants.FN_BUILD_XML),
|
||||||
keywords);
|
keywords);
|
||||||
@@ -286,7 +288,7 @@ public class ProjectCreator {
|
|||||||
// create the test project folder.
|
// create the test project folder.
|
||||||
createDirs(projectFolder, FOLDER_TESTS);
|
createDirs(projectFolder, FOLDER_TESTS);
|
||||||
File testProjectFolder = new File(folderPath, FOLDER_TESTS);
|
File testProjectFolder = new File(folderPath, FOLDER_TESTS);
|
||||||
|
|
||||||
createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
|
createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
|
||||||
activityName, target, true /*isTestProject*/);
|
activityName, target, true /*isTestProject*/);
|
||||||
}
|
}
|
||||||
@@ -296,7 +298,7 @@ public class ProjectCreator {
|
|||||||
mLog.error(e, null);
|
mLog.error(e, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing project.
|
* Updates an existing project.
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -308,12 +310,12 @@ public class ProjectCreator {
|
|||||||
* <li> Refresh/create "sdk" in local.properties
|
* <li> Refresh/create "sdk" in local.properties
|
||||||
* <li> Build.xml: create if not present or no <androidinit(\w|/>) in it
|
* <li> Build.xml: create if not present or no <androidinit(\w|/>) in it
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param folderPath the folder of the project to update. This folder must exist.
|
* @param folderPath the folder of the project to update. This folder must exist.
|
||||||
* @param target the project target. Can be null.
|
* @param target the project target. Can be null.
|
||||||
* @param projectName The project name from --name. Can be null.
|
* @param projectName The project name from --name. Can be null.
|
||||||
*/
|
*/
|
||||||
public void updateProject(String folderPath, IAndroidTarget target, String projectName ) {
|
public void updateProject(String folderPath, IAndroidTarget target, String projectName) {
|
||||||
// project folder must exist and be a directory, since this is an update
|
// project folder must exist and be a directory, since this is an update
|
||||||
File projectFolder = new File(folderPath);
|
File projectFolder = new File(folderPath);
|
||||||
if (!projectFolder.isDirectory()) {
|
if (!projectFolder.isDirectory()) {
|
||||||
@@ -331,7 +333,7 @@ public class ProjectCreator {
|
|||||||
folderPath);
|
folderPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check there's a default.properties with a target *or* --target was specified
|
// Check there's a default.properties with a target *or* --target was specified
|
||||||
ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT);
|
ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT);
|
||||||
if (props == null || props.getProperty(ProjectProperties.PROPERTY_TARGET) == null) {
|
if (props == null || props.getProperty(ProjectProperties.PROPERTY_TARGET) == null) {
|
||||||
@@ -351,7 +353,7 @@ public class ProjectCreator {
|
|||||||
if (props == null) {
|
if (props == null) {
|
||||||
props = ProjectProperties.create(folderPath, PropertyType.DEFAULT);
|
props = ProjectProperties.create(folderPath, PropertyType.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set or replace the target
|
// set or replace the target
|
||||||
props.setAndroidTarget(target);
|
props.setAndroidTarget(target);
|
||||||
try {
|
try {
|
||||||
@@ -364,7 +366,7 @@ public class ProjectCreator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh/create "sdk" in local.properties
|
// Refresh/create "sdk" in local.properties
|
||||||
// because the file may already exists and contain other values (like apk config),
|
// because the file may already exists and contain other values (like apk config),
|
||||||
// we first try to load it.
|
// we first try to load it.
|
||||||
@@ -372,7 +374,7 @@ public class ProjectCreator {
|
|||||||
if (props == null) {
|
if (props == null) {
|
||||||
props = ProjectProperties.create(folderPath, PropertyType.LOCAL);
|
props = ProjectProperties.create(folderPath, PropertyType.LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set or replace the sdk location.
|
// set or replace the sdk location.
|
||||||
props.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
|
props.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
|
||||||
try {
|
try {
|
||||||
@@ -384,7 +386,7 @@ public class ProjectCreator {
|
|||||||
folderPath);
|
folderPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build.xml: create if not present or no <androidinit/> in it
|
// Build.xml: create if not present or no <androidinit/> in it
|
||||||
File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML);
|
File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML);
|
||||||
boolean needsBuildXml = projectName != null || !buildXml.exists();
|
boolean needsBuildXml = projectName != null || !buildXml.exists();
|
||||||
@@ -397,7 +399,7 @@ public class ProjectCreator {
|
|||||||
println("File %1$s is too old and needs to be updated.", SdkConstants.FN_BUILD_XML);
|
println("File %1$s is too old and needs to be updated.", SdkConstants.FN_BUILD_XML);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsBuildXml) {
|
if (needsBuildXml) {
|
||||||
// create the map for place-holders of values to replace in the templates
|
// create the map for place-holders of values to replace in the templates
|
||||||
final HashMap<String, String> keywords = new HashMap<String, String>();
|
final HashMap<String, String> keywords = new HashMap<String, String>();
|
||||||
@@ -408,13 +410,13 @@ public class ProjectCreator {
|
|||||||
} else {
|
} else {
|
||||||
extractPackageFromManifest(androidManifest, keywords);
|
extractPackageFromManifest(androidManifest, keywords);
|
||||||
if (keywords.containsKey(PH_ACTIVITY_NAME)) {
|
if (keywords.containsKey(PH_ACTIVITY_NAME)) {
|
||||||
// Use the activity as project name
|
// Use the activity as project name
|
||||||
keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
|
keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
|
||||||
} else {
|
} else {
|
||||||
// We need a project name. Just pick up the basename of the project
|
// We need a project name. Just pick up the basename of the project
|
||||||
// directory.
|
// directory.
|
||||||
projectName = projectFolder.getName();
|
projectName = projectFolder.getName();
|
||||||
keywords.put(PH_PROJECT_NAME, projectName);
|
keywords.put(PH_PROJECT_NAME, projectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +425,7 @@ public class ProjectCreator {
|
|||||||
SdkConstants.FN_BUILD_XML,
|
SdkConstants.FN_BUILD_XML,
|
||||||
keywords.get(PH_PROJECT_NAME));
|
keywords.get(PH_PROJECT_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
installTemplate("build.template",
|
installTemplate("build.template",
|
||||||
new File(projectFolder, SdkConstants.FN_BUILD_XML),
|
new File(projectFolder, SdkConstants.FN_BUILD_XML),
|
||||||
@@ -443,18 +445,18 @@ public class ProjectCreator {
|
|||||||
try {
|
try {
|
||||||
BufferedReader in = new BufferedReader(new FileReader(file));
|
BufferedReader in = new BufferedReader(new FileReader(file));
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
if (p.matcher(line).find()) {
|
if (p.matcher(line).find()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in.close();
|
in.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,8 +466,8 @@ public class ProjectCreator {
|
|||||||
* The keywords dictionary is always filed the package name under the key {@link #PH_PACKAGE}.
|
* 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_NAME}.
|
||||||
* When no activity is found, this key is not created.
|
* When no activity is found, this key is not created.
|
||||||
*
|
*
|
||||||
* @param manifestFile The AndroidManifest.xml file
|
* @param manifestFile The AndroidManifest.xml file
|
||||||
* @param outKeywords Place where to put the out parameters: package and activity names.
|
* @param outKeywords Place where to put the out parameters: package and activity names.
|
||||||
* @return True if the package/activity was parsed and updated in the keyword dictionary.
|
* @return True if the package/activity was parsed and updated in the keyword dictionary.
|
||||||
*/
|
*/
|
||||||
@@ -474,9 +476,9 @@ public class ProjectCreator {
|
|||||||
try {
|
try {
|
||||||
final String nsPrefix = "android";
|
final String nsPrefix = "android";
|
||||||
final String nsURI = SdkConstants.NS_RESOURCES;
|
final String nsURI = SdkConstants.NS_RESOURCES;
|
||||||
|
|
||||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
xpath.setNamespaceContext(new NamespaceContext() {
|
xpath.setNamespaceContext(new NamespaceContext() {
|
||||||
public String getNamespaceURI(String prefix) {
|
public String getNamespaceURI(String prefix) {
|
||||||
if (nsPrefix.equals(prefix)) {
|
if (nsPrefix.equals(prefix)) {
|
||||||
@@ -501,18 +503,18 @@ public class ProjectCreator {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
InputSource source = new InputSource(new FileReader(manifestFile));
|
InputSource source = new InputSource(new FileReader(manifestFile));
|
||||||
String packageName = xpath.evaluate("/manifest/@package", source);
|
String packageName = xpath.evaluate("/manifest/@package", source);
|
||||||
|
|
||||||
source = new InputSource(new FileReader(manifestFile));
|
source = new InputSource(new FileReader(manifestFile));
|
||||||
|
|
||||||
// Select the "android:name" attribute of all <activity> nodes but only if they
|
// Select the "android:name" attribute of all <activity> nodes but only if they
|
||||||
// contain a sub-node <intent-filter><action> with an "android:name" attribute which
|
// contain a sub-node <intent-filter><action> with an "android:name" attribute which
|
||||||
// is 'android.intent.action.MAIN' and an <intent-filter><category> with an
|
// is 'android.intent.action.MAIN' and an <intent-filter><category> with an
|
||||||
// "android:name" attribute which is 'android.intent.category.LAUNCHER'
|
// "android:name" attribute which is 'android.intent.category.LAUNCHER'
|
||||||
String expression = String.format("/manifest/application/activity" +
|
String expression = String.format("/manifest/application/activity" +
|
||||||
"[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
|
"[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
|
||||||
"intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
|
"intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
|
||||||
@@ -524,7 +526,7 @@ public class ProjectCreator {
|
|||||||
// If we get here, both XPath expressions were valid so we're most likely dealing
|
// If we get here, both XPath expressions were valid so we're most likely dealing
|
||||||
// with an actual AndroidManifest.xml file. The nodes may not have the requested
|
// with an actual AndroidManifest.xml file. The nodes may not have the requested
|
||||||
// attributes though, if which case we should warn.
|
// attributes though, if which case we should warn.
|
||||||
|
|
||||||
if (packageName == null || packageName.length() == 0) {
|
if (packageName == null || packageName.length() == 0) {
|
||||||
mLog.error(null,
|
mLog.error(null,
|
||||||
"Missing <manifest package=\"...\"> in '%1$s'",
|
"Missing <manifest package=\"...\"> in '%1$s'",
|
||||||
@@ -545,14 +547,14 @@ public class ProjectCreator {
|
|||||||
"Only the first one will be used. If this is not appropriate, you need\n" +
|
"Only the first one will be used. If this is not appropriate, you need\n" +
|
||||||
"to specify one of these values manually instead:",
|
"to specify one of these values manually instead:",
|
||||||
manifestFile.getName());
|
manifestFile.getName());
|
||||||
|
|
||||||
for (int i = 0; i < activityNames.getLength(); i++) {
|
for (int i = 0; i < activityNames.getLength(); i++) {
|
||||||
String name = activityNames.item(i).getNodeValue();
|
String name = activityNames.item(i).getNodeValue();
|
||||||
name = combinePackageActivityNames(packageName, name);
|
name = combinePackageActivityNames(packageName, name);
|
||||||
println("- %1$s", name);
|
println("- %1$s", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activityName.length() == 0) {
|
if (activityName.length() == 0) {
|
||||||
mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
|
mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
|
||||||
"No activity will be generated.",
|
"No activity will be generated.",
|
||||||
@@ -563,7 +565,7 @@ public class ProjectCreator {
|
|||||||
|
|
||||||
outKeywords.put(PH_PACKAGE, packageName);
|
outKeywords.put(PH_PACKAGE, packageName);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
mLog.error(e, "Failed to read %1$s", manifestFile.getName());
|
mLog.error(e, "Failed to read %1$s", manifestFile.getName());
|
||||||
} catch (XPathExpressionException e) {
|
} catch (XPathExpressionException e) {
|
||||||
@@ -572,10 +574,10 @@ public class ProjectCreator {
|
|||||||
"Failed to parse %1$s",
|
"Failed to parse %1$s",
|
||||||
manifestFile.getName());
|
manifestFile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String combinePackageActivityNames(String packageName, String activityName) {
|
private String combinePackageActivityNames(String packageName, String activityName) {
|
||||||
// Activity Name can have 3 forms:
|
// Activity Name can have 3 forms:
|
||||||
// - ".Name" means this is a class name in the given package name.
|
// - ".Name" means this is a class name in the given package name.
|
||||||
@@ -585,7 +587,7 @@ public class ProjectCreator {
|
|||||||
// To be valid, the package name should have at least two components. This is checked
|
// To be valid, the package name should have at least two components. This is checked
|
||||||
// later during the creation of the build.xml file, so we just need to detect there's
|
// later during the creation of the build.xml file, so we just need to detect there's
|
||||||
// a dot but not at pos==0.
|
// a dot but not at pos==0.
|
||||||
|
|
||||||
int pos = activityName.indexOf('.');
|
int pos = activityName.indexOf('.');
|
||||||
if (pos == 0) {
|
if (pos == 0) {
|
||||||
return packageName + activityName;
|
return packageName + activityName;
|
||||||
@@ -600,12 +602,12 @@ public class ProjectCreator {
|
|||||||
* Installs a new file that is based on a template file provided by a given target.
|
* Installs a new file that is based on a template file provided by a given target.
|
||||||
* Each match of each key from the place-holder map in the template will be replaced with its
|
* Each match of each key from the place-holder map in the template will be replaced with its
|
||||||
* corresponding value in the created file.
|
* corresponding value in the created file.
|
||||||
*
|
*
|
||||||
* @param templateName the name of to the template file
|
* @param templateName the name of to the template file
|
||||||
* @param destFile the path to the destination file, relative to the project
|
* @param destFile the path to the destination file, relative to the project
|
||||||
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
||||||
* @param target the Target of the project that will be providing the template.
|
* @param target the Target of the project that will be providing the template.
|
||||||
* @throws ProjectCreateException
|
* @throws ProjectCreateException
|
||||||
*/
|
*/
|
||||||
private void installTemplate(String templateName, File destFile,
|
private void installTemplate(String templateName, File destFile,
|
||||||
Map<String, String> placeholderMap, IAndroidTarget target)
|
Map<String, String> placeholderMap, IAndroidTarget target)
|
||||||
@@ -621,11 +623,11 @@ public class ProjectCreator {
|
|||||||
* Installs a new file that is based on a template file provided by the tools folder.
|
* Installs a new file that is based on a template file provided by the tools folder.
|
||||||
* Each match of each key from the place-holder map in the template will be replaced with its
|
* Each match of each key from the place-holder map in the template will be replaced with its
|
||||||
* corresponding value in the created file.
|
* corresponding value in the created file.
|
||||||
*
|
*
|
||||||
* @param templateName the name of to the template file
|
* @param templateName the name of to the template file
|
||||||
* @param destFile the path to the destination file, relative to the project
|
* @param destFile the path to the destination file, relative to the project
|
||||||
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
||||||
* @throws ProjectCreateException
|
* @throws ProjectCreateException
|
||||||
*/
|
*/
|
||||||
private void installTemplate(String templateName, File destFile,
|
private void installTemplate(String templateName, File destFile,
|
||||||
Map<String, String> placeholderMap)
|
Map<String, String> placeholderMap)
|
||||||
@@ -641,38 +643,38 @@ public class ProjectCreator {
|
|||||||
* Installs a new file that is based on a template.
|
* Installs a new file that is based on a template.
|
||||||
* Each match of each key from the place-holder map in the template will be replaced with its
|
* Each match of each key from the place-holder map in the template will be replaced with its
|
||||||
* corresponding value in the created file.
|
* corresponding value in the created file.
|
||||||
*
|
*
|
||||||
* @param sourcePath the full path to the source template file
|
* @param sourcePath the full path to the source template file
|
||||||
* @param destFile the destination file
|
* @param destFile the destination file
|
||||||
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
* @param placeholderMap a map of (place-holder, value) to create the file from the template.
|
||||||
* @throws ProjectCreateException
|
* @throws ProjectCreateException
|
||||||
*/
|
*/
|
||||||
private void installFullPathTemplate(String sourcePath, File destFile,
|
private void installFullPathTemplate(String sourcePath, File destFile,
|
||||||
Map<String, String> placeholderMap) throws ProjectCreateException {
|
Map<String, String> placeholderMap) throws ProjectCreateException {
|
||||||
|
|
||||||
boolean existed = destFile.exists();
|
boolean existed = destFile.exists();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BufferedWriter out = new BufferedWriter(new FileWriter(destFile));
|
BufferedWriter out = new BufferedWriter(new FileWriter(destFile));
|
||||||
BufferedReader in = new BufferedReader(new FileReader(sourcePath));
|
BufferedReader in = new BufferedReader(new FileReader(sourcePath));
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
for (String key : placeholderMap.keySet()) {
|
for (String key : placeholderMap.keySet()) {
|
||||||
line = line.replace(key, placeholderMap.get(key));
|
line = line.replace(key, placeholderMap.get(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.write(line);
|
out.write(line);
|
||||||
out.newLine();
|
out.newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
in.close();
|
in.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ProjectCreateException(e, "Could not access %1$s: %2$s",
|
throw new ProjectCreateException(e, "Could not access %1$s: %2$s",
|
||||||
destFile, e.getMessage());
|
destFile, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
println("%1$s file %2$s",
|
println("%1$s file %2$s",
|
||||||
existed ? "Updated" : "Added",
|
existed ? "Updated" : "Added",
|
||||||
destFile);
|
destFile);
|
||||||
@@ -683,7 +685,7 @@ public class ProjectCreator {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* This is just a convenience wrapper around {@link ISdkLog#printf(String, Object...)} from
|
* This is just a convenience wrapper around {@link ISdkLog#printf(String, Object...)} from
|
||||||
* {@link #mLog} after testing if ouput level is {@link OutputLevel#VERBOSE}.
|
* {@link #mLog} after testing if ouput level is {@link OutputLevel#VERBOSE}.
|
||||||
*
|
*
|
||||||
* @param format Format for String.format
|
* @param format Format for String.format
|
||||||
* @param args Arguments for String.format
|
* @param args Arguments for String.format
|
||||||
*/
|
*/
|
||||||
@@ -698,10 +700,10 @@ public class ProjectCreator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new folder, along with any parent folders that do not exists.
|
* Creates a new folder, along with any parent folders that do not exists.
|
||||||
*
|
*
|
||||||
* @param parent the parent folder
|
* @param parent the parent folder
|
||||||
* @param name the name of the directory to create.
|
* @param name the name of the directory to create.
|
||||||
* @throws ProjectCreateException
|
* @throws ProjectCreateException
|
||||||
*/
|
*/
|
||||||
private File createDirs(File parent, String name) throws ProjectCreateException {
|
private File createDirs(File parent, String name) throws ProjectCreateException {
|
||||||
final File newFolder = new File(parent, name);
|
final File newFolder = new File(parent, name);
|
||||||
@@ -730,7 +732,7 @@ public class ProjectCreator {
|
|||||||
"Could not determine canonical path of created directory", e);
|
"Could not determine canonical path of created directory", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFolder;
|
return newFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +740,7 @@ public class ProjectCreator {
|
|||||||
* Strips the string of beginning and trailing characters (multiple
|
* Strips the string of beginning and trailing characters (multiple
|
||||||
* characters will be stripped, example stripString("..test...", '.')
|
* characters will be stripped, example stripString("..test...", '.')
|
||||||
* results in "test";
|
* results in "test";
|
||||||
*
|
*
|
||||||
* @param s the string to strip
|
* @param s the string to strip
|
||||||
* @param strip the character to strip from beginning and end
|
* @param strip the character to strip from beginning and end
|
||||||
* @return the stripped string or the empty string if everything is stripped.
|
* @return the stripped string or the empty string if everything is stripped.
|
||||||
@@ -746,24 +748,24 @@ public class ProjectCreator {
|
|||||||
private static String stripString(String s, char strip) {
|
private static String stripString(String s, char strip) {
|
||||||
final int sLen = s.length();
|
final int sLen = s.length();
|
||||||
int newStart = 0, newEnd = sLen - 1;
|
int newStart = 0, newEnd = sLen - 1;
|
||||||
|
|
||||||
while (newStart < sLen && s.charAt(newStart) == strip) {
|
while (newStart < sLen && s.charAt(newStart) == strip) {
|
||||||
newStart++;
|
newStart++;
|
||||||
}
|
}
|
||||||
while (newEnd >= 0 && s.charAt(newEnd) == strip) {
|
while (newEnd >= 0 && s.charAt(newEnd) == strip) {
|
||||||
newEnd--;
|
newEnd--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newEnd contains a char we want, and substring takes end as being
|
* newEnd contains a char we want, and substring takes end as being
|
||||||
* exclusive
|
* exclusive
|
||||||
*/
|
*/
|
||||||
newEnd++;
|
newEnd++;
|
||||||
|
|
||||||
if (newStart >= sLen || newEnd < 0) {
|
if (newStart >= sLen || newEnd < 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.substring(newStart, newEnd);
|
return s.substring(newStart, newEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user