Skip to content

Instantly share code, notes, and snippets.

@takumakei
Created November 25, 2011 07:25
Show Gist options
  • Save takumakei/1392991 to your computer and use it in GitHub Desktop.
Save takumakei/1392991 to your computer and use it in GitHub Desktop.
Create an instance of org.apache.thrift.TProcessor bound to the classes at run time
/* TProcessors.java
* Create an instance of org.apache.thrift.TProcessor bound to the classes at run time.
* TProcessor processor = TProcessors.newInstance(Class.forName(className), Class.forName(serviceName));
*
* Copyright (C) 2011 TAKUMAKei
*
* 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 com.blogspot.takumakei.gist;
import java.util.HashSet;
import org.apache.thrift.TProcessor;
/**
* Utility class for Apache Thrift.
*
* Create an instance of org.apache.thrift.TProcessor bound to the classes at run time.<p>
*
* You can easily create an instance of TProcessor like below.<p>
* <code>
* TProcessor processor = Processors.newInstance(Implementation.class);
* </code><p>
*
* The code above creates an equivalent processor instance like below.<p>
* <code>
* TProcessor processor = new GeneratedServiceClass.Processor<GeneratedServiceClass.Iface>(new Implementation());
* </code><p>
*
* You can also specify the GeneratedServiceClass.
* This feature is needed in case of that your implementation class implements multiple Iface.<p>
* <code>
* TProcessor processor = Processors.newInstance(Implementation.class, GeneratedServiceClass.class);
* </code><p>
*
* These features allows you to write the code below.<p>
* <code>
* TProcessor processor = TProcessors.newInstance(Class.forName(className), Class.forName(serviceName));
* </code><p>
*
* The real purpose of this class is to achieve the ability to write in this way.<p>
*/
public class TProcessors {
/**
* Create an instance of Processor, which wraps a new instance of targetClass.
*/
public static TProcessor newInstance(Class<?> targetClass) {
return newInstance(newTarget(targetClass));
}
/**
* Create an instance of Processor, which wraps the target object.
*/
public static TProcessor newInstance(Object target) {
HashSet<Class<?>> ifaces = findIfaces(target.getClass(), new HashSet<Class<?>>());
if (ifaces.isEmpty()) {
throw new IllegalArgumentException(
target.getClass().getName() + " must implement Iface");
}
return newProcessor(target, ifaces.iterator().next());
}
/**
* Create an instance of Processor, which wraps a new instance of targetClass.
* @param serviceClass the Iface class or the service class enclosing the Iface class.
*/
public static TProcessor newInstance(Class<?> targetClass, Class<?> serviceClass) {
return newInstance(newTarget(targetClass), serviceClass);
}
/**
* Create an instance of Processor, which wraps the target object.
* @param serviceClass the Iface class or the service class enclosing the Iface class.
*/
public static TProcessor newInstance(Object target, Class<?> serviceClass) {
if (null == serviceClass) {
return newInstance(target);
}
for (Class<?> iface : findIfaces(target.getClass(), new HashSet<Class<?>>())) {
if (iface.getEnclosingClass() == serviceClass || iface == serviceClass) {
return newProcessor(target, iface);
}
}
throw new IllegalArgumentException(
target.getClass().getName() + " does not implement " + serviceClass.getName());
}
protected static Object newTarget(Class<?> targetClass) {
try {
return targetClass.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(
"Failed to create an instance of " + targetClass.getName(), e);
}
}
protected static HashSet<Class<?>> findIfaces(Class<?> targetClass, HashSet<Class<?>> ifaces) {
if (targetClass == Object.class) {
return ifaces;
}
for (Class<?> iface : targetClass.getInterfaces()) {
if ("Iface".equals(iface.getSimpleName())) {
for (Class<?> processorClass : iface.getEnclosingClass().getClasses()) {
if (TProcessor.class.isAssignableFrom(processorClass)) {
ifaces.add(iface);
break;
}
}
}
}
return findIfaces(targetClass.getSuperclass(), ifaces);
}
protected static TProcessor newProcessor(Object target, Class<?> ifaceClass) {
try {
for (Class<?> processorClass : ifaceClass.getEnclosingClass().getClasses()) {
if (TProcessor.class.isAssignableFrom(processorClass)) {
return (TProcessor) processorClass.getConstructor(ifaceClass).newInstance(target);
}
}
} catch (Exception e) {
throw new IllegalArgumentException(
"Failed to create an instance of Processor for " + ifaceClass.getName(), e);
}
throw new IllegalArgumentException("No Processor class found for " + ifaceClass.getName());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment