下面列出了org.apache.http.impl.conn.ProxySelectorRoutePlanner#com.android.annotations.NonNull 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
@NonNull
public Properties loadProperties(@NonNull File file) {
Properties props = new Properties();
Closer closer = Closer.create();
try {
FileInputStream fis = closer.register(new FileInputStream(file));
props.load(fis);
} catch (IOException ignore) {
} finally {
try {
closer.close();
} catch (IOException e) {
}
}
return props;
}
/**
* Utility method to parse the {@link PkgProps#PKG_REVISION} property as a no-preview
* revision (major.minor.micro integers but no preview part.)
*
* @param props The properties to parse.
* @return A {@link NoPreviewRevision} or
* null if there is no such property or it couldn't be parsed.
* @param propKey The name of the property. Must not be null.
*/
@Nullable
public static NoPreviewRevision getPropertyNoPreview(
@Nullable Properties props,
@NonNull String propKey) {
String revStr = getProperty(props, propKey, null);
NoPreviewRevision rev = null;
if (revStr != null) {
try {
rev = NoPreviewRevision.parseRevision(revStr);
} catch (NumberFormatException ignore) {}
}
return rev;
}
@NonNull
private static FileCache.Inputs getBuildCacheInputs(@NonNull Path input, int minSdkVersion)
throws IOException {
FileCache.Inputs.Builder buildCacheInputs =
new FileCache.Inputs.Builder(FileCache.Command.DESUGAR_LIBRARY);
buildCacheInputs
.putFile(
FileCacheInputParams.FILE.name(),
input.toFile(),
FileCache.FileProperties.PATH_HASH)
.putString(
FileCacheInputParams.PLUGIN_VERSION.name(),
Version.ANDROID_GRADLE_PLUGIN_VERSION)
.putLong(FileCacheInputParams.MIN_SDK_VERSION.name(), minSdkVersion);
return buildCacheInputs.build();
}
/**
* Creates a new doc package descriptor.
*
* @param revision The revision of the doc package.
* @return A {@link PkgDesc} describing this doc package.
*/
@NonNull
public static Builder newDoc(@NonNull AndroidVersion version,
@NonNull MajorRevision revision) {
Builder p = new Builder(PkgType.PKG_DOC);
p.mAndroidVersion = version;
p.mMajorRevision = revision;
p.mCustomIsUpdateFor = new IIsUpdateFor() {
@Override
public boolean isUpdateFor(PkgDesc thisPkgDesc, IPkgDesc existingDesc) {
if (existingDesc == null ||
!thisPkgDesc.getType().equals(existingDesc.getType())) {
return false;
}
// This package is unique in the SDK. It's an update if the API is newer
// or the revision is newer for the same API.
int diff = thisPkgDesc.getAndroidVersion().compareTo(
existingDesc.getAndroidVersion());
return diff > 0 ||
(diff == 0 && thisPkgDesc.getMajorRevision().compareTo(
existingDesc.getMajorRevision()) > 0);
}
};
return p;
}
/**
* Utility method to parse the {@link PkgProps#PKG_REVISION} property as a major
* revision (major integer, no minor/micro/preview parts.)
*
* @param props The properties to parse.
* @return A {@link MajorRevision} or null if there is no such property or it couldn't be parsed.
* @param propKey The name of the property. Must not be null.
*/
@Nullable
public static MajorRevision getPropertyMajor(
@Nullable Properties props,
@NonNull String propKey) {
String revStr = getProperty(props, propKey, null);
MajorRevision rev = null;
if (revStr != null) {
try {
rev = MajorRevision.parseRevision(revStr);
} catch (NumberFormatException ignore) {}
}
return rev;
}
private NodeTypes(
@NonNull MergeType mergeType,
@NonNull NodeKeyResolver nodeKeyResolver,
boolean mutipleDeclarationAllowed,
@Nullable AttributeModel.Builder... attributeModelBuilders) {
this.mMergeType = Preconditions.checkNotNull(mergeType);
this.mNodeKeyResolver = Preconditions.checkNotNull(nodeKeyResolver);
ImmutableList.Builder<AttributeModel> attributeModels =
new ImmutableList.Builder<AttributeModel>();
if (attributeModelBuilders != null) {
for (AttributeModel.Builder attributeModelBuilder : attributeModelBuilders) {
attributeModels.add(attributeModelBuilder.build());
}
}
this.mAttributeModels = attributeModels.build();
this.mMultipleDeclarationAllowed = mutipleDeclarationAllowed;
}
/**
* Creates an {@link AndroidVersion} from {@link Properties}. The properties must contain
* android version information, or an exception will be thrown.
* @throws AndroidVersionException if no Android version information have been found
*
* @see #saveProperties(Properties)
*/
public AndroidVersion(@NonNull Properties properties) throws AndroidVersionException {
Exception error = null;
String apiLevel = properties.getProperty(PkgProps.VERSION_API_LEVEL, null/*defaultValue*/);
if (apiLevel != null) {
try {
mApiLevel = Integer.parseInt(apiLevel);
mCodename = sanitizeCodename(properties.getProperty(PkgProps.VERSION_CODENAME,
null/*defaultValue*/));
return;
} catch (NumberFormatException e) {
error = e;
}
}
// reaching here means the Properties object did not contain the apiLevel which is required.
throw new AndroidVersionException(PkgProps.VERSION_API_LEVEL + " not found!", error);
}
/**
* Returns a map of (resource name, resource value) for the given {@link ResourceType}.
* <p/>The values returned are taken from the resource files best matching a given
* {@link FolderConfiguration}.
* @param type the type of the resources.
* @param referenceConfig the configuration to best match.
*/
@NonNull
private Map<String, ResourceValue> getConfiguredResource(@NonNull ResourceType type,
@NonNull FolderConfiguration referenceConfig) {
// get the resource item for the given type
Map<String, ResourceItem> items = mResourceMap.get(type);
if (items == null) {
return new HashMap<String, ResourceValue>();
}
// create the map
HashMap<String, ResourceValue> map = new HashMap<String, ResourceValue>(items.size());
for (ResourceItem item : items.values()) {
ResourceValue value = item.getResourceValue(type, referenceConfig,
isFrameworkRepository());
if (value != null) {
map.put(item.getName(), value);
}
}
return map;
}
/**
* Compares two {@link Element}s recursively.
* They must be identical with the same structure.
* Order should not matter.
* Whitespace and comments are ignored.
*
* @param expected The first element to compare.
* @param actual The second element to compare with.
* @param nextSiblings If true, will also compare the following siblings.
* If false, it will just compare the given node.
* @param diff An optional {@link StringBuilder} where to accumulate a diff output.
* @param keyAttr An optional key attribute to always add to elements when dumping a diff.
* @return True if {@code e1} and {@code e2} are equal.
*/
private boolean compareElements(
@NonNull Node expected,
@NonNull Node actual,
boolean nextSiblings,
@Nullable StringBuilder diff,
@Nullable String keyAttr) {
Map<String, String> nsPrefixE = new HashMap<String, String>();
Map<String, String> nsPrefixA = new HashMap<String, String>();
String sE = MergerXmlUtils.printElement(expected, nsPrefixE, ""); //$NON-NLS-1$
String sA = MergerXmlUtils.printElement(actual, nsPrefixA, ""); //$NON-NLS-1$
if (sE.equals(sA)) {
return true;
} else {
if (diff != null) {
MergerXmlUtils.printXmlDiff(diff, sE, sA, nsPrefixE, nsPrefixA, NS_URI + ':' + keyAttr);
}
return false;
}
}
@Nullable
private InputStream readCachedFile(@NonNull File cached) throws IOException {
InputStream is = null;
int inc = 65536;
int curr = 0;
long len = cached.length();
assert len < Integer.MAX_VALUE;
if (len >= MAX_SMALL_FILE_SIZE) {
// This is supposed to cache small files, not 2+ GB files.
return null;
}
byte[] result = new byte[(int) (len > 0 ? len : inc)];
try {
is = mFileOp.newFileInputStream(cached);
int n;
while ((n = is.read(result, curr, result.length - curr)) != -1) {
curr += n;
if (curr == result.length) {
byte[] temp = new byte[curr + inc];
System.arraycopy(result, 0, temp, 0, curr);
result = temp;
}
}
return new ByteArrayInputStream(result, 0, curr);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignore) {}
}
}
}
/**
* Returns a display string for a resource lookup
* @param url the resource url, such as {@code @string/foo}
* @param lookupChain the list of resolved items to display
* @return the display string
*/
@NonNull
public static String getDisplayString(
@NonNull String url,
@NonNull List<ResourceValue> lookupChain) {
StringBuilder sb = new StringBuilder();
sb.append(url);
String prev = url;
for (ResourceValue element : lookupChain) {
if (element == null) {
continue;
}
String value = element.getValue();
if (value == null) {
continue;
}
String text = value;
if (text.equals(prev)) {
continue;
}
sb.append(" => ");
// Strip paths
if (!(text.startsWith(PREFIX_THEME_REF) || text.startsWith(PREFIX_RESOURCE_REF))) {
int end = Math.max(text.lastIndexOf('/'), text.lastIndexOf('\\'));
if (end != -1) {
text = text.substring(end + 1);
}
}
sb.append(text);
prev = value;
}
return sb.toString();
}
/**
* Create a new add-on package descriptor.
* <p/>
* The vendor id and the name id provided are used to compute the add-on's
* target hash.
*
* @param version The android version of the add-on package.
* @param revision The revision of the add-on package.
* @param addonVendor The vendor id/display of the add-on package.
* @param addonName The name id/display of the add-on package.
* @return A {@link PkgDesc} describing this add-on package.
*/
@NonNull
public static Builder newAddon(@NonNull AndroidVersion version,
@NonNull MajorRevision revision,
@NonNull IdDisplay addonVendor,
@NonNull IdDisplay addonName) {
Builder p = new Builder(PkgType.PKG_ADDON);
p.mAndroidVersion = version;
p.mMajorRevision = revision;
p.mVendor = addonVendor;
p.mNameIdDisplay = addonName;
return p;
}
private void removeItem(@NonNull ResourceItem removedItem) {
synchronized (ITEM_MAP_LOCK) {
Multimap<String, ResourceItem> map = getMap(removedItem.getType(), false);
if (map != null) {
map.remove(removedItem.getName(), removedItem);
}
}
}
private static boolean isAnnotationPartOf(
@NonNull List<AnnotationNode> annotations, @NonNull String annotationInternalName) {
for (AnnotationNode annotation : annotations) {
if (annotation.desc.equals(annotationInternalName)) {
return true;
}
}
return false;
}
/**
* Private constructor.
* <p/>
* Use {@link #load(String, PropertyType)} or {@link #create(String, PropertyType)}
* to instantiate.
*/
protected ProjectProperties(
@NonNull IAbstractFolder projectFolder,
@NonNull Map<String, String> map,
@NonNull PropertyType type) {
mProjectFolder = projectFolder;
mProperties = map;
mType = type;
}
/**
* Creates a new debug store with the location, keyalias, and passwords specified in the
* config.
*
* @param signingConfig The signing config
* @param logger a logger object to receive the log of the creation.
* @throws KeytoolException
*/
public static boolean createDebugStore(@Nullable String storeType, @NonNull File storeFile,
@NonNull String storePassword, @NonNull String keyPassword,
@NonNull String keyAlias,
@NonNull ILogger logger) throws KeytoolException {
return createNewStore(storeType, storeFile, storePassword, keyPassword, keyAlias,
CERTIFICATE_DESC, 30 /* validity*/, logger);
}
@Override
public boolean validates(@NonNull MergingReport.Builder mergingReport,
@NonNull XmlAttribute attribute, @NonNull String value) {
boolean valid = super.validates(mergingReport, attribute, value);
if (valid) {
try {
Long decodedValue = Long.decode(value);
valid = decodedValue >= mMinimumValue && decodedValue < 0xFFFFFFFFL;
} catch(NumberFormatException e) {
valid = false;
}
if (!valid) {
attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR,
String.format(
"Attribute %1$s at %2$s is not a valid hexadecimal value,"
+ " minimum is 0x%3$08X, maximum is 0x%4$08X, found %5$s",
attribute.getId(),
attribute.printPosition(),
mMinimumValue,
Integer.MAX_VALUE,
value
));
}
return valid;
}
return false;
}
/**
* Enforces {@link SdkConstants#ANDROID_URI} declaration in the top level element.
* It is possible that the original manifest file did not contain any attribute declaration,
* therefore not requiring a xmlns: declaration. Yet the implicit elements handling may have
* added attributes requiring the namespace declaration.
*/
private static void enforceAndroidNamespaceDeclaration(@NonNull XmlDocument xmlDocument) {
XmlElement manifest = xmlDocument.getRootNode();
for (XmlAttribute xmlAttribute : manifest.getAttributes()) {
if (xmlAttribute.getXml().getName().startsWith(SdkConstants.XMLNS) &&
xmlAttribute.getValue().equals(SdkConstants.ANDROID_URI)) {
return;
}
}
// if we are here, we did not find the namespace declaration, add it.
manifest.getXml().setAttribute(SdkConstants.XMLNS + ":" + "android",
SdkConstants.ANDROID_URI);
}
protected void removeFile(@NonNull Collection<ResourceType> types,
@NonNull ResourceFile file) {
ensureInitialized();
for (ResourceType type : types) {
removeFile(type, file);
}
}
/**
* Post validation of the merged document. This will essentially check that all merging
* instructions were applied at least once.
*
* @param xmlDocument merged document to check.
* @param mergingReport report for errors and warnings.
*/
public static void validate(
@NonNull XmlDocument xmlDocument,
@NonNull MergingReport.Builder mergingReport) {
Preconditions.checkNotNull(xmlDocument);
Preconditions.checkNotNull(mergingReport);
enforceAndroidNamespaceDeclaration(xmlDocument);
reOrderElements(xmlDocument.getRootNode());
validate(xmlDocument.getRootNode(),
mergingReport.getActionRecorder().build(),
mergingReport);
}
/**
* Returns a long description for an {@link IDescription}.
* Can be empty but not null.
*/
@NonNull
@Override
public String getLongDescription() {
StringBuilder sb = new StringBuilder();
String s = getDescription();
if (s != null) {
sb.append(s);
}
if (sb.length() > 0) {
sb.append("\n");
}
sb.append(String.format("Revision %1$s%2$s",
getRevision().toShortString(),
isObsolete() ? " (Obsolete)" : ""));
s = getDescUrl();
if (s != null && s.length() > 0) {
sb.append(String.format("\n\nMore information at %1$s", s));
}
s = getReleaseNote();
if (s != null && s.length() > 0) {
sb.append("\n\nRelease note:\n").append(s);
}
s = getReleaseNoteUrl();
if (s != null && s.length() > 0) {
sb.append("\nRelease note URL: ").append(s);
}
return sb.toString();
}
static boolean isClassEligibleForStark(@NonNull File inputFile) {
if (inputFile.getPath().endsWith(SdkConstants.DOT_CLASS)) {
return isClassEligibleForStark(inputFile.getName());
} else {
return false;
}
}
static boolean isClassEligibleForStark(@NonNull String name) {
if (name.endsWith(SdkConstants.DOT_CLASS)) {
return !name.equals("R" + SdkConstants.DOT_CLASS) && !name.startsWith("R$");
} else {
return false;
}
}
/**
* Adds any declare styleable attr items below the given declare styleable nodes
* into the given list
*
* @param styleableNode the declare styleable node
* @param list the list to add items into
* @param map map of existing items to detect dups.
*/
static void addStyleableItems(@NonNull Node styleableNode,
@NonNull List<ResourceItem> list,
@Nullable Map<ResourceType, Set<String>> map,
@Nullable File from)
throws MergingException {
assert styleableNode.getNodeName().equals(ResourceType.DECLARE_STYLEABLE.getName());
NodeList nodes = styleableNode.getChildNodes();
for (int i = 0, n = nodes.getLength(); i < n; i++) {
Node node = nodes.item(i);
if (node.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
ResourceItem resource = getResource(node, from);
if (resource != null) {
assert resource.getType() == ResourceType.ATTR;
// is the attribute in the android namespace?
if (!resource.getName().startsWith(ANDROID_NS_NAME_PREFIX)) {
if (hasFormatAttribute(node) || XmlUtils.hasElementChildren(node)) {
checkDuplicate(resource, map);
resource.setIgnoredFromDiskMerge(true);
list.add(resource);
}
}
}
}
}
/**
* Save this {@link ArchFilter} attributes into the the given {@link Properties} object.
* These properties can later be given to the constructor that takes a {@link Properties} object.
* <p/>
* Null attributes are not saved in the properties.
*
* @param props A non-null properties object to fill with non-null attributes.
*/
void saveProperties(@NonNull Properties props) {
if (mHostOs != null) {
props.setProperty(PROP_HOST_OS, mHostOs.getXmlName());
}
if (mHostBits != null) {
props.setProperty(PROP_HOST_BITS, mHostBits.getXmlName());
}
if (mJvmBits != null) {
props.setProperty(PROP_JVM_BITS, mJvmBits.getXmlName());
}
if (mMinJvmVersion != null) {
props.setProperty(PROP_MIN_JVM_VERSION, mMinJvmVersion.toShortString());
}
}
@NonNull
private static AttrResourceValue parseAttrValue(@NonNull Node valueNode,
@NonNull AttrResourceValue attrValue) {
NodeList children = valueNode.getChildNodes();
for (int i = 0, n = children.getLength(); i < n; i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
NamedNodeMap attributes = child.getAttributes();
String name = getAttributeValue(attributes, ATTR_NAME);
if (name != null) {
String value = getAttributeValue(attributes, ATTR_VALUE);
if (value != null) {
try {
// Integer.decode/parseInt can't deal with hex value > 0x7FFFFFFF so we
// use Long.decode instead.
attrValue.addValue(name, (int) (long) Long.decode(value));
} catch (NumberFormatException e) {
// pass, we'll just ignore this value
}
}
}
}
}
return attrValue;
}
/**
* Creates a {@link FolderConfiguration} matching the folder segments.
* @param folderSegments The segments of the folder name. The first segments should contain
* the name of the folder
* @return a FolderConfiguration object, or null if the folder name isn't valid..
*/
@Nullable
public static FolderConfiguration getConfig(@NonNull String[] folderSegments) {
Iterator<String> iterator = Iterators.forArray(folderSegments);
if (iterator.hasNext()) {
// Skip the first segment: it should be just the base folder, such as "values" or
// "layout"
iterator.next();
}
return getConfigFromQualifiers(iterator);
}
/**
* Returns whether the given file is an ouput of this source file.
* @param file the file to test.
* @return true if the file is an output file.
*/
public boolean hasOutput(@NonNull File file) {
if (!mIsParsed) {
throw new IllegalStateException("Parsing was not done");
}
return mOutputFiles.contains(file);
}
/** Strips out a leading UTF byte order mark, if present */
@NonNull
public static String stripBom(@NonNull String xml) {
if (!xml.isEmpty() && xml.charAt(0) == '\uFEFF') {
return xml.substring(1);
}
return xml;
}
private Record(@NonNull ActionType actionType,
@NonNull ActionLocation actionLocation,
@NonNull XmlNode.NodeKey targetId,
@Nullable String reason) {
mActionType = Preconditions.checkNotNull(actionType);
mActionLocation = Preconditions.checkNotNull(actionLocation);
mTargetId = Preconditions.checkNotNull(targetId);
mReason = reason;
}