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