Coverage Report - org.apache.myfaces.config.annotation._ClassByteCodeAnnotationFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
_ClassByteCodeAnnotationFilter
0%
0/44
0%
0/21
23
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.config.annotation;
 20  
 
 21  
 import java.io.DataInput;
 22  
 import java.io.IOException;
 23  
 import java.util.Set;
 24  
 import java.util.logging.Level;
 25  
 import java.util.logging.Logger;
 26  
 
 27  
 /**
 28  
  * Scan .class files for annotation signature directly, without load them.
 29  
  * 
 30  
  * @since 2.0
 31  
  * @author Leonardo Uribe (latest modification by $Author$)
 32  
  * @version $Revision$ $Date$
 33  
  */
 34  0
 class _ClassByteCodeAnnotationFilter
 35  
 {
 36  
     
 37  0
     private static final Logger log = Logger.getLogger(_ClassByteCodeAnnotationFilter.class.getName());
 38  
     
 39  
     //Constants used to define type in cp_info structure
 40  
     private static final int CP_INFO_CLASS = 7;
 41  
     private static final int CP_INFO_FIELD_REF = 9;
 42  
     private static final int CP_INFO_METHOD_REF = 10;
 43  
     private static final int CP_INFO_INTERFACE_REF = 11;
 44  
     private static final int CP_INFO_STRING = 8;
 45  
     private static final int CP_INFO_INTEGER = 3;
 46  
     private static final int CP_INFO_FLOAT = 4;
 47  
     private static final int CP_INFO_LONG = 5;
 48  
     private static final int CP_INFO_DOUBLE = 6;
 49  
     private static final int CP_INFO_NAME_AND_TYPE = 12;
 50  
     private static final int CP_INFO_UTF8 = 1;
 51  
 
 52  
     private static final int CP_INFO_METHOD_HANDLE = 15;
 53  
     private static final int CP_INFO_METHOD_TYPE = 16;
 54  
     private static final int CP_INFO_INVOKE_DYNAMIC = 18;
 55  
 
 56  
 
 57  
     /**
 58  
      * Checks if the .class file referenced by the DataInput could 
 59  
      * contain the annotation names available in the set.
 60  
      * 
 61  
      * @param in
 62  
      * @param byteCodeAnnotationsNames
 63  
      * @return
 64  
      * @throws IOException
 65  
      */
 66  
     public boolean couldContainAnnotationsOnClassDef(DataInput in,
 67  
             Set<String> byteCodeAnnotationsNames)
 68  
         throws IOException
 69  
     {
 70  
         /* According to Java VM Spec, each .class file contains
 71  
          * a single class or interface definition. The structure
 72  
          * definition is shown below:
 73  
 
 74  
     ClassFile {
 75  
         u4 magic;
 76  
         u2 minor_version;
 77  
         u2 major_version;
 78  
         u2 constant_pool_count;
 79  
         cp_info constant_pool[constant_pool_count-1];
 80  
         u2 access_flags;
 81  
         u2 this_class;
 82  
         u2 super_class;
 83  
         u2 interfaces_count;
 84  
         u2 interfaces[interfaces_count];
 85  
         u2 fields_count;
 86  
         field_info fields[fields_count];
 87  
         u2 methods_count;
 88  
         method_info methods[methods_count];
 89  
         u2 attributes_count;
 90  
         attribute_info attributes[attributes_count];
 91  
     }
 92  
 
 93  
         * u1 = readUnsignedByte 
 94  
         * u2 = readUnsignedShort
 95  
         * u4 = readInt
 96  
         *   
 97  
         */
 98  0
         int magic = in.readInt(); //u4
 99  
         
 100  0
         if (magic != 0xCAFEBABE)
 101  
         {
 102  
             //the file is not recognized as a class file 
 103  0
             return false;
 104  
         }
 105  
         //u2 but since in java does not exists unsigned,
 106  
         //store on a bigger value
 107  0
         int minorVersion = in.readUnsignedShort();//u2
 108  0
         int majorVersion = in.readUnsignedShort();//u2
 109  
         
 110  0
         if (majorVersion < 49)
 111  
         {
 112  
             //Compiled with jdk 1.4, so does not have annotations
 113  0
             return false;
 114  
         }
 115  
         
 116  
         //constantsPoolCount is the number of entries + 1
 117  
         //The index goes from 1 to constantsPoolCount-1
 118  0
         int constantsPoolCount = in.readUnsignedShort();
 119  
         
 120  0
         for (int i = 1; i < constantsPoolCount; i++)
 121  
         {
 122  
             // Format:
 123  
             // cp_info {
 124  
             //     u1 tag;
 125  
             //     u1 info[];
 126  
             // }
 127  0
             int tag = in.readUnsignedByte();
 128  
             
 129  0
             switch (tag)
 130  
             {
 131  
                 case CP_INFO_UTF8:
 132  
                     //u2 length
 133  
                     //u1 bytes[length]
 134  
                     //Check if the string is a annotation reference
 135  
                     //name
 136  0
                     String name = in.readUTF();
 137  0
                     if (byteCodeAnnotationsNames.contains(name))
 138  
                     {
 139  0
                         return true;
 140  
                     }
 141  
                     break;
 142  
                 case CP_INFO_CLASS: //ignore
 143  
                     //u2 name_index
 144  0
                     in.readUnsignedShort();
 145  0
                     break;
 146  
                 case CP_INFO_FIELD_REF: //ignore
 147  
                 case CP_INFO_METHOD_REF: //ignore
 148  
                 case CP_INFO_INTERFACE_REF: //ignore
 149  
                     //u2 class_index
 150  
                     //u2 name_and_type_index
 151  0
                     in.readUnsignedShort();
 152  0
                     in.readUnsignedShort();
 153  0
                     break;
 154  
                 case CP_INFO_STRING: //ignore
 155  
                     //u2 string_index
 156  0
                     in.readUnsignedShort();
 157  0
                     break;
 158  
                 case CP_INFO_INTEGER: //ignore
 159  
                 case CP_INFO_FLOAT: //ignore
 160  
                     //u4 bytes
 161  0
                     in.readInt();
 162  0
                     break;
 163  
                 case CP_INFO_LONG: //ignore
 164  
                 case CP_INFO_DOUBLE: //ignore
 165  
                     //u4 high_bytes
 166  
                     //u4 low_bytes
 167  0
                     in.readInt();
 168  0
                     in.readInt();
 169  
                     // this tag takes two entries in the constants pool
 170  0
                     i++;
 171  0
                     break;
 172  
                 case CP_INFO_NAME_AND_TYPE: //ignore
 173  
                     //u2 name_index
 174  
                     //u2 descriptor_index
 175  0
                     in.readUnsignedShort();
 176  0
                     in.readUnsignedShort();
 177  0
                     break;
 178  
 
 179  
                 case CP_INFO_METHOD_HANDLE:     // Ignore
 180  
                     // u1 reference_kind
 181  
                     // u2 reference_index
 182  0
                     in.readUnsignedByte();
 183  0
                     in.readUnsignedShort();
 184  0
                     break;
 185  
 
 186  
                 case CP_INFO_METHOD_TYPE:       // Ignore
 187  
                     // u2 descriptor_index
 188  0
                     in.readUnsignedShort();
 189  0
                     break;
 190  
 
 191  
                 case CP_INFO_INVOKE_DYNAMIC:    // Ignore
 192  
                     // u2 bootstrap_method_attr_index;
 193  
                     // u2 name_and_type_index;
 194  0
                     in.readUnsignedShort();
 195  0
                     in.readUnsignedShort();
 196  0
                     break;
 197  
 
 198  
                 default:
 199  
                     // THIS SHOULD NOT HAPPEN! Log error info
 200  
                     // and break for loop, because from this point
 201  
                     // we are reading corrupt data.
 202  0
                     if (log.isLoggable(Level.WARNING))
 203  
                     {
 204  0
                         log.warning("Unknown tag in constants pool: " + tag);
 205  
                     }
 206  0
                     i = constantsPoolCount;
 207  
                     break;
 208  
             }
 209  
         }
 210  0
         return false;
 211  
     }
 212  
 }