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 19 package org.apache.bcel; 20 21 import java.io.File; 22 import java.io.IOException; 23 24 import org.apache.bcel.classfile.Attribute; 25 import org.apache.bcel.classfile.ConstantPool; 26 import org.apache.bcel.classfile.EnclosingMethod; 27 import org.apache.bcel.classfile.JavaClass; 28 import org.apache.bcel.util.SyntheticRepository; 29 import org.junit.Assert; 30 31 public class EnclosingMethodAttributeTestCase extends AbstractTestCase 32 { 33 /** 34 * Verify for an inner class declared inside the 'main' method that the 35 * enclosing method attribute is set correctly. 36 */ testCheckMethodLevelNamedInnerClass()37 public void testCheckMethodLevelNamedInnerClass() 38 throws ClassNotFoundException 39 { 40 final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AttributeTestClassEM01$1S"); 41 final ConstantPool pool = clazz.getConstantPool(); 42 final Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); 43 assertTrue("Expected 1 EnclosingMethod attribute but found " 44 + encMethodAttrs.length, encMethodAttrs.length == 1); 45 final EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; 46 final String enclosingClassName = em.getEnclosingClass().getBytes(pool); 47 final String enclosingMethodName = em.getEnclosingMethod().getName(pool); 48 assertTrue( 49 "Expected class name to be '"+PACKAGE_BASE_SIG+"/data/AttributeTestClassEM01' but was " 50 + enclosingClassName, enclosingClassName 51 .equals(PACKAGE_BASE_SIG+"/data/AttributeTestClassEM01")); 52 assertTrue("Expected method name to be 'main' but was " 53 + enclosingMethodName, enclosingMethodName.equals("main")); 54 } 55 56 /** 57 * Verify for an inner class declared at the type level that the 58 * EnclosingMethod attribute is set correctly (i.e. to a null value) 59 */ testCheckClassLevelNamedInnerClass()60 public void testCheckClassLevelNamedInnerClass() 61 throws ClassNotFoundException 62 { 63 final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AttributeTestClassEM02$1"); 64 final ConstantPool pool = clazz.getConstantPool(); 65 final Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); 66 assertTrue("Expected 1 EnclosingMethod attribute but found " 67 + encMethodAttrs.length, encMethodAttrs.length == 1); 68 final EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; 69 final String enclosingClassName = em.getEnclosingClass().getBytes(pool); 70 assertTrue( 71 "The class is not within a method, so method_index should be null, but it is " 72 + em.getEnclosingMethodIndex(), em 73 .getEnclosingMethodIndex() == 0); 74 assertTrue( 75 "Expected class name to be '"+PACKAGE_BASE_SIG+"/data/AttributeTestClassEM02' but was " 76 + enclosingClassName, enclosingClassName 77 .equals(PACKAGE_BASE_SIG+"/data/AttributeTestClassEM02")); 78 } 79 80 /** 81 * Check that we can save and load the attribute correctly. 82 */ testAttributeSerializtion()83 public void testAttributeSerializtion() throws ClassNotFoundException, 84 IOException 85 { 86 final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AttributeTestClassEM02$1"); 87 final ConstantPool pool = clazz.getConstantPool(); 88 final Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz); 89 assertTrue("Expected 1 EnclosingMethod attribute but found " 90 + encMethodAttrs.length, encMethodAttrs.length == 1); 91 // Write it out 92 final File tfile = createTestdataFile("AttributeTestClassEM02$1.class"); 93 clazz.dump(tfile); 94 // Read in the new version and check it is OK 95 final SyntheticRepository repos2 = createRepos("."); 96 final JavaClass clazz2 = repos2.loadClass("AttributeTestClassEM02$1"); 97 Assert.assertNotNull(clazz2); // Use the variable to avoid a warning 98 final EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0]; 99 final String enclosingClassName = em.getEnclosingClass().getBytes(pool); 100 assertTrue( 101 "The class is not within a method, so method_index should be null, but it is " 102 + em.getEnclosingMethodIndex(), em 103 .getEnclosingMethodIndex() == 0); 104 assertTrue( 105 "Expected class name to be '"+PACKAGE_BASE_SIG+"/data/AttributeTestClassEM02' but was " 106 + enclosingClassName, enclosingClassName 107 .equals(PACKAGE_BASE_SIG+"/data/AttributeTestClassEM02")); 108 tfile.deleteOnExit(); 109 } 110 } 111