blob: 773a2a32442cf0000e2f88d86b42fee4faad9f5d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.felix.ipojo.manipulation;
import junit.framework.TestCase;
import org.apache.felix.ipojo.manipulator.util.Streams;
import org.objectweb.asm.*;
import org.osgi.framework.BundleContext;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ClassCheckerTestCase extends TestCase {
public void testIsAlreadyManipulatedWithNotManipulatedResource() throws Exception {
ClassChecker checker = check(resource("test/SimplePojo.class"));
assertFalse(checker.isAlreadyManipulated());
}
public void testIsAlreadyManipulatedWithManipulatedResource() throws Exception {
ClassChecker checker = check(manipulate(resource("test/SimplePojo.class")));
assertTrue(checker.isAlreadyManipulated());
}
public void testMetadataForAlreadyManipulatedClassAreCleaned() throws Exception {
ClassChecker checker = check(manipulate(resource("test/AnnotatedComponent.class")));
// Check implemented interfaces
List<String> interfaces = checker.getInterfaces();
assertTrue(interfaces.isEmpty());
// Check super class
assertNull(checker.getSuperClass());
// Check inner classes
Collection<String> inner = checker.getInnerClasses();
assertTrue(inner.isEmpty());
// Ensure fields are correctly filtered
Map<String, String> fields = checker.getFields();
assertEquals(1, fields.size());
assertEquals("java.lang.String", fields.get("prop"));
// Ensure methods are also correctly filtered
List<MethodDescriptor> descriptors = checker.getMethods();
assertEquals(2, descriptors.size());
// AnnotatedComponent(BundleContext)
MethodDescriptor constructor = searchMethod("$init", descriptors);
assertNotNull(constructor);
Type[] arguments = Type.getArgumentTypes(constructor.getDescriptor());
assertEquals(1, arguments.length);
assertEquals(Type.getType(BundleContext.class), arguments[0]);
// @FakeAnnotation
// AnnotatedComponent.annotatedMethod():Void
MethodDescriptor method = searchMethod("annotatedMethod", descriptors);
assertNotNull(method);
assertEquals("()V", method.getDescriptor()); // return void + no params
assertAnnotationIsAlone(method, "Ltest/FakeAnnotation;");
}
private void assertAnnotationIsAlone(MethodDescriptor method, String desc) {
List<ClassChecker.AnnotationDescriptor> annotations = method.getAnnotations();
assertEquals(1, annotations.size());
ClassChecker.AnnotationDescriptor annotationDescriptor = annotations.get(0);
MethodVisitor mv = mock(MethodVisitor.class);
when(mv.visitAnnotation(desc, true)).thenReturn(new AnnotationVisitor(Opcodes.ASM5) {});
annotationDescriptor.visitAnnotation(mv);
}
private MethodDescriptor searchMethod(String methodName, List<MethodDescriptor> descriptors) {
for (MethodDescriptor descriptor : descriptors) {
if (methodName.equals(descriptor.getName())) {
return descriptor;
}
}
return null;
}
private byte[] manipulate(byte[] input) throws Exception {
Manipulator manipulator = new Manipulator(this.getClass().getClassLoader());
manipulator.prepare(input);
return manipulator.manipulate(input);
}
private byte[] resource(String name) throws Exception {
return ManipulatorTest.getBytesFromFile(new File("target/test-classes/" + name));
}
private ClassChecker check(byte[] resource) throws Exception {
ClassChecker checker = new ClassChecker();
ByteArrayInputStream is = new ByteArrayInputStream(resource);
try {
ClassReader classReader = new ClassReader(is);
classReader.accept(checker, ClassReader.SKIP_FRAMES);
} finally {
Streams.close(is);
}
return checker;
}
}