Mercurial > hg > Members > sugi > MessagePack-java
view src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java.orig @ 0:cb825acd883a
first commit
author | sugi |
---|---|
date | Sat, 18 Oct 2014 15:06:15 +0900 |
parents | |
children |
line wrap: on
line source
// // MessagePack for Java // // Copyright (C) 2009 - 2013 FURUHASHI Sadayuki // // 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 org.msgpack.template.builder; import java.lang.Thread; import java.lang.reflect.Type; import java.util.logging.Level; import java.util.logging.Logger; import javassist.ClassPool; import javassist.CtClass; import javassist.LoaderClassPath; import javassist.NotFoundException; import org.msgpack.template.FieldOption; import org.msgpack.template.Template; import org.msgpack.template.AbstractTemplate; import org.msgpack.template.TemplateRegistry; @SuppressWarnings({ "rawtypes", "unchecked" }) public class JavassistTemplateBuilder extends AbstractTemplateBuilder { private static Logger LOG = Logger.getLogger(JavassistTemplateBuilder.class.getName()); public static abstract class JavassistTemplate<T> extends AbstractTemplate<T> { public Class<T> targetClass; public Template<?>[] templates; public JavassistTemplate(Class<T> targetClass, Template<?>[] templates) { this.targetClass = targetClass; this.templates = templates; } } protected ClassPool pool; protected int seqId = 0; public JavassistTemplateBuilder(TemplateRegistry registry) { super(registry); pool = new ClassPool(); boolean appended = false; ClassLoader cl = null; try { cl = Thread.currentThread().getContextClassLoader(); if (cl != null) { pool.appendClassPath(new LoaderClassPath(cl)); appended = true; } } catch (SecurityException e) { LOG.fine("Cannot append a search path of context classloader"); e.printStackTrace(); } try { ClassLoader cl2 = getClass().getClassLoader(); if (cl2 != null && cl2 != cl) { pool.appendClassPath(new LoaderClassPath(cl2)); appended = true; } } catch (SecurityException e) { LOG.fine("Cannot append a search path of classloader"); e.printStackTrace(); } if (!appended) { pool.appendSystemPath(); } } @Override public boolean matchType(Type targetType, boolean hasAnnotation) { Class<?> targetClass = (Class<?>) targetType; boolean matched = matchAtClassTemplateBuilder(targetClass, hasAnnotation); if (matched && LOG.isLoggable(Level.FINE)) { LOG.fine("matched type: " + targetClass.getName()); } return matched; } public void addClassLoader(ClassLoader cl) { pool.appendClassPath(new LoaderClassPath(cl)); } protected CtClass makeCtClass(String className) { return pool.makeClass(className); } protected CtClass getCtClass(String className) throws NotFoundException { return pool.get(className); } protected int nextSeqId() { return seqId++; } protected BuildContext createBuildContext() { return new DefaultBuildContext(this); } @Override public <T> Template<T> buildTemplate(Class<T> targetClass, FieldEntry[] entries) { Template<?>[] tmpls = toTemplate(entries); BuildContext bc = createBuildContext(); return bc.buildTemplate(targetClass, entries, tmpls); } private Template<?>[] toTemplate(FieldEntry[] from) { Template<?>[] tmpls = new Template<?>[from.length]; for (int i = 0; i < from.length; ++i) { FieldEntry e = from[i]; if (!e.isAvailable()) { tmpls[i] = null; } else { Template<?> tmpl = registry.lookup(e.getGenericType()); tmpls[i] = tmpl; } } return tmpls; } @Override public void writeTemplate(Type targetType, String directoryName) { Class<?> targetClass = (Class<?>) targetType; checkClassValidation(targetClass); FieldOption implicitOption = getFieldOption(targetClass); FieldEntry[] entries = toFieldEntries(targetClass, implicitOption); writeTemplate(targetClass, entries, directoryName); } private void writeTemplate(Class<?> targetClass, FieldEntry[] entries, String directoryName) { Template[] tmpls = toTemplate(entries); BuildContext bc = createBuildContext(); bc.writeTemplate(targetClass, entries, tmpls, directoryName); } @Override public <T> Template<T> loadTemplate(Type targetType) { // FIXME #MN must consider how to load "reference cycle class" in next // version Class<T> targetClass = (Class) targetType; //checkClassValidation(targetClass); try { // check loadable String tmplName = targetClass.getName() + "_$$_Template"; ClassLoader cl = targetClass.getClassLoader(); if (cl != null) { cl.loadClass(tmplName); } else { return null; } } catch (ClassNotFoundException e) { return null; } FieldOption implicitOption = getFieldOption(targetClass); FieldEntry[] entries = toFieldEntries(targetClass, implicitOption); Template<?>[] tmpls = toTemplate(entries); BuildContext bc = createBuildContext(); return bc.loadTemplate(targetClass, entries, tmpls); } }