⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 annotationparser.java

📁 jetty SERVER連接資料庫用的軟體
💻 JAVA
字号:
//========================================================================//$Id: AnnotationParser.java 3680 2008-09-21 10:37:13Z janb $//Copyright 2006 Mort Bay Consulting Pty. Ltd.//------------------------------------------------------------------------//Licensed under the Apache License, Version 2.0 (the "License");//you may not use this file except in compliance with the License.//You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0//Unless required by applicable law or agreed to in writing, software//distributed under the License is distributed on an "AS IS" BASIS,//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.//See the License for the specific language governing permissions and//limitations under the License.//========================================================================package org.mortbay.jetty.annotations;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.ListIterator;import org.mortbay.jetty.plus.annotation.InjectionCollection;import org.mortbay.jetty.plus.annotation.LifeCycleCallbackCollection;import org.mortbay.jetty.plus.annotation.RunAsCollection;import org.mortbay.jetty.servlet.Holder;import org.mortbay.jetty.servlet.ServletHolder;import org.mortbay.jetty.webapp.WebAppContext;import org.mortbay.log.Log;import org.mortbay.util.IntrospectionUtil;/** * AnnotationParser * * None of the common annotations are inheritable, thus * calling getAnnotations() is exactly equivalent to  * getDeclaredAnnotations(). Therefore, in order to find * all relevant annotations, the full inheritance tree of * a class must be considered. *  * From the spec: *  Class-level annotations only affect the class they  *  annotate and their members, that is, its methods and fields.  *  They never affect a member declared by a superclass, even  *  if it is not hidden or overridden by the class in question. *  *  In addition to affecting the annotated class, class-level  *  annotations may act as a shorthand for member-level annotations.  *  If a member carries a specific member-level annotation, any  *  annotations of the same type implied by a class-level annotation  *  are ignored. In other words, explicit member-level annotations *  have priority over member-level annotations implied by a class-level  *  annotation. For example, a @WebService annotation on a class implies  *  that all the public method in the class that it is applied on are  *  annotated with @WebMethod if there is no @WebMethod annotation on  *  any of the methods. However if there is a @WebMethod annotation on  *  any method then the @WebService does not imply the presence of  *  @WebMethod on the other public methods in the class. *   *  The interfaces implemented by a class never contribute annotations  *  to the class itself or any of its members. *   *  Members inherited from a superclass and which are not hidden or  *  overridden maintain the annotations they had in the class that *  declared them, including member-level annotations implied by  *  class-level ones. *   *  Member-level annotations on a hidden or overridden member are  *  always ignored */public class AnnotationParser{    /**     * Examine the class hierarchy for a class, finding all annotations. Then, merge any      * servlet2.5 spec annotations found with those already existing (from parsing web.xml)     * respecting the overriding rules found in the spec.     *      * @param webApp the webapp     * @param clazz the class to inspect     * @param runAs any run-as elements from web.xml     * @param injections any injections specified in web.xml     * @param callbacks any postconstruct/predestroy callbacks in web.xml     */    public static void parseAnnotations (WebAppContext webApp, Class clazz, RunAsCollection runAs, InjectionCollection injections, LifeCycleCallbackCollection callbacks)    {        if (clazz==null)            return;        AnnotationCollection annotations = processClass(clazz);        annotations.setWebAppContext(webApp);        annotations.processRunAsAnnotations(runAs);        annotations.processResourcesAnnotations();        annotations.processResourceAnnotations(injections);        annotations.processLifeCycleCallbackAnnotations(callbacks);    }            /**     * Examine the class hierarchy for this class looking for annotations.     *      * @param clazz     * @return AnnotationCollection     */    static AnnotationCollection processClass (Class clazz)    {         AnnotationCollection collection = new AnnotationCollection();        if (clazz==null)            return collection;               collection.setTargetClass(clazz);                //add any class level annotations        collection.addClass(clazz);               //Add all the fields with annotations.        Field[] fields = clazz.getDeclaredFields();        //For each field, get all of it's annotations        for (int i=0; i<fields.length; i++)        {            collection.addField(fields[i]);        }                //Get all the methods with annotations        Method[] methods = clazz.getDeclaredMethods();        for (int i=0; i<methods.length;i++)        {            collection.addMethod(methods[i]);        }                //process the inheritance hierarchy for the class        Class ancestor = clazz.getSuperclass();        while (ancestor!=null && (!ancestor.equals(Object.class)))        {            processHierarchy (clazz, ancestor, collection);            ancestor = ancestor.getSuperclass();        }                 return collection;    }                /**     * Methods which are inherited retain their annotations.     * Methods which are not inherited and not overridden or hidden must also have their annotations processed.     * An overridden method can remove or change it's annotations.     * @param targetClazz     * @param ancestor     * @param targetClazzMethods     */    private static void processHierarchy (Class targetClazz, Class ancestor, AnnotationCollection collection)    {        if (targetClazz==null)            return;        if (ancestor==null)            return;                //If the ancestor has class level annotations, remember it        collection.addClass(ancestor);                //Get annotations on the declared methods of the ancestor class.         //For each declared method that has an annotation, we need to        //determine if that method is inheritable&&!overridden or hidden        //in derived classes of the ancestor, in which case it contributes        //an annotation to the collection        //OR        //if the method is not inheritable, but has an annotation, it still        //contributes an annotation (even private non-inherited methods must        //have their annotations honoured)        Method[] methods = ancestor.getDeclaredMethods();        for (int i=0; i<methods.length;i++)        {            if (methods[i].getAnnotations().length > 0)            {               if (!isOverriddenOrHidden(targetClazz, methods[i]))                   collection.addMethod(methods[i]);            }         }                //Get annotations on declared fields. For each field work out if it is        //overridden or hidden in targetClazz        Field[] fields = ancestor.getDeclaredFields();        for (int i=0;i<fields.length;i++)        {            if (fields[i].getAnnotations().length > 0)            {                //the field has annotations, so check to see if it should be inherited                //field is inheritable if it is:                // NOT private                // of package scope and of the same package                if (!isHidden(targetClazz, fields[i]))                    collection.addField(fields[i]);            }        }    }                /**     * isOverriddenOrHidden     *      * Find out if method is overridden or hidden in the hierarchy down towards the      * most derived targetClass.     *      * case private:      *    never inherited so therefore cannot be overridden or hidden return false;     *         * case public:     * case protected:     *     inherited if no class from derived up to class declaring the method declares a method of the same signature     *          * case package:     *      inherited if all classes in same package from derived to declaring class and no method of the same signature     *      * @param derivedClass the most derived class we are processing     * @param superclassMethod a method to check for being overridden or hidden     */    private static boolean isOverriddenOrHidden (Class derivedClass, Method superclassMethod)    {        if (Modifier.isPrivate(superclassMethod.getModifiers()))            return false; //private methods cannot be inherited therefore cannot be overridden                if (Modifier.isPublic(superclassMethod.getModifiers()) || Modifier.isProtected(superclassMethod.getModifiers()))        {            //check to see if any class from most derived up to the declaring class for the method contains a method of the same sig            boolean sameSig = false;            Class c = derivedClass;            while (c != superclassMethod.getDeclaringClass()&&!sameSig)            {                sameSig = IntrospectionUtil.containsSameMethodSignature(superclassMethod, c, false);                c = c.getSuperclass();            }            return sameSig;        }                //package protected        //check to see if any class from most derived up to declaring class contains method of same sig and that all        //intervening classes are of the same package (otherwise inheritance is blocked)        boolean sameSig = false;        Class c = derivedClass;        while (c != superclassMethod.getDeclaringClass() && !sameSig)        {            sameSig = IntrospectionUtil.containsSameMethodSignature(superclassMethod, c, true);            c = c.getSuperclass();        }        return sameSig;    }            /**     * isHidden determines if a field from a superclass is hidden by field     * of the same name in any of the derived classes.     *      * We check upwards from the most derived class to the class containing     * the field.     * @param derivedClass the most derived class     * @param superclassField     * @return     */    private static boolean isHidden (Class derivedClass, Field superclassField)    {        if (Modifier.isPrivate(superclassField.getModifiers()))            return false; //private methods are never inherited therefore never hidden                if (Modifier.isPublic(superclassField.getModifiers()) || Modifier.isProtected(superclassField.getModifiers()))        {            boolean hidden = false;            Class c = derivedClass;            while (!c.equals(superclassField.getDeclaringClass()) && !hidden)            {                hidden = IntrospectionUtil.containsSameFieldName(superclassField, c, false);                c=c.getSuperclass();            }            return hidden;        }                //Package scope        //Derived classes hide the field if they are in the same package and have same field name        boolean hidden = false;        Class c = derivedClass;        while (!c.equals(superclassField.getDeclaringClass()) && !hidden)        {            hidden = IntrospectionUtil.containsSameFieldName(superclassField, c, true);        }        return hidden;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -