1 /*
2  * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Portions copyright 2006-2009 James Murty. Please see LICENSE.txt
5  * for applicable license terms and NOTICE.txt for applicable notices.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License").
8  * You may not use this file except in compliance with the License.
9  * A copy of the License is located at
10  *
11  *  http://aws.amazon.com/apache2.0
12  *
13  * or in the "license" file accompanying this file. This file is distributed
14  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
15  * express or implied. See the License for the specific language governing
16  * permissions and limitations under the License.
17  */

18 package com.amazonaws.util;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.net.URL;
23 import java.util.jar.JarFile;
24
25 /**
26  * Classes related utilities.
27  */

28 public enum Classes {
29     ;
30     /**
31      * Returns the class of the immediate subclass of the given parent class for
32      * the given object instance; or null if such immediate subclass cannot be
33      * uniquely identified for the given object instance.
34      * 
35      * @param parentClass
36      *            the parent class. The child class is {@link Object} if and
37      *            only if the parent class is null.
38      * @param instance
39      *            the given object instance
40      */

41     public static Class<?> childClassOf(Class<?> parentClass,
42             Object instance) {
43         if (instance == null || instance == Object.class)
44             return null;
45         if (parentClass != null) {
46             if (parentClass.isInterface()) {
47                 // child of an interface class is not injective (ie one-to-one)
48                 return null;
49             }
50         }
51         Class<?> childClass = instance.getClass();
52         while (true) {
53             Class<?> parent = childClass.getSuperclass();
54             if (parent == parentClass)
55                 return childClass;
56             if (parent == null)
57                 return null;
58             childClass = parent;
59         }
60     }
61
62     /**
63      * Returns the jar file from which the given class is loaded; or null
64      * if no such jar file can be located.
65      */

66     public static JarFile jarFileOf(Class<?> klass) {
67         URL url = klass.getResource(
68             "/" + klass.getName().replace('.', '/') + ".class");
69         if (url == null)
70             return null;
71         String s = url.getFile();
72         int beginIndex = s.indexOf("file:") + "file:".length();
73         int endIndex = s.indexOf(".jar!");
74         if (endIndex == -1)
75             return null;
76         endIndex += ".jar".length();
77         String f = s.substring(beginIndex, endIndex);
78         File file = new File(f);
79         try {
80             return file.exists() ? new JarFile(file) : null;
81         } catch (IOException e) {
82             throw new IllegalStateException(e);
83         }
84     }
85 }
86