1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ant;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
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.repository.FullRevision;
import com.android.sdklib.repository.PkgProps;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.DeweyDecimal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
final class TaskHelper {
private static Map<String, String> DEFAULT_ATTR_VALUES = new HashMap<String, String>();
static {
DEFAULT_ATTR_VALUES.put("source.dir", SdkConstants.FD_SOURCES);
DEFAULT_ATTR_VALUES.put("out.dir", SdkConstants.FD_OUTPUT);
}
static String getDefault(String name) {
return DEFAULT_ATTR_VALUES.get(name);
}
static File getSdkLocation(Project antProject) {
// get the SDK location
String sdkOsPath = antProject.getProperty(ProjectProperties.PROPERTY_SDK);
// check if it's valid and exists
if (sdkOsPath == null || sdkOsPath.length() == 0) {
throw new BuildException("SDK Location is not set.");
}
File sdk = new File(sdkOsPath);
if (sdk.isDirectory() == false) {
throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkOsPath));
}
return sdk;
}
/**
* Returns the revision of the tools for a given SDK.
* @param sdkFile the {@link File} for the root folder of the SDK
* @return the tools revision or -1 if not found.
*/
@Nullable
static DeweyDecimal getToolsRevision(File sdkFile) {
Properties p = new Properties();
try{
// tools folder must exist, or this custom task wouldn't run!
File toolsFolder= new File(sdkFile, SdkConstants.FD_TOOLS);
File sourceProp = new File(toolsFolder, SdkConstants.FN_SOURCE_PROP);
FileInputStream fis = null;
try {
fis = new FileInputStream(sourceProp);
p.load(fis);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ignore) {
}
}
}
String value = p.getProperty(PkgProps.PKG_REVISION);
if (value != null) {
FullRevision rev = FullRevision.parseRevision(value);
return new DeweyDecimal(rev.toIntArray(false /*includePreview*/));
}
} catch (NumberFormatException e) {
// couldn't parse the version number.
} catch (FileNotFoundException e) {
// couldn't find the file.
} catch (IOException e) {
// couldn't find the file.
}
return null;
}
static String checkSinglePath(String attribute, Path path) {
String[] paths = path.list();
if (paths.length != 1) {
throw new BuildException(String.format(
"Value for '%1$s' is not valid. It must resolve to a single path", attribute));
}
return paths[0];
}
/**
* Returns the ProjectProperties for a given project path.
* This loads and merges all the .properties files in the same way that Ant does it.
*
* Note that this does not return all the Ant properties but only the one customized by the
* project's own build.xml file.
*
* If the project has no .properties files, this returns an empty {@link ProjectProperties}
* with type {@link PropertyType#PROJECT}.
*
* @param projectPath the path to the project root folder.
* @return a ProjectProperties.
*/
@NonNull
static ProjectProperties getProperties(@NonNull String projectPath) {
// the import order is local, ant, project so we need to respect this.
PropertyType[] types = PropertyType.getOrderedTypes();
// make a working copy of the first non null props and then merge the rest into it.
ProjectProperties properties = null;
for (int i = 0 ; i < types.length ; i++) {
properties = ProjectProperties.load(projectPath, types[i]);
if (properties != null) {
ProjectPropertiesWorkingCopy workingCopy = properties.makeWorkingCopy();
for (int k = i + 1 ; k < types.length ; k++) {
workingCopy.merge(types[k]);
}
// revert back to a read-only version
properties = workingCopy.makeReadOnlyCopy();
return properties;
}
}
// return an empty object with type PropertyType.PROJECT (doesn't actually matter).
return ProjectProperties.createEmpty(projectPath, PropertyType.PROJECT);
}
}
|