Skip to content

Instantly share code, notes, and snippets.

@tauty
Created June 19, 2015 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tauty/3c2d12e33b0ffa08db0b to your computer and use it in GitHub Desktop.
Save tauty/3c2d12e33b0ffa08db0b to your computer and use it in GitHub Desktop.
Build a template of wrapper
/*
* Copyright 2014 - 2015 tetsuo.ohta[at]gmail.com
*
* 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.github.tauty.study;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.reflect.Modifier.*;
/**
* Created by tetsuo.uchiumi on 6/6/15.
*/
public class WrapperBuilder {
public static void main(String[] args) {
new WrapperBuilder(Tako.class).build();
// new WrapperBuilder(Connection.class).build();
}
private final Class<?> clazz;
private final Set<String> importList = new TreeSet<>();
public WrapperBuilder(Class<?> clazz) {
this.clazz = clazz;
}
private void build() {
final PrintStream STDOUT = System.out;
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream printStream = new PrintStream(baos);
System.setOut(printStream);
final String origName = clazz.getSimpleName();
importList.add(clazz.getName());
// class definition
System.out.print("public class " + origName + "Wrapper ");
System.out.print(clazz.isInterface() ? "implements" : "extends");
System.out.println(" " + origName + " {");
// field to be wrapped
System.out.println("\tprivate final " + origName + " orig;");
// Constructor
System.out.println("\tpublic " + origName + "Wrapper (" + origName + " orig) {");
System.out.println("\t\tthis.orig = orig;");
System.out.println("\t}");
for (Method m : clazz.getDeclaredMethods()) {
int mod = m.getModifiers();
if (isStatic(mod)) continue;
if (isPublic(mod)) buildWrapper(m, mod);
else if (isAbstract(mod)) buildUnsupported(m, mod);
}
System.out.println("}");
for (String s : importList) {
STDOUT.println("import " + s + ";");
}
try {
printStream.flush();
baos.writeTo(STDOUT);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void buildWrapper(Method m, int mod) {
String args = buildSigneture(m, mod);
System.out.print(m.getGenericReturnType().toString().equals("void") ? "\t\t" : "\t\treturn ");
System.out.print("orig." + m.getName());
System.out.println("(" + args + ");");
System.out.println("\t}");
}
private void buildUnsupported(Method m, int mod) {
buildSigneture(m, mod);
System.out.println("\t\tthrow new UnsupportedOperationException(\"Not supported.\");");
System.out.println("\t}");
}
private String buildSigneture(Method m, int mod) {
// public? protected? default?
System.out.println("\t@Override");
System.out.print(isPublic(mod) ? "\tpublic " : isProtected(mod) ? "\tprotected " : "\t");
// return type and method name.
System.out.print(typeToString(m.getGenericReturnType()) + " " + m.getName());
// parameters
char argName = 'a';
System.out.print(" (");
String delim = "";
StringBuilder sb = new StringBuilder();
for (Type type : m.getGenericParameterTypes()) {
System.out.print(delim);
System.out.print(typeToString(type));
sb.append(delim).append(argName);
System.out.print(" " + argName++);
delim = ", ";
}
System.out.print(")");
// exceptions
delim = " throws ";
for (Type type : m.getGenericExceptionTypes()) {
System.out.print(delim);
System.out.print(typeToString(type));
delim = ", ";
}
System.out.println(" {");
return sb.toString();
}
private static Pattern PTN = Pattern.compile("(\\w+\\.)+(\\w+)");
private String typeToString(Type type) {
String s = type.toString();
s = avoidPrefix(s, "class ");
s = avoidPrefix(s, "interface ");
Matcher m = PTN.matcher(s);
while (m.find()) {
String fullName = m.group();
String simpleName = m.group(2);
s = s.replace(fullName, simpleName);
if (!fullName.startsWith("java.lang") && !fullName.startsWith("Ljava.lang")) {
importList.add(fullName);
}
m = PTN.matcher(s);
}
return s;
}
private String avoidPrefix(String text, String token) {
return !text.startsWith(token) ? text : text.substring(token.length());
}
}
abstract class Tako {
public static void ignoreStatic(String s) {
}
int ignoreNonPublic(String s) {
return 0;
}
public int method1(String s) {
return 1;
}
abstract int method2(String s, int i);
public List<String> method3(List<String> strs) throws RuntimeException {
return null;
}
public List<String> method4(List<String> strs) throws RuntimeException, IOException {
return null;
}
public List<String> method5(List<String> strs, List<Integer> ints, boolean b) throws RuntimeException, IOException {
return null;
}
public abstract List<String> method6(List<String> strs, List<Integer> ints, boolean b) throws SQLException, IOException;
public void method7(List<String> strs, List<Integer> ints, boolean b) throws SQLException, IOException {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment