001    /*
002     * $Id: ClassTester.java,v 1.4 2010/12/31 14:40:14 oboehm Exp $
003     *
004     * Copyright (c) 2010 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 27.12.2010 by oliver (ob@oasd.de)
019     */
020    
021    package patterntesting.runtime.experimental;
022    
023    import java.security.AccessController;
024    import java.util.Set;
025    import java.security.PrivilegedAction;
026    
027    /**
028     * If you want to test some dependencies to a given class you can use this
029     * tester here.
030     *
031     * @author oliver
032     * @since 1.1 (27.12.2010)
033     */
034    public final class ClassTester {
035    
036        private final Class<?> clazz;
037        private final XrayClassLoader classloader = AccessController.doPrivileged(new PrivilegedAction<XrayClassLoader>() {
038            public XrayClassLoader run() {
039                return new XrayClassLoader();
040            }
041        });
042    
043        /**
044         * Instantiates a new class tester.
045         *
046         * @param classname the classname
047         * @throws ClassNotFoundException the class not found exception
048         */
049        public ClassTester(final String classname) throws ClassNotFoundException {
050            this.clazz = this.classloader.loadClass(classname);
051            if (clazz == null) {
052                throw new ClassNotFoundException(classname);
053            }
054        }
055    
056        /**
057         * Gets the class name.
058         *
059         * @return the class name
060         */
061        public String getClassName() {
062            return this.clazz.getName();
063        }
064    
065        /**
066         * Gets the dependencies of the class name.
067         * To get all dependencies we load all declared methods, fields and
068         * other stuff.
069         *
070         * @return the dependencies of
071         */
072        public Set<Class<?>> getDependencies() {
073            this.clazz.getDeclaredAnnotations();
074            this.clazz.getDeclaredClasses();
075            this.clazz.getDeclaredConstructors();
076            this.clazz.getDeclaredFields();
077            this.clazz.getDeclaredMethods();
078            return classloader.getLoadedClasses();
079        }
080    
081        /**
082         * Checks if the stored class depends on another class.
083         * Because the given otherClass is using probably another class loader
084         * we compare the class name to decide if it is loaded.
085         *
086         * @param otherClass the other class
087         * @return true, if successful
088         */
089        public boolean dependsOn(final Class<?> otherClass) {
090            return dependsOn(otherClass.getName());
091        }
092    
093        /**
094         * Checks if the stored class depends on another class.
095         *
096         * @param otherClassname the other classname
097         * @return true, if successful
098         */
099        public boolean dependsOn(final String otherClassname) {
100            Set<Class<?>> dependencies = this.getDependencies();
101            for (Class<?> cl : dependencies) {
102                if (otherClassname.equals(cl.getName())) {
103                    return true;
104                }
105            }
106            return false;
107        }
108    
109    
110    
111        /////   STATIC UTILITY METHODS   //////////////////////////////////////////
112    
113        /**
114         * Gets the dependencies of the given class name.
115         *
116         * @param classname the classname
117         * @return the dependencies of
118         * @throws ClassNotFoundException the class not found exception
119         */
120        public static Set<Class<?>> getDependenciesOf(final String classname) throws ClassNotFoundException {
121            return new ClassTester(classname).getDependencies();
122        }
123    
124        /**
125         * Checks if the given class depends on another class.
126         *
127         * @param classname the classname
128         * @param otherClass the other class
129         * @return true, if successful
130         * @throws ClassNotFoundException the class not found exception
131         */
132        public static boolean dependsOn(final String classname, final Class<?> otherClass)
133                throws ClassNotFoundException {
134            return new ClassTester(classname).dependsOn(otherClass);
135        }
136    
137    }
138