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);
+    }
+}