comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:cb825acd883a
1 //
2 // MessagePack for Java
3 //
4 // Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 //
10 // http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
18 package org.msgpack.template.builder;
19
20 import java.lang.Thread;
21 import java.lang.reflect.Type;
22 import java.util.logging.Level;
23 import java.util.logging.Logger;
24
25 import javassist.ClassPool;
26 import javassist.CtClass;
27 import javassist.LoaderClassPath;
28 import javassist.NotFoundException;
29
30 import org.msgpack.template.FieldOption;
31 import org.msgpack.template.Template;
32 import org.msgpack.template.AbstractTemplate;
33 import org.msgpack.template.TemplateRegistry;
34
35 @SuppressWarnings({ "rawtypes", "unchecked" })
36 public class JavassistTemplateBuilder extends AbstractTemplateBuilder {
37
38 private static Logger LOG = Logger.getLogger(JavassistTemplateBuilder.class.getName());
39
40 public static abstract class JavassistTemplate<T> extends AbstractTemplate<T> {
41 public Class<T> targetClass;
42 public Template<?>[] templates;
43
44 public JavassistTemplate(Class<T> targetClass, Template<?>[] templates) {
45 this.targetClass = targetClass;
46 this.templates = templates;
47 }
48 }
49
50 protected ClassPool pool;
51
52 protected int seqId = 0;
53
54 public JavassistTemplateBuilder(TemplateRegistry registry) {
55 super(registry);
56 pool = new ClassPool();
57 boolean appended = false;
58 ClassLoader cl = null;
59 try {
60 cl = Thread.currentThread().getContextClassLoader();
61 if (cl != null) {
62 pool.appendClassPath(new LoaderClassPath(cl));
63 appended = true;
64 }
65 } catch (SecurityException e) {
66 LOG.fine("Cannot append a search path of context classloader");
67 e.printStackTrace();
68 }
69 try {
70 ClassLoader cl2 = getClass().getClassLoader();
71 if (cl2 != null && cl2 != cl) {
72 pool.appendClassPath(new LoaderClassPath(cl2));
73 appended = true;
74 }
75 } catch (SecurityException e) {
76 LOG.fine("Cannot append a search path of classloader");
77 e.printStackTrace();
78 }
79 if (!appended) {
80 pool.appendSystemPath();
81 }
82 }
83
84 @Override
85 public boolean matchType(Type targetType, boolean hasAnnotation) {
86 Class<?> targetClass = (Class<?>) targetType;
87 boolean matched = matchAtClassTemplateBuilder(targetClass, hasAnnotation);
88 if (matched && LOG.isLoggable(Level.FINE)) {
89 LOG.fine("matched type: " + targetClass.getName());
90 }
91 return matched;
92 }
93
94 public void addClassLoader(ClassLoader cl) {
95 pool.appendClassPath(new LoaderClassPath(cl));
96 }
97
98 protected CtClass makeCtClass(String className) {
99 return pool.makeClass(className);
100 }
101
102 protected CtClass getCtClass(String className) throws NotFoundException {
103 return pool.get(className);
104 }
105
106 protected int nextSeqId() {
107 return seqId++;
108 }
109
110 protected BuildContext createBuildContext() {
111 return new DefaultBuildContext(this);
112 }
113
114 @Override
115 public <T> Template<T> buildTemplate(Class<T> targetClass, FieldEntry[] entries) {
116 Template<?>[] tmpls = toTemplate(entries);
117 BuildContext bc = createBuildContext();
118 return bc.buildTemplate(targetClass, entries, tmpls);
119 }
120
121 private Template<?>[] toTemplate(FieldEntry[] from) {
122 Template<?>[] tmpls = new Template<?>[from.length];
123 for (int i = 0; i < from.length; ++i) {
124 FieldEntry e = from[i];
125 if (!e.isAvailable()) {
126 tmpls[i] = null;
127 } else {
128 Template<?> tmpl = registry.lookup(e.getGenericType());
129 tmpls[i] = tmpl;
130 }
131 }
132 return tmpls;
133 }
134
135 @Override
136 public void writeTemplate(Type targetType, String directoryName) {
137 Class<?> targetClass = (Class<?>) targetType;
138 checkClassValidation(targetClass);
139 FieldOption implicitOption = getFieldOption(targetClass);
140 FieldEntry[] entries = toFieldEntries(targetClass, implicitOption);
141 writeTemplate(targetClass, entries, directoryName);
142 }
143
144 private void writeTemplate(Class<?> targetClass, FieldEntry[] entries, String directoryName) {
145 Template[] tmpls = toTemplate(entries);
146 BuildContext bc = createBuildContext();
147 bc.writeTemplate(targetClass, entries, tmpls, directoryName);
148 }
149
150 @Override
151 public <T> Template<T> loadTemplate(Type targetType) {
152 // FIXME #MN must consider how to load "reference cycle class" in next
153 // version
154 Class<T> targetClass = (Class) targetType;
155 //checkClassValidation(targetClass);
156 try {
157 // check loadable
158 String tmplName = targetClass.getName() + "_$$_Template";
159 ClassLoader cl = targetClass.getClassLoader();
160 if (cl != null) {
161 cl.loadClass(tmplName);
162 } else {
163 return null;
164 }
165 } catch (ClassNotFoundException e) {
166 return null;
167 }
168 FieldOption implicitOption = getFieldOption(targetClass);
169 FieldEntry[] entries = toFieldEntries(targetClass, implicitOption);
170 Template<?>[] tmpls = toTemplate(entries);
171 BuildContext bc = createBuildContext();
172 return bc.loadTemplate(targetClass, entries, tmpls);
173 }
174 }