Mercurial > hg > Members > sugi > MessagePack-java
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/org/msgpack/template/builder/JavassistTemplateBuilder.java.orig Sat Oct 18 15:06:15 2014 +0900 @@ -0,0 +1,174 @@ +// +// 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); + } +}