1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang; 34 35 import dalvik.system.VMStack; 36 37 import java.lang.annotation.Annotation; 38 import java.lang.reflect.AnnotatedElement; 39 import java.net.URL; 40 41 /** 42 * Contains information about a Java package. This includes implementation and 43 * specification versions. Typically this information is retrieved from the 44 * manifest. 45 * <p> 46 * Packages are managed by class loaders. All classes loaded by the same loader 47 * from the same package share a {@code Package} instance. 48 * </p> 49 * @since Android 1.0 50 * 51 * @see java.lang.ClassLoader 52 */ 53 public class Package implements AnnotatedElement { 54 55 private final String name, specTitle, specVersion, specVendor, implTitle, 56 implVersion, implVendor; 57 private final URL sealBase; 58 Package(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)59 Package(String name, String specTitle, String specVersion, String specVendor, 60 String implTitle, String implVersion, String implVendor, URL sealBase) { 61 this.name = name; 62 this.specTitle = specTitle; 63 this.specVersion = specVersion; 64 this.specVendor = specVendor; 65 this.implTitle = implTitle; 66 this.implVersion = implVersion; 67 this.implVendor = implVendor; 68 this.sealBase = sealBase; 69 } 70 71 /** 72 * Gets the annotation associated with the specified annotation type and 73 * this package, if present. 74 * 75 * @param annotationType 76 * the annotation type to look for. 77 * @return an instance of {@link Annotation} or {@code null}. 78 * @see java.lang.reflect.AnnotatedElement#getAnnotation(java.lang.Class) 79 * @since Android 1.0 80 */ 81 @SuppressWarnings("unchecked") getAnnotation(Class<T> annotationType)82 public <T extends Annotation> T getAnnotation(Class<T> annotationType) { 83 Annotation[] list = getAnnotations(); 84 for (int i = 0; i < list.length; i++) { 85 if (annotationType.isInstance(list[i])) { 86 return (T)list[i]; 87 } 88 } 89 90 return null; 91 } 92 93 /** 94 * Gets all annotations associated with this package, if any. 95 * 96 * @return an array of {@link Annotation} instances, which may be empty. 97 * @see java.lang.reflect.AnnotatedElement#getAnnotations() 98 * @since Android 1.0 99 */ getAnnotations()100 public Annotation[] getAnnotations() { 101 return getDeclaredAnnotations(this, true); 102 } 103 104 /** 105 * Gets all annotations directly declared on this package, if any. 106 * 107 * @return an array of {@link Annotation} instances, which may be empty. 108 * @see java.lang.reflect.AnnotatedElement#getDeclaredAnnotations() 109 * @since Android 1.0 110 */ getDeclaredAnnotations()111 public Annotation[] getDeclaredAnnotations() { 112 return getDeclaredAnnotations(this, false); 113 } 114 115 /* 116 * Returns the list of declared annotations of the given package. 117 * If no annotations exist, an empty array is returned. 118 * 119 * @param pkg the package of interest 120 * @param publicOnly reflects whether we want only public annotation or all 121 * of them. 122 * @return the list of annotations 123 */ 124 // TODO(Google) Provide proper (native) implementation. getDeclaredAnnotations(Package pkg, boolean publicOnly)125 private static native Annotation[] getDeclaredAnnotations(Package pkg, 126 boolean publicOnly); 127 128 /** 129 * Indicates whether the specified annotation is present. 130 * 131 * @param annotationType 132 * the annotation type to look for. 133 * @return {@code true} if the annotation is present; {@code false} 134 * otherwise. 135 * @see java.lang.reflect.AnnotatedElement#isAnnotationPresent(java.lang.Class) 136 * @since Android 1.0 137 */ isAnnotationPresent( Class<? extends Annotation> annotationType)138 public boolean isAnnotationPresent( 139 Class<? extends Annotation> annotationType) { 140 return getAnnotation(annotationType) != null; 141 } 142 143 /** 144 * Returns the title of the implementation of this package, or {@code null} 145 * if this is unknown. The format of this string is unspecified. 146 * 147 * @return the implementation title, may be {@code null}. 148 * @since Android 1.0 149 */ getImplementationTitle()150 public String getImplementationTitle() { 151 return implTitle; 152 } 153 154 /** 155 * Returns the name of the vendor or organization that provides this 156 * implementation of the package, or {@code null} if this is unknown. The 157 * format of this string is unspecified. 158 * 159 * @return the implementation vendor name, may be {@code null}. 160 * @since Android 1.0 161 */ getImplementationVendor()162 public String getImplementationVendor() { 163 return implVendor; 164 } 165 166 /** 167 * Returns the version of the implementation of this package, or {@code 168 * null} if this is unknown. The format of this string is unspecified. 169 * 170 * @return the implementation version, may be {@code null}. 171 * @since Android 1.0 172 */ getImplementationVersion()173 public String getImplementationVersion() { 174 return implVersion; 175 } 176 177 /** 178 * Returns the name of this package in the standard dot notation; for 179 * example: "java.lang". 180 * 181 * @return the name of this package. 182 * @since Android 1.0 183 */ getName()184 public String getName() { 185 return name; 186 } 187 188 /** 189 * Attempts to locate the requested package in the caller's class loader. If 190 * no package information can be located, {@code null} is returned. 191 * 192 * @param packageName 193 * the name of the package to find. 194 * @return the requested package, or {@code null}. 195 * @see ClassLoader#getPackage(java.lang.String) 196 * @since Android 1.0 197 */ getPackage(String packageName)198 public static Package getPackage(String packageName) { 199 ClassLoader classloader = VMStack.getCallingClassLoader(); 200 return classloader.getPackage(packageName); 201 } 202 203 /** 204 * Returns all the packages known to the caller's class loader. 205 * 206 * @return all the packages known to the caller's class loader. 207 * @see ClassLoader#getPackages 208 * @since Android 1.0 209 */ getPackages()210 public static Package[] getPackages() { 211 ClassLoader classloader = VMStack.getCallingClassLoader(); 212 return classloader.getPackages(); 213 } 214 215 /** 216 * Returns the title of the specification this package implements, or 217 * {@code null} if this is unknown. 218 * 219 * @return the specification title, may be {@code null}. 220 * @since Android 1.0 221 */ getSpecificationTitle()222 public String getSpecificationTitle() { 223 return specTitle; 224 } 225 226 /** 227 * Returns the name of the vendor or organization that owns and maintains 228 * the specification this package implements, or {@code null} if this is 229 * unknown. 230 * 231 * @return the specification vendor name, may be {@code null}. 232 * @since Android 1.0 233 */ getSpecificationVendor()234 public String getSpecificationVendor() { 235 return specVendor; 236 } 237 238 /** 239 * Returns the version of the specification this package implements, or 240 * {@code null} if this is unknown. The version string is a sequence of 241 * non-negative integers separated by dots; for example: "1.2.3". 242 * 243 * @return the specification version string, may be {@code null}. 244 * @since Android 1.0 245 */ getSpecificationVersion()246 public String getSpecificationVersion() { 247 return specVersion; 248 } 249 250 @Override hashCode()251 public int hashCode() { 252 return name.hashCode(); 253 } 254 255 /** 256 * Indicates whether this package's specification version is compatible with 257 * the specified version string. Version strings are compared by comparing 258 * each dot separated part of the version as an integer. 259 * 260 * @param version 261 * the version string to compare against. 262 * @return {@code true} if the package versions are compatible; {@code 263 * false} otherwise. 264 * @throws NumberFormatException 265 * if this package's version string or the one provided are not 266 * in the correct format. 267 * @since Android 1.0 268 */ isCompatibleWith(String version)269 public boolean isCompatibleWith(String version) 270 throws NumberFormatException { 271 String[] requested = version.split("."); 272 String[] provided = specVersion.split("."); 273 274 for (int i = 0; i < Math.min(requested.length, provided.length); i++) { 275 int reqNum = Integer.parseInt(requested[i]); 276 int provNum = Integer.parseInt(provided[i]); 277 278 if (reqNum > provNum) { 279 return false; 280 } else if (reqNum < provNum) { 281 return true; 282 } 283 } 284 285 if (requested.length > provided.length) { 286 return false; 287 } 288 289 return true; 290 } 291 292 /** 293 * Indicates whether this package is sealed. 294 * 295 * @return {@code true} if this package is sealed; {@code false} otherwise. 296 * @since Android 1.0 297 */ isSealed()298 public boolean isSealed() { 299 return sealBase != null; 300 } 301 302 /** 303 * Indicates whether this package is sealed with respect to the specified 304 * URL. 305 * 306 * @param url 307 * the URL to check. 308 * @return {@code true} if this package is sealed with {@code url}; {@code 309 * false} otherwise 310 * @since Android 1.0 311 */ isSealed(URL url)312 public boolean isSealed(URL url) { 313 return sealBase != null && sealBase.sameFile(url); 314 } 315 316 @Override toString()317 public String toString() { 318 return "package " + name; 319 } 320 } 321 322