/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.whip.instrument;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
/**
* @author Shuyang Zhou
*/
public class ContextAwareClassWriter extends ClassWriter {
public ContextAwareClassWriter(int flags) {
super(flags);
}
@Override
protected String getCommonSuperClass(String type1, String type2) {
if (type1.equals(type2)) {
return type1;
}
List<String> list1 = new ArrayList<>();
list1.add(type1);
List<String> list2 = new ArrayList<>();
list2.add(type2);
while (true) {
type1 = getSuperName(type1);
if (type1 != null) {
if (list2.contains(type1)) {
return type1;
}
list1.add(type1);
}
type2 = getSuperName(type2);
if (type2 != null) {
if (list1.contains(type2)) {
return type2;
}
list2.add(type2);
}
}
}
protected String getSuperName(String type) {
if (type == null) {
return null;
}
String resourceName = type.concat(".class");
ClassLoader classLoader =
ContextAwareClassWriter.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(resourceName);
if (inputStream == null) {
Thread currentThread = Thread.currentThread();
classLoader = currentThread.getContextClassLoader();
inputStream = classLoader.getResourceAsStream(resourceName);
}
if (inputStream == null) {
throw new RuntimeException(
"Unable to locate class definition for " + type);
}
try {
ClassReader classReader = new ClassReader(inputStream);
return classReader.getSuperName();
}
catch (IOException ioe) {
throw new RuntimeException(
"Unable to parse class definition for " + type, ioe);
}
finally {
try {
inputStream.close();
}
catch (IOException ioe) {
}
}
}
}