From 51036711f744664c46a178aac458bb0cc8fa2c63 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Tue, 23 Aug 2011 16:28:21 -0700 Subject: Rename default.prop/build.prop to project.prop/ant.prop Opening projects in Eclipse will rename the file and "android update project" will do the same. Change-Id: I251881897c251eb07c9704eb9c2448cab47e5b83 --- anttasks/src/com/android/ant/AaptExecLoopTask.java | 2 +- anttasks/src/com/android/ant/NewSetupTask.java | 12 +- common/src/com/android/io/IAbstractResource.java | 5 + .../build/builders/PostCompilerBuilder.java | 2 +- .../build/builders/PreCompilerBuilder.java | 2 +- .../AndroidClasspathContainerInitializer.java | 8 +- .../internal/properties/AndroidPropertyPage.java | 12 +- .../resources/manager/ProjectClassLoader.java | 2 +- .../ide/eclipse/adt/internal/sdk/ProjectState.java | 10 +- .../android/ide/eclipse/adt/internal/sdk/Sdk.java | 46 +++++-- .../wizards/newproject/NewProjectCreationPage.java | 5 +- .../android/ide/eclipse/adt/io/IFileWrapper.java | 10 ++ .../android/ide/eclipse/adt/io/IFolderWrapper.java | 11 ++ .../app/src/com/android/sdkmanager/Main.java | 4 +- .../src/com/android/sdklib/SdkConstants.java | 11 +- .../sdklib/internal/project/ProjectCreator.java | 141 +++++++++++++++------ .../sdklib/internal/project/ProjectProperties.java | 81 ++++++++---- templates/build.template | 31 +++-- 18 files changed, 267 insertions(+), 128 deletions(-) diff --git a/anttasks/src/com/android/ant/AaptExecLoopTask.java b/anttasks/src/com/android/ant/AaptExecLoopTask.java index 7b7d82d..8a593f9 100644 --- a/anttasks/src/com/android/ant/AaptExecLoopTask.java +++ b/anttasks/src/com/android/ant/AaptExecLoopTask.java @@ -272,7 +272,7 @@ public final class AaptExecLoopTask extends BaseTask { /* * (non-Javadoc) * - * Executes the loop. Based on the values inside default.properties, this will + * Executes the loop. Based on the values inside project.properties, this will * create alternate temporary ap_ files. * * @see org.apache.tools.ant.Task#execute() diff --git a/anttasks/src/com/android/ant/NewSetupTask.java b/anttasks/src/com/android/ant/NewSetupTask.java index 49e8595..c0e8d2a 100644 --- a/anttasks/src/com/android/ant/NewSetupTask.java +++ b/anttasks/src/com/android/ant/NewSetupTask.java @@ -538,13 +538,13 @@ public class NewSetupTask extends Task { File library = inLibraries.get(i); // get the default.property file for it - final ProjectProperties defaultProp = ProjectProperties.load( - new FolderWrapper(library), PropertyType.DEFAULT); + final ProjectProperties projectProp = ProjectProperties.load( + new FolderWrapper(library), PropertyType.PROJECT); // get its libraries List dependencies = getDirectDependencies(library, new IPropertySource() { public String getProperty(String name) { - return defaultProp.getProperty(name); + return projectProp.getProperty(name); } }); @@ -585,12 +585,12 @@ public class NewSetupTask extends Task { File library = new File(baseFolder, rootPath).getCanonicalFile(); // check for validity - File defaultProp = new File(library, PropertyType.DEFAULT.getFilename()); - if (defaultProp.isFile() == false) { + File projectProp = new File(library, PropertyType.PROJECT.getFilename()); + if (projectProp.isFile() == false) { // error! throw new BuildException(String.format( "%1$s resolve to a path with no %2$s file for project %3$s", rootPath, - PropertyType.DEFAULT.getFilename(), baseFolder.getAbsolutePath())); + PropertyType.PROJECT.getFilename(), baseFolder.getAbsolutePath())); } if (libraries.contains(library) == false) { diff --git a/common/src/com/android/io/IAbstractResource.java b/common/src/com/android/io/IAbstractResource.java index 3d762eb..e6358ec 100644 --- a/common/src/com/android/io/IAbstractResource.java +++ b/common/src/com/android/io/IAbstractResource.java @@ -42,4 +42,9 @@ public interface IAbstractResource { * Returns the parent folder or null if there is no parent. */ IAbstractFolder getParentFolder(); + + /** + * Deletes the resource. + */ + boolean delete(); } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java index 3d23c49..c136fb5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java @@ -265,7 +265,7 @@ public class PostCompilerBuilder extends BaseBuilder { // get the project info ProjectState projectState = Sdk.getProjectState(project); - // this can happen if the project has no default.properties. + // this can happen if the project has no project.properties. if (projectState == null) { return null; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java index 3ece0e5..11a7385 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java @@ -201,7 +201,7 @@ public class PreCompilerBuilder extends BaseBuilder { // get the project info ProjectState projectState = Sdk.getProjectState(project); - // this can happen if the project has no default.properties. + // this can happen if the project has no project.properties. if (projectState == null) { return null; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java index d83d539..a8d1914 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java @@ -23,6 +23,7 @@ import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.sdklib.AndroidVersion; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import com.android.sdklib.IAndroidTarget.IOptionalLibrary; import org.eclipse.core.resources.IMarker; @@ -176,9 +177,10 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit // check if the project has a valid target. ProjectState state = Sdk.getProjectState(iProject); if (state == null) { - // looks like the project state (default.properties) couldn't be read! + // looks like the project state (project.properties) couldn't be read! markerMessage = String.format( - "Project has no default.properties file! Edit the project properties to set one."); + "Project has no %1$s file! Edit the project properties to set one.", + SdkConstants.FN_PROJECT_PROPERTIES); } else { // this might be null if the sdk is not yet loaded. target = state.getTarget(); @@ -633,7 +635,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit IAndroidTarget target = currentSdk.loadTarget(Sdk.getProjectState(iProject)); if (target == null) { // this is really not supposed to happen. This would mean there are cached paths, - // but default.properties was deleted. Keep the project in the list to force + // but project.properties was deleted. Keep the project in the list to force // a resolve which will display the error. i++; continue; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java index 05dede1..ad2e571 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java @@ -37,7 +37,6 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; -import org.eclipse.ui.IWorkbenchPropertyPage; import org.eclipse.ui.dialogs.PropertyPage; /** @@ -46,7 +45,7 @@ import org.eclipse.ui.dialogs.PropertyPage; * "Properties". * */ -public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPropertyPage { +public class AndroidPropertyPage extends PropertyPage { private IProject mProject; private SdkTargetSelector mSelector; @@ -150,18 +149,16 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope mustSaveProp = true; } - // TODO: update ApkSettings. - if (mustSaveProp) { try { mPropertiesWorkingCopy.save(); - IResource defaultProp = mProject.findMember(SdkConstants.FN_DEFAULT_PROPERTIES); - defaultProp.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()); + IResource projectProp = mProject.findMember(SdkConstants.FN_PROJECT_PROPERTIES); + projectProp.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()); } catch (Exception e) { String msg = String.format( "Failed to save %1$s for project %2$s", - SdkConstants.FN_DEFAULT_PROPERTIES, mProject.getName()); + SdkConstants.FN_PROJECT_PROPERTIES, mProject.getName()); AdtPlugin.log(e, msg); } } @@ -207,5 +204,4 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope IAndroidTarget target = mSelector.getSelected(); setValid(target != null); } - } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java index 4495553..eb0ddf1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java @@ -80,7 +80,7 @@ public final class ProjectClassLoader extends ClassLoader { // get the project info ProjectState projectState = Sdk.getProjectState(mJavaProject.getProject()); - // this can happen if the project has no default.properties. + // this can happen if the project has no project.properties. if (projectState != null) { List libProjects = projectState.getFullLibraryProjects(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java index 5b221fc..e336868 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/ProjectState.java @@ -35,7 +35,7 @@ import java.util.regex.Matcher; /** * Centralized state for Android Eclipse project. - *

This gives raw access to the properties (from default.properties), as well + *

This gives raw access to the properties (from project.properties), as well * as direct access to target, apksettings and library information. * * This also gives access to library information. @@ -106,7 +106,7 @@ public final class ProjectState { /** * Returns the relative path of the library from the main project. - *

This is identical to the value defined in the main project's default.properties. + *

This is identical to the value defined in the main project's project.properties. */ public String getRelativePath() { return mRelativePath; @@ -485,7 +485,7 @@ public final class ProjectState { * and the {@link LibraryState} for the library is returned. *

Updating the project does two things:

    *
  • Update LibraryState with new relative path and new {@link IProject} object.
  • - *
  • Update the main project's default.properties with the new relative path + *
  • Update the main project's project.properties with the new relative path * for the changed library.
  • *
* @@ -521,7 +521,7 @@ public final class ProjectState { state.setRelativePath(newRelativePath); state.setProject(newLibraryState); - // update the default.properties file + // update the project.properties file IStatus status = replaceLibraryProperty(oldProperty, newRelativePath); if (status != null) { if (status.getSeverity() != IStatus.OK) { @@ -563,7 +563,7 @@ public final class ProjectState { *

This loops on all current dependency looking for the value to replace and then replaces * it. *

This both updates the in-memory {@link #mProperties} values and on-disk - * default.properties file. + * project.properties file. * @param oldValue the old value to replace * @param newValue the new value to set. * @return the status of the replacement. If null, no replacement was done (value not found). diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java index 4d11bc9..666860b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java @@ -302,7 +302,7 @@ public final class Sdk { } /** - * Initializes a new project with a target. This creates the default.properties + * Initializes a new project with a target. This creates the project.properties * file. * @param project the project to intialize * @param target the project's target. @@ -332,7 +332,7 @@ public final class Sdk { return; } - properties = ProjectProperties.create(location.toOSString(), PropertyType.DEFAULT); + properties = ProjectProperties.create(location.toOSString(), PropertyType.PROJECT); } // save the target hash string in the project persistent property @@ -353,6 +353,7 @@ public final class Sdk { * @param project the request project * @return the ProjectState for the project. */ + @SuppressWarnings("deprecation") public static ProjectState getProjectState(IProject project) { if (project == null) { return null; @@ -361,19 +362,44 @@ public final class Sdk { synchronized (LOCK) { ProjectState state = sProjectStateMap.get(project); if (state == null) { - // load the default.properties from the project folder. + // load the project.properties from the project folder. IPath location = project.getLocation(); if (location == null) { // can return null when the project is being deleted. // do nothing and return null; return null; } - ProjectProperties properties = ProjectProperties.load(location.toOSString(), - PropertyType.DEFAULT); + String projectLocation = location.toOSString(); + + ProjectProperties properties = ProjectProperties.load(projectLocation, + PropertyType.PROJECT); if (properties == null) { - AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'", - project.getName()); - return null; + // legacy support: look for default.properties and rename it if needed. + properties = ProjectProperties.load(projectLocation, + PropertyType.LEGACY_DEFAULT); + + if (properties == null) { + AdtPlugin.log(IStatus.ERROR, + "Failed to load properties file for project '%s'", + project.getName()); + return null; + } else { + //legacy mode. + // get a working copy with the new type "project" + ProjectPropertiesWorkingCopy wc = properties.makeWorkingCopy( + PropertyType.PROJECT); + // and save it + try { + wc.save(); + + // delete the old file. + ProjectProperties.delete(projectLocation, PropertyType.LEGACY_DEFAULT); + } catch (Exception e) { + AdtPlugin.log(IStatus.ERROR, + "Failed to rename properties file to %1$s for project '%s2$'", + PropertyType.PROJECT.getFilename(), project.getName()); + } + } } state = new ProjectState(project, properties); @@ -934,10 +960,10 @@ public final class Sdk { */ private IFileListener mFileListener = new IFileListener() { public void fileChanged(final IFile file, IMarkerDelta[] markerDeltas, int kind) { - if (SdkConstants.FN_DEFAULT_PROPERTIES.equals(file.getName()) && + if (SdkConstants.FN_PROJECT_PROPERTIES.equals(file.getName()) && file.getParent() == file.getProject()) { try { - // reload the content of the default.properties file and update + // reload the content of the project.properties file and update // the target. IProject iProject = file.getProject(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java index 3b1b59e..182c7b1 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java @@ -36,7 +36,6 @@ import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.internal.project.ProjectProperties.PropertyType; -import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy; import com.android.sdklib.xml.AndroidManifest; import com.android.sdklib.xml.ManifestData; import com.android.sdklib.xml.ManifestData.Activity; @@ -1224,10 +1223,8 @@ public class NewProjectCreationPage extends WizardPage { // is tied to the current target, so changing it would invalidate the project we're // trying to load in the first place. if (currentTarget == null || !mInfo.isCreateFromSample()) { - ProjectPropertiesWorkingCopy p = ProjectProperties.create(projectLocation, null); + ProjectProperties p = ProjectProperties.load(projectLocation, PropertyType.PROJECT); if (p != null) { - // Check the {build|default}.properties files if present - p.merge(PropertyType.BUILD).merge(PropertyType.DEFAULT); String v = p.getProperty(ProjectProperties.PROPERTY_TARGET); IAndroidTarget desiredTarget = Sdk.getCurrent().getTargetFromHashString(v); // We can change the current target if: diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java index b4e7a3f..af6b56b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFileWrapper.java @@ -24,6 +24,7 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -90,6 +91,15 @@ public class IFileWrapper implements IAbstractFile { return mFile.exists(); } + public boolean delete() { + try { + mFile.delete(true /*force*/, new NullProgressMonitor()); + return true; + } catch (CoreException e) { + return false; + } + } + /** * Returns the {@link IFile} object that the receiver could represent. Can be null */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java index 85106c2..01c230f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/io/IFolderWrapper.java @@ -25,6 +25,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import java.util.ArrayList; @@ -55,6 +56,16 @@ public class IFolderWrapper implements IAbstractFolder { return mContainer.exists(); } + public boolean delete() { + try { + mContainer.delete(true /*force*/, new NullProgressMonitor()); + return true; + } catch (CoreException e) { + return false; + } + } + + public IAbstractResource[] listMembers() { try { IResource[] members = mContainer.members(); diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java index bf9283d..10f0853 100644 --- a/sdkmanager/app/src/com/android/sdkmanager/Main.java +++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java @@ -599,10 +599,10 @@ public class Main { // now get the target hash ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(), - PropertyType.DEFAULT); + PropertyType.PROJECT); if (p == null) { errorAndExit("Unable to load the main project's %1$s", - PropertyType.DEFAULT.getFilename()); + PropertyType.PROJECT.getFilename()); return; } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java index 181e7ec..c9d1b50 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -96,17 +96,14 @@ public final class SdkConstants { /** hardware properties definition file */ public final static String FN_HARDWARE_INI = "hardware-properties.ini"; - /** project default property file */ - public final static String FN_DEFAULT_PROPERTIES = "default.properties"; - - /** project export property file */ - public final static String FN_EXPORT_PROPERTIES = "export.properties"; + /** project property file */ + public final static String FN_PROJECT_PROPERTIES = "project.properties"; /** project local property file */ public final static String FN_LOCAL_PROPERTIES = "local.properties"; - /** project build property file */ - public final static String FN_BUILD_PROPERTIES = "build.properties"; + /** project ant property file */ + public final static String FN_ANT_PROPERTIES = "ant.properties"; /** Skin layout file */ public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$ diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java index adfa90d..9cac373 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java @@ -17,6 +17,8 @@ package com.android.sdklib.internal.project; import com.android.AndroidConstants; +import com.android.io.FileWrapper; +import com.android.io.FolderWrapper; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; @@ -203,7 +205,7 @@ public class ProjectCreator { // target goes in default properties ProjectPropertiesWorkingCopy defaultProperties = ProjectProperties.create(folderPath, - PropertyType.DEFAULT); + PropertyType.PROJECT); defaultProperties.setProperty(ProjectProperties.PROPERTY_TARGET, target.hashString()); if (library) { defaultProperties.setProperty(ProjectProperties.PROPERTY_LIBRARY, "true"); @@ -212,7 +214,7 @@ public class ProjectCreator { // create a build.properties file with just the application package ProjectPropertiesWorkingCopy buildProperties = ProjectProperties.create(folderPath, - PropertyType.BUILD); + PropertyType.ANT); if (isTestProject) { buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, @@ -420,7 +422,8 @@ public class ProjectCreator { * Workflow: *

    *
  • Check AndroidManifest.xml is present (required) - *
  • Check there's a default.properties with a target *or* --target was specified + *
  • Check if there's a legacy properties file and convert it + *
  • Check there's a project.properties with a target *or* --target was specified *
  • Update default.prop if --target was specified *
  • Refresh/create "sdk" in local.properties *
  • Build.xml: create if not present or if version-tag is found or not. version-tag:custom @@ -434,22 +437,32 @@ public class ProjectCreator { * @param libraryPath the path to a library to add to the references. Can be null. * @return true if the project was successfully updated. */ + @SuppressWarnings("deprecation") public boolean updateProject(String folderPath, IAndroidTarget target, String projectName, String libraryPath) { // since this is an update, check the folder does point to a project - File androidManifest = checkProjectFolder(folderPath, SdkConstants.FN_ANDROID_MANIFEST_XML); + FileWrapper androidManifest = checkProjectFolder(folderPath, + SdkConstants.FN_ANDROID_MANIFEST_XML); if (androidManifest == null) { return false; } - // get the parent File. - File projectFolder = androidManifest.getParentFile(); + // get the parent folder. + FolderWrapper projectFolder = (FolderWrapper) androidManifest.getParentFolder(); boolean hasProguard = false; - // Check there's a default.properties with a target *or* --target was specified + // Check there's a project.properties with a target *or* --target was specified IAndroidTarget originalTarget = null; - ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT); + boolean writeProjectProp = false; + ProjectProperties props = ProjectProperties.load(projectFolder, PropertyType.PROJECT); + + if (props == null) { + // no project.properties, try to load default.properties + props = ProjectProperties.load(projectFolder, PropertyType.LEGACY_DEFAULT); + writeProjectProp = true; + } + if (props != null) { String targetHash = props.getProperty(ProjectProperties.PROPERTY_TARGET); originalTarget = mSdkManager.getTargetFromHashString(targetHash); @@ -466,22 +479,24 @@ public class ProjectCreator { return false; } - boolean saveDefaultProps = false; + boolean saveProjectProps = false; ProjectPropertiesWorkingCopy propsWC = null; // Update default.prop if --target was specified - if (target != null) { + if (target != null || writeProjectProp) { // we already attempted to load the file earlier, if that failed, create it. if (props == null) { - propsWC = ProjectProperties.create(folderPath, PropertyType.DEFAULT); + propsWC = ProjectProperties.create(projectFolder, PropertyType.PROJECT); } else { - propsWC = props.makeWorkingCopy(); + propsWC = props.makeWorkingCopy(PropertyType.PROJECT); } // set or replace the target - propsWC.setProperty(ProjectProperties.PROPERTY_TARGET, target.hashString()); - saveDefaultProps = true; + if (target != null) { + propsWC.setProperty(ProjectProperties.PROPERTY_TARGET, target.hashString()); + } + saveProjectProps = true; } if (libraryPath != null) { @@ -496,7 +511,7 @@ public class ProjectCreator { File libProject = new File(libraryPath); String resolvedPath; if (libProject.isAbsolute() == false) { - libProject = new File(folderPath, libraryPath); + libProject = new File(projectFolder, libraryPath); try { resolvedPath = libProject.getCanonicalPath(); } catch (IOException e) { @@ -530,29 +545,40 @@ public class ProjectCreator { String propName = ProjectProperties.PROPERTY_LIB_REF + Integer.toString(index); propsWC.setProperty(propName, libraryPath); - saveDefaultProps = true; + saveProjectProps = true; } // save the default props if needed. - if (saveDefaultProps) { + if (saveProjectProps) { try { assert propsWC != null; propsWC.save(); - println("Updated %1$s", PropertyType.DEFAULT.getFilename()); + if (writeProjectProp) { + println("Updated and renamed %1$s to %2$s", + PropertyType.LEGACY_DEFAULT.getFilename(), + PropertyType.PROJECT.getFilename()); + } else { + println("Updated %1$s", PropertyType.PROJECT.getFilename()); + } } catch (Exception e) { mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.DEFAULT.getFilename(), + PropertyType.PROJECT.getFilename(), folderPath); return false; } + + if (writeProjectProp) { + // need to delete the default prop file. + ProjectProperties.delete(projectFolder, PropertyType.LEGACY_DEFAULT); + } } // Refresh/create "sdk" in local.properties // because the file may already exists and contain other values (like apk config), // we first try to load it. - props = ProjectProperties.load(folderPath, PropertyType.LOCAL); + props = ProjectProperties.load(projectFolder, PropertyType.LOCAL); if (props == null) { - propsWC = ProjectProperties.create(folderPath, PropertyType.LOCAL); + propsWC = ProjectProperties.create(projectFolder, PropertyType.LOCAL); } else { propsWC = props.makeWorkingCopy(); } @@ -569,6 +595,31 @@ public class ProjectCreator { return false; } + // legacy: check if build.properties must be renamed to ant.properties. + props = ProjectProperties.load(projectFolder, PropertyType.ANT); + if (props == null) { + props = ProjectProperties.load(projectFolder, PropertyType.LEGACY_BUILD); + if (props != null) { + try { + // get a working copy with the new property type + propsWC = props.makeWorkingCopy(PropertyType.ANT); + propsWC.save(); + + // delete the old file + ProjectProperties.delete(projectFolder, PropertyType.LEGACY_BUILD); + + println("Renamed %1$s to %2$s", + PropertyType.LEGACY_BUILD.getFilename(), + PropertyType.ANT.getFilename()); + } catch (Exception e) { + mLog.error(e, "Failed to write %1$s file in '%2$s'", + PropertyType.ANT.getFilename(), + folderPath); + return false; + } + } + } + // Build.xml: create if not present or no in it File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML); boolean needsBuildXml = projectName != null || !buildXml.exists(); @@ -713,6 +764,7 @@ public class ProjectCreator { * @param folderPath the path of the test project. * @param pathToMainProject the path to the main project, relative to the test project. */ + @SuppressWarnings("deprecation") public void updateTestProject(final String folderPath, final String pathToMainProject, final SdkManager sdkManager) { // since this is an update, check the folder does point to a project @@ -744,16 +796,21 @@ public class ProjectCreator { } // now get the target from the main project - ProjectProperties defaultProp = ProjectProperties.load(resolvedPath, PropertyType.DEFAULT); - if (defaultProp == null) { - mLog.error(null, "No %1$s at: %2$s", PropertyType.DEFAULT.getFilename(), resolvedPath); - return; + ProjectProperties projectProp = ProjectProperties.load(resolvedPath, PropertyType.PROJECT); + if (projectProp == null) { + // legacy support for older file name. + projectProp = ProjectProperties.load(resolvedPath, PropertyType.LEGACY_DEFAULT); + if (projectProp == null) { + mLog.error(null, "No %1$s at: %2$s", PropertyType.PROJECT.getFilename(), + resolvedPath); + return; + } } - String targetHash = defaultProp.getProperty(ProjectProperties.PROPERTY_TARGET); + String targetHash = projectProp.getProperty(ProjectProperties.PROPERTY_TARGET); if (targetHash == null) { mLog.error(null, "%1$s in the main project has no target property.", - PropertyType.DEFAULT.getFilename()); + PropertyType.PROJECT.getFilename()); return; } @@ -802,40 +859,40 @@ public class ProjectCreator { } // add the test project specific properties. - ProjectProperties buildProps = ProjectProperties.load(folderPath, PropertyType.BUILD); - ProjectPropertiesWorkingCopy buildWorkingCopy; - if (buildProps == null) { - buildWorkingCopy = ProjectProperties.create(folderPath, PropertyType.BUILD); + // At this point, we know build.prop has been renamed ant.prop + ProjectProperties antProps = ProjectProperties.load(folderPath, PropertyType.ANT); + ProjectPropertiesWorkingCopy antWorkingCopy; + if (antProps == null) { + antWorkingCopy = ProjectProperties.create(folderPath, PropertyType.ANT); } else { - buildWorkingCopy = buildProps.makeWorkingCopy(); + antWorkingCopy = antProps.makeWorkingCopy(); } // set or replace the path to the main project - buildWorkingCopy.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, pathToMainProject); + antWorkingCopy.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, pathToMainProject); try { - buildWorkingCopy.save(); - println("Updated %1$s", PropertyType.BUILD.getFilename()); + antWorkingCopy.save(); + println("Updated %1$s", PropertyType.ANT.getFilename()); } catch (Exception e) { mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.BUILD.getFilename(), + PropertyType.ANT.getFilename(), folderPath); return; } - } /** * Checks whether the give folderPath is a valid project folder, and returns - * a {@link File} to the required file. + * a {@link FileWrapper} to the required file. *

    This checks that the folder exists and contains an AndroidManifest.xml file in it. *

    Any error are output using {@link #mLog}. * @param folderPath the folder to check * @param requiredFilename the file name of the file that's required. - * @return a {@link File} to the AndroidManifest.xml file, or null otherwise. + * @return a {@link FileWrapper} to the AndroidManifest.xml file, or null otherwise. */ - private File checkProjectFolder(String folderPath, String requiredFilename) { + private FileWrapper checkProjectFolder(String folderPath, String requiredFilename) { // project folder must exist and be a directory, since this is an update - File projectFolder = new File(folderPath); + FolderWrapper projectFolder = new FolderWrapper(folderPath); if (!projectFolder.isDirectory()) { mLog.error(null, "Project folder '%1$s' is not a valid directory.", projectFolder); @@ -843,7 +900,7 @@ public class ProjectCreator { } // Check AndroidManifest.xml is present - File requireFile = new File(projectFolder, requiredFilename); + FileWrapper requireFile = new FileWrapper(projectFolder, requiredFilename); if (!requireFile.isFile()) { mLog.error(null, "%1$s is not a valid project (%2$s not found).", diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java index cce7e47..3a73bef 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java @@ -83,10 +83,10 @@ public class ProjectProperties { public final static String PROPERTY_KEY_ALIAS = "key.alias"; public static enum PropertyType { - BUILD(SdkConstants.FN_BUILD_PROPERTIES, BUILD_HEADER, new String[] { + ANT(SdkConstants.FN_ANT_PROPERTIES, BUILD_HEADER, new String[] { PROPERTY_BUILD_SOURCE_DIR, PROPERTY_BUILD_OUT_DIR }, null), - DEFAULT(SdkConstants.FN_DEFAULT_PROPERTIES, DEFAULT_HEADER, new String[] { + PROJECT(SdkConstants.FN_PROJECT_PROPERTIES, DEFAULT_HEADER, new String[] { PROPERTY_TARGET, PROPERTY_LIBRARY, PROPERTY_LIB_REF_REGEX, PROPERTY_KEY_STORE, PROPERTY_KEY_ALIAS, PROPERTY_PROGUARD_CONFIG, PROPERTY_RULES_PATH @@ -94,7 +94,12 @@ public class ProjectProperties { LOCAL(SdkConstants.FN_LOCAL_PROPERTIES, LOCAL_HEADER, new String[] { PROPERTY_SDK }, - new String[] { PROPERTY_SDK_LEGACY }); + new String[] { PROPERTY_SDK_LEGACY }), + @Deprecated + LEGACY_DEFAULT("default.properties", null, null, null), + @Deprecated + LEGACY_BUILD("build.properties", null, null, null); + private final String mFilename; private final String mHeader; @@ -170,7 +175,7 @@ public class ProjectProperties { "# This file must be checked in Version Control Systems.\n" + "#\n" + "# To customize properties used by the Ant build system use,\n" + - "# \"build.properties\", and override values to adapt the script to your\n" + + "# \"ant.properties\", and override values to adapt the script to your\n" + "# project structure.\n" + "\n"; @@ -194,31 +199,13 @@ public class ProjectProperties { "# The password will be asked during the build when you use the 'release' target.\n" + "\n"; - private final static String EXPORT_HEADER = -// 1-------10--------20--------30--------40--------50--------60--------70--------80 - "# Export properties\n" + - "#\n" + - "# This file must be checked in Version Control Systems.\n" + - "\n" + - "# The main content for this file is:\n" + - "# - package name for the application being export\n" + - "# - list of the projects being export\n" + - "# - version code for the application\n" + - "\n" + - "# You can also use it define how the release builds are signed by declaring\n" + - "# the following properties:\n" + - "# 'key.store' for the location of your keystore and\n" + - "# 'key.alias' for the name of the key alias to use.\n" + - "# The password will be asked during the build when you use the 'release' target.\n" + - "\n"; - protected final IAbstractFolder mProjectFolder; protected final Map mProperties; protected final PropertyType mType; /** * Loads a project properties file and return a {@link ProjectProperties} object - * containing the properties + * containing the properties. * * @param projectFolderOsPath the project folder. * @param type One the possible {@link PropertyType}s. @@ -230,7 +217,7 @@ public class ProjectProperties { /** * Loads a project properties file and return a {@link ProjectProperties} object - * containing the properties + * containing the properties. * * @param projectFolder the project folder. * @param type One the possible {@link PropertyType}s. @@ -249,6 +236,37 @@ public class ProjectProperties { } /** + * Deletes a project properties file. + * + * @param projectFolder the project folder. + * @param type One the possible {@link PropertyType}s. + * @return true if success. + */ + public static boolean delete(IAbstractFolder projectFolder, PropertyType type) { + if (projectFolder.exists()) { + IAbstractFile propFile = projectFolder.getFile(type.mFilename); + if (propFile.exists()) { + return propFile.delete(); + } + } + + return false; + } + + /** + * Deletes a project properties file. + * + * @param projectFolderOsPath the project folder. + * @param type One the possible {@link PropertyType}s. + * @return true if success. + */ + public static boolean delete(String projectFolderOsPath, PropertyType type) { + IAbstractFolder wrapper = new FolderWrapper(projectFolderOsPath); + return delete(wrapper, type); + } + + + /** * Creates a new project properties object, with no properties. *

    The file is not created until {@link ProjectPropertiesWorkingCopy#save()} is called. * @param projectFolderOsPath the project folder. @@ -279,11 +297,24 @@ public class ProjectProperties { * @return a new instance of {@link ProjectPropertiesWorkingCopy} */ public ProjectPropertiesWorkingCopy makeWorkingCopy() { + return makeWorkingCopy(mType); + } + + /** + * Creates and returns a copy of the current properties as a + * {@link ProjectPropertiesWorkingCopy} that can be modified and saved. This also allows + * converting to a new type, by specifying a different {@link PropertyType}. + * + * @param type the {@link PropertyType} of the prop file to save. + * + * @return a new instance of {@link ProjectPropertiesWorkingCopy} + */ + public ProjectPropertiesWorkingCopy makeWorkingCopy(PropertyType type) { // copy the current properties in a new map HashMap propList = new HashMap(); propList.putAll(mProperties); - return new ProjectPropertiesWorkingCopy(mProjectFolder, propList, mType); + return new ProjectPropertiesWorkingCopy(mProjectFolder, propList, type); } /** diff --git a/templates/build.template b/templates/build.template index 9f13d6e..1ea1be9 100644 --- a/templates/build.template +++ b/templates/build.template @@ -1,15 +1,14 @@ - - - - + + + - + - - +