• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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