annotate src/main/java/org/msgpack/template/TemplateRegistry.java @ 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;
cb825acd883a first commit
sugi
parents:
diff changeset
19
cb825acd883a first commit
sugi
parents:
diff changeset
20 import java.util.Collection;
cb825acd883a first commit
sugi
parents:
diff changeset
21 import java.util.Collections;
cb825acd883a first commit
sugi
parents:
diff changeset
22 import java.util.Date;
cb825acd883a first commit
sugi
parents:
diff changeset
23 import java.util.List;
cb825acd883a first commit
sugi
parents:
diff changeset
24 import java.util.Map;
cb825acd883a first commit
sugi
parents:
diff changeset
25 import java.util.HashMap;
cb825acd883a first commit
sugi
parents:
diff changeset
26 import java.util.Set;
cb825acd883a first commit
sugi
parents:
diff changeset
27 import java.lang.reflect.GenericArrayType;
cb825acd883a first commit
sugi
parents:
diff changeset
28 import java.lang.reflect.ParameterizedType;
cb825acd883a first commit
sugi
parents:
diff changeset
29 import java.lang.reflect.Type;
cb825acd883a first commit
sugi
parents:
diff changeset
30 import java.lang.reflect.TypeVariable;
cb825acd883a first commit
sugi
parents:
diff changeset
31 import java.lang.reflect.WildcardType;
cb825acd883a first commit
sugi
parents:
diff changeset
32 import java.math.BigDecimal;
cb825acd883a first commit
sugi
parents:
diff changeset
33 import java.math.BigInteger;
cb825acd883a first commit
sugi
parents:
diff changeset
34 import java.nio.ByteBuffer;
cb825acd883a first commit
sugi
parents:
diff changeset
35
cb825acd883a first commit
sugi
parents:
diff changeset
36 import org.msgpack.MessagePackable;
cb825acd883a first commit
sugi
parents:
diff changeset
37 import org.msgpack.MessageTypeException;
cb825acd883a first commit
sugi
parents:
diff changeset
38 import org.msgpack.template.BigIntegerTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
39 import org.msgpack.template.BooleanTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
40 import org.msgpack.template.ByteArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
41 import org.msgpack.template.ByteTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
42 import org.msgpack.template.DoubleArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
43 import org.msgpack.template.DoubleTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
44 import org.msgpack.template.FieldList;
cb825acd883a first commit
sugi
parents:
diff changeset
45 import org.msgpack.template.FloatArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
46 import org.msgpack.template.FloatTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
47 import org.msgpack.template.GenericTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
48 import org.msgpack.template.IntegerArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
49 import org.msgpack.template.IntegerTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
50 import org.msgpack.template.LongArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
51 import org.msgpack.template.LongTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
52 import org.msgpack.template.ShortArrayTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
53 import org.msgpack.template.ShortTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
54 import org.msgpack.template.StringTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
55 import org.msgpack.template.Template;
cb825acd883a first commit
sugi
parents:
diff changeset
56 import org.msgpack.template.ValueTemplate;
cb825acd883a first commit
sugi
parents:
diff changeset
57 import org.msgpack.template.builder.ArrayTemplateBuilder;
cb825acd883a first commit
sugi
parents:
diff changeset
58 import org.msgpack.template.builder.TemplateBuilder;
cb825acd883a first commit
sugi
parents:
diff changeset
59 import org.msgpack.template.builder.TemplateBuilderChain;
cb825acd883a first commit
sugi
parents:
diff changeset
60 import org.msgpack.type.Value;
cb825acd883a first commit
sugi
parents:
diff changeset
61
cb825acd883a first commit
sugi
parents:
diff changeset
62 @SuppressWarnings({ "rawtypes", "unchecked" })
cb825acd883a first commit
sugi
parents:
diff changeset
63 public class TemplateRegistry {
cb825acd883a first commit
sugi
parents:
diff changeset
64
cb825acd883a first commit
sugi
parents:
diff changeset
65 private TemplateRegistry parent = null;
cb825acd883a first commit
sugi
parents:
diff changeset
66
cb825acd883a first commit
sugi
parents:
diff changeset
67 private TemplateBuilderChain chain;
cb825acd883a first commit
sugi
parents:
diff changeset
68
cb825acd883a first commit
sugi
parents:
diff changeset
69 Map<Type, Template<Type>> cache;
cb825acd883a first commit
sugi
parents:
diff changeset
70
cb825acd883a first commit
sugi
parents:
diff changeset
71 private Map<Type, GenericTemplate> genericCache;
cb825acd883a first commit
sugi
parents:
diff changeset
72
cb825acd883a first commit
sugi
parents:
diff changeset
73 /**
cb825acd883a first commit
sugi
parents:
diff changeset
74 * create <code>TemplateRegistry</code> object of root.
cb825acd883a first commit
sugi
parents:
diff changeset
75 */
cb825acd883a first commit
sugi
parents:
diff changeset
76 private TemplateRegistry() {
cb825acd883a first commit
sugi
parents:
diff changeset
77 parent = null;
cb825acd883a first commit
sugi
parents:
diff changeset
78 chain = createTemplateBuilderChain();
cb825acd883a first commit
sugi
parents:
diff changeset
79 genericCache = new HashMap<Type, GenericTemplate>();
cb825acd883a first commit
sugi
parents:
diff changeset
80 cache = new HashMap<Type, Template<Type>>();
cb825acd883a first commit
sugi
parents:
diff changeset
81 registerTemplates();
cb825acd883a first commit
sugi
parents:
diff changeset
82 cache = Collections.unmodifiableMap(cache);
cb825acd883a first commit
sugi
parents:
diff changeset
83 }
cb825acd883a first commit
sugi
parents:
diff changeset
84
cb825acd883a first commit
sugi
parents:
diff changeset
85 /**
cb825acd883a first commit
sugi
parents:
diff changeset
86 *
cb825acd883a first commit
sugi
parents:
diff changeset
87 * @param registry
cb825acd883a first commit
sugi
parents:
diff changeset
88 */
cb825acd883a first commit
sugi
parents:
diff changeset
89 public TemplateRegistry(TemplateRegistry registry) {
cb825acd883a first commit
sugi
parents:
diff changeset
90 if (registry != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
91 parent = registry;
cb825acd883a first commit
sugi
parents:
diff changeset
92 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
93 parent = new TemplateRegistry();
cb825acd883a first commit
sugi
parents:
diff changeset
94 }
cb825acd883a first commit
sugi
parents:
diff changeset
95 chain = createTemplateBuilderChain();
cb825acd883a first commit
sugi
parents:
diff changeset
96 cache = new HashMap<Type, Template<Type>>();
cb825acd883a first commit
sugi
parents:
diff changeset
97 genericCache = new HashMap<Type, GenericTemplate>();
cb825acd883a first commit
sugi
parents:
diff changeset
98 registerTemplatesWhichRefersRegistry();
cb825acd883a first commit
sugi
parents:
diff changeset
99 }
cb825acd883a first commit
sugi
parents:
diff changeset
100
cb825acd883a first commit
sugi
parents:
diff changeset
101 protected TemplateBuilderChain createTemplateBuilderChain() {
cb825acd883a first commit
sugi
parents:
diff changeset
102 return new TemplateBuilderChain(this);
cb825acd883a first commit
sugi
parents:
diff changeset
103 }
cb825acd883a first commit
sugi
parents:
diff changeset
104
cb825acd883a first commit
sugi
parents:
diff changeset
105 public void setClassLoader(final ClassLoader cl) {
cb825acd883a first commit
sugi
parents:
diff changeset
106 chain = new TemplateBuilderChain(this, cl);
cb825acd883a first commit
sugi
parents:
diff changeset
107 }
cb825acd883a first commit
sugi
parents:
diff changeset
108
cb825acd883a first commit
sugi
parents:
diff changeset
109 private void registerTemplates() {
cb825acd883a first commit
sugi
parents:
diff changeset
110 register(boolean.class, BooleanTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
111 register(Boolean.class, BooleanTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
112 register(byte.class, ByteTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
113 register(Byte.class, ByteTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
114 register(short.class, ShortTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
115 register(Short.class, ShortTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
116 register(int.class, IntegerTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
117 register(Integer.class, IntegerTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
118 register(long.class, LongTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
119 register(Long.class, LongTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
120 register(float.class, FloatTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
121 register(Float.class, FloatTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
122 register(double.class, DoubleTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
123 register(Double.class, DoubleTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
124 register(BigInteger.class, BigIntegerTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
125 register(char.class, CharacterTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
126 register(Character.class, CharacterTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
127 register(boolean[].class, BooleanArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
128 register(short[].class, ShortArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
129 register(int[].class, IntegerArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
130 register(long[].class, LongArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
131 register(float[].class, FloatArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
132 register(double[].class, DoubleArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
133 register(String.class, StringTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
134 register(byte[].class, ByteArrayTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
135 register(ByteBuffer.class, ByteBufferTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
136 register(Value.class, ValueTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
137 register(BigDecimal.class, BigDecimalTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
138 register(Date.class, DateTemplate.getInstance());
cb825acd883a first commit
sugi
parents:
diff changeset
139
cb825acd883a first commit
sugi
parents:
diff changeset
140 registerTemplatesWhichRefersRegistry();
cb825acd883a first commit
sugi
parents:
diff changeset
141
cb825acd883a first commit
sugi
parents:
diff changeset
142 }
cb825acd883a first commit
sugi
parents:
diff changeset
143
cb825acd883a first commit
sugi
parents:
diff changeset
144 protected void registerTemplatesWhichRefersRegistry() {
cb825acd883a first commit
sugi
parents:
diff changeset
145 AnyTemplate anyTemplate = new AnyTemplate(this);
cb825acd883a first commit
sugi
parents:
diff changeset
146
cb825acd883a first commit
sugi
parents:
diff changeset
147 register(List.class, new ListTemplate(anyTemplate));
cb825acd883a first commit
sugi
parents:
diff changeset
148 register(Set.class, new SetTemplate(anyTemplate));
cb825acd883a first commit
sugi
parents:
diff changeset
149 register(Collection.class, new CollectionTemplate(anyTemplate));
cb825acd883a first commit
sugi
parents:
diff changeset
150 register(Map.class, new MapTemplate(anyTemplate, anyTemplate));
cb825acd883a first commit
sugi
parents:
diff changeset
151 registerGeneric(List.class, new GenericCollectionTemplate(this, ListTemplate.class));
cb825acd883a first commit
sugi
parents:
diff changeset
152 registerGeneric(Set.class, new GenericCollectionTemplate(this, SetTemplate.class));
cb825acd883a first commit
sugi
parents:
diff changeset
153 registerGeneric(Collection.class, new GenericCollectionTemplate(this, CollectionTemplate.class));
cb825acd883a first commit
sugi
parents:
diff changeset
154 registerGeneric(Map.class, new GenericMapTemplate(this, MapTemplate.class));
cb825acd883a first commit
sugi
parents:
diff changeset
155 }
cb825acd883a first commit
sugi
parents:
diff changeset
156
cb825acd883a first commit
sugi
parents:
diff changeset
157 public void register(final Class<?> targetClass) {
cb825acd883a first commit
sugi
parents:
diff changeset
158 buildAndRegister(null, targetClass, false, null);
cb825acd883a first commit
sugi
parents:
diff changeset
159 }
cb825acd883a first commit
sugi
parents:
diff changeset
160
cb825acd883a first commit
sugi
parents:
diff changeset
161 public void register(final Class<?> targetClass, final FieldList flist) {
cb825acd883a first commit
sugi
parents:
diff changeset
162 if (flist == null) {
cb825acd883a first commit
sugi
parents:
diff changeset
163 throw new NullPointerException("FieldList object is null");
cb825acd883a first commit
sugi
parents:
diff changeset
164 }
cb825acd883a first commit
sugi
parents:
diff changeset
165
cb825acd883a first commit
sugi
parents:
diff changeset
166 buildAndRegister(null, targetClass, false, flist);
cb825acd883a first commit
sugi
parents:
diff changeset
167 }
cb825acd883a first commit
sugi
parents:
diff changeset
168
cb825acd883a first commit
sugi
parents:
diff changeset
169 public synchronized void register(final Type targetType, final Template tmpl) {
cb825acd883a first commit
sugi
parents:
diff changeset
170 if (tmpl == null) {
cb825acd883a first commit
sugi
parents:
diff changeset
171 throw new NullPointerException("Template object is null");
cb825acd883a first commit
sugi
parents:
diff changeset
172 }
cb825acd883a first commit
sugi
parents:
diff changeset
173
cb825acd883a first commit
sugi
parents:
diff changeset
174 if (targetType instanceof ParameterizedType) {
cb825acd883a first commit
sugi
parents:
diff changeset
175 cache.put(((ParameterizedType) targetType).getRawType(), tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
176 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
177 cache.put(targetType, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
178 }
cb825acd883a first commit
sugi
parents:
diff changeset
179 }
cb825acd883a first commit
sugi
parents:
diff changeset
180
cb825acd883a first commit
sugi
parents:
diff changeset
181 public synchronized void registerGeneric(final Type targetType, final GenericTemplate tmpl) {
cb825acd883a first commit
sugi
parents:
diff changeset
182 if (targetType instanceof ParameterizedType) {
cb825acd883a first commit
sugi
parents:
diff changeset
183 genericCache.put(((ParameterizedType) targetType).getRawType(),
cb825acd883a first commit
sugi
parents:
diff changeset
184 tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
185 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
186 genericCache.put(targetType, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
187 }
cb825acd883a first commit
sugi
parents:
diff changeset
188 }
cb825acd883a first commit
sugi
parents:
diff changeset
189
cb825acd883a first commit
sugi
parents:
diff changeset
190 public synchronized boolean unregister(final Type targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
191 Template<Type> tmpl = cache.remove(targetType);
cb825acd883a first commit
sugi
parents:
diff changeset
192 return tmpl != null;
cb825acd883a first commit
sugi
parents:
diff changeset
193 }
cb825acd883a first commit
sugi
parents:
diff changeset
194
cb825acd883a first commit
sugi
parents:
diff changeset
195 public synchronized void unregister() {
cb825acd883a first commit
sugi
parents:
diff changeset
196 cache.clear();
cb825acd883a first commit
sugi
parents:
diff changeset
197 }
cb825acd883a first commit
sugi
parents:
diff changeset
198
cb825acd883a first commit
sugi
parents:
diff changeset
199 public synchronized Template lookup(Type targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
200 Template tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
201
cb825acd883a first commit
sugi
parents:
diff changeset
202 if (targetType instanceof ParameterizedType) {
cb825acd883a first commit
sugi
parents:
diff changeset
203 // ParameterizedType is not a Class<?>
cb825acd883a first commit
sugi
parents:
diff changeset
204 ParameterizedType paramedType = (ParameterizedType) targetType;
cb825acd883a first commit
sugi
parents:
diff changeset
205 tmpl = lookupGenericType(paramedType);
cb825acd883a first commit
sugi
parents:
diff changeset
206 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
207 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
208 }
cb825acd883a first commit
sugi
parents:
diff changeset
209 targetType = paramedType.getRawType();
cb825acd883a first commit
sugi
parents:
diff changeset
210 }
cb825acd883a first commit
sugi
parents:
diff changeset
211
cb825acd883a first commit
sugi
parents:
diff changeset
212 tmpl = lookupGenericArrayType(targetType);
cb825acd883a first commit
sugi
parents:
diff changeset
213 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
214 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
215 }
cb825acd883a first commit
sugi
parents:
diff changeset
216
cb825acd883a first commit
sugi
parents:
diff changeset
217 tmpl = lookupCache(targetType);
cb825acd883a first commit
sugi
parents:
diff changeset
218 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
219 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
220 }
cb825acd883a first commit
sugi
parents:
diff changeset
221
cb825acd883a first commit
sugi
parents:
diff changeset
222 if (targetType instanceof WildcardType ||
cb825acd883a first commit
sugi
parents:
diff changeset
223 targetType instanceof TypeVariable) {
cb825acd883a first commit
sugi
parents:
diff changeset
224 // WildcardType is not a Class<?>
cb825acd883a first commit
sugi
parents:
diff changeset
225 tmpl = new AnyTemplate<Object>(this);
cb825acd883a first commit
sugi
parents:
diff changeset
226 register(targetType, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
227 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
228 }
cb825acd883a first commit
sugi
parents:
diff changeset
229
cb825acd883a first commit
sugi
parents:
diff changeset
230 Class<?> targetClass = (Class<?>) targetType;
cb825acd883a first commit
sugi
parents:
diff changeset
231
cb825acd883a first commit
sugi
parents:
diff changeset
232 // MessagePackable interface is implemented
cb825acd883a first commit
sugi
parents:
diff changeset
233 if (MessagePackable.class.isAssignableFrom(targetClass)) {
cb825acd883a first commit
sugi
parents:
diff changeset
234 // FIXME #MN
cb825acd883a first commit
sugi
parents:
diff changeset
235 // following processing should be merged into lookAfterBuilding
cb825acd883a first commit
sugi
parents:
diff changeset
236 // or lookupInterfaceTypes method in next version
cb825acd883a first commit
sugi
parents:
diff changeset
237 tmpl = new MessagePackableTemplate(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
238 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
239 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
240 }
cb825acd883a first commit
sugi
parents:
diff changeset
241
cb825acd883a first commit
sugi
parents:
diff changeset
242 if (targetClass.isInterface()) {
cb825acd883a first commit
sugi
parents:
diff changeset
243 // writing interfaces will succeed
cb825acd883a first commit
sugi
parents:
diff changeset
244 // reading into interfaces will fail
cb825acd883a first commit
sugi
parents:
diff changeset
245 tmpl = new AnyTemplate<Object>(this);
cb825acd883a first commit
sugi
parents:
diff changeset
246 register(targetType, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
247 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
248 }
cb825acd883a first commit
sugi
parents:
diff changeset
249
cb825acd883a first commit
sugi
parents:
diff changeset
250 // find matched template builder and build template
cb825acd883a first commit
sugi
parents:
diff changeset
251 tmpl = lookupAfterBuilding(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
252 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
253 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
254 }
cb825acd883a first commit
sugi
parents:
diff changeset
255
cb825acd883a first commit
sugi
parents:
diff changeset
256 // lookup template of interface type
cb825acd883a first commit
sugi
parents:
diff changeset
257 tmpl = lookupInterfaceTypes(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
258 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
259 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
260 }
cb825acd883a first commit
sugi
parents:
diff changeset
261
cb825acd883a first commit
sugi
parents:
diff changeset
262 // lookup template of superclass type
cb825acd883a first commit
sugi
parents:
diff changeset
263 tmpl = lookupSuperclasses(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
264 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
265 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
266 }
cb825acd883a first commit
sugi
parents:
diff changeset
267
cb825acd883a first commit
sugi
parents:
diff changeset
268 // lookup template of interface type of superclasss
cb825acd883a first commit
sugi
parents:
diff changeset
269 tmpl = lookupSuperclassInterfaceTypes(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
270 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
271 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
272 }
cb825acd883a first commit
sugi
parents:
diff changeset
273
cb825acd883a first commit
sugi
parents:
diff changeset
274 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
275 "Cannot find template for " + targetClass + " class. " +
cb825acd883a first commit
sugi
parents:
diff changeset
276 "Try to add @Message annotation to the class or call MessagePack.register(Type).");
cb825acd883a first commit
sugi
parents:
diff changeset
277 }
cb825acd883a first commit
sugi
parents:
diff changeset
278
cb825acd883a first commit
sugi
parents:
diff changeset
279 private Template<Type> lookupGenericType(ParameterizedType paramedType) {
cb825acd883a first commit
sugi
parents:
diff changeset
280 Template<Type> tmpl = lookupGenericTypeImpl(paramedType);
cb825acd883a first commit
sugi
parents:
diff changeset
281 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
282 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
283 }
cb825acd883a first commit
sugi
parents:
diff changeset
284
cb825acd883a first commit
sugi
parents:
diff changeset
285 try {
cb825acd883a first commit
sugi
parents:
diff changeset
286 tmpl = parent.lookupGenericTypeImpl(paramedType);
cb825acd883a first commit
sugi
parents:
diff changeset
287 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
288 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
289 }
cb825acd883a first commit
sugi
parents:
diff changeset
290 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
291 }
cb825acd883a first commit
sugi
parents:
diff changeset
292
cb825acd883a first commit
sugi
parents:
diff changeset
293 tmpl = lookupGenericInterfaceTypes(paramedType);
cb825acd883a first commit
sugi
parents:
diff changeset
294 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
295 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
296 }
cb825acd883a first commit
sugi
parents:
diff changeset
297
cb825acd883a first commit
sugi
parents:
diff changeset
298 tmpl = lookupGenericSuperclasses(paramedType);
cb825acd883a first commit
sugi
parents:
diff changeset
299 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
300 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
301 }
cb825acd883a first commit
sugi
parents:
diff changeset
302
cb825acd883a first commit
sugi
parents:
diff changeset
303 return null;
cb825acd883a first commit
sugi
parents:
diff changeset
304 }
cb825acd883a first commit
sugi
parents:
diff changeset
305
cb825acd883a first commit
sugi
parents:
diff changeset
306 private Template lookupGenericTypeImpl(ParameterizedType targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
307 Type rawType = targetType.getRawType();
cb825acd883a first commit
sugi
parents:
diff changeset
308 return lookupGenericTypeImpl0(targetType, rawType);
cb825acd883a first commit
sugi
parents:
diff changeset
309 }
cb825acd883a first commit
sugi
parents:
diff changeset
310
cb825acd883a first commit
sugi
parents:
diff changeset
311 private Template lookupGenericTypeImpl0(ParameterizedType targetType, Type rawType) {
cb825acd883a first commit
sugi
parents:
diff changeset
312 GenericTemplate gtmpl = genericCache.get(rawType);
cb825acd883a first commit
sugi
parents:
diff changeset
313 if (gtmpl == null) {
cb825acd883a first commit
sugi
parents:
diff changeset
314 return null;
cb825acd883a first commit
sugi
parents:
diff changeset
315 }
cb825acd883a first commit
sugi
parents:
diff changeset
316
cb825acd883a first commit
sugi
parents:
diff changeset
317 Type[] types = targetType.getActualTypeArguments();
cb825acd883a first commit
sugi
parents:
diff changeset
318 Template[] tmpls = new Template[types.length];
cb825acd883a first commit
sugi
parents:
diff changeset
319 for (int i = 0; i < types.length; ++i) {
cb825acd883a first commit
sugi
parents:
diff changeset
320 tmpls[i] = lookup(types[i]);
cb825acd883a first commit
sugi
parents:
diff changeset
321 }
cb825acd883a first commit
sugi
parents:
diff changeset
322
cb825acd883a first commit
sugi
parents:
diff changeset
323 return gtmpl.build(tmpls);
cb825acd883a first commit
sugi
parents:
diff changeset
324 }
cb825acd883a first commit
sugi
parents:
diff changeset
325
cb825acd883a first commit
sugi
parents:
diff changeset
326 private <T> Template<T> lookupGenericInterfaceTypes(ParameterizedType targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
327 Type rawType = targetType.getRawType();
cb825acd883a first commit
sugi
parents:
diff changeset
328 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
329
cb825acd883a first commit
sugi
parents:
diff changeset
330 try {
cb825acd883a first commit
sugi
parents:
diff changeset
331 Class<?>[] infTypes = ((Class) rawType).getInterfaces();
cb825acd883a first commit
sugi
parents:
diff changeset
332 for (Class<?> infType : infTypes) {
cb825acd883a first commit
sugi
parents:
diff changeset
333 tmpl = lookupGenericTypeImpl0(targetType, infType);
cb825acd883a first commit
sugi
parents:
diff changeset
334 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
335 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
336 }
cb825acd883a first commit
sugi
parents:
diff changeset
337 }
cb825acd883a first commit
sugi
parents:
diff changeset
338 } catch (ClassCastException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
339 }
cb825acd883a first commit
sugi
parents:
diff changeset
340
cb825acd883a first commit
sugi
parents:
diff changeset
341 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
342 }
cb825acd883a first commit
sugi
parents:
diff changeset
343
cb825acd883a first commit
sugi
parents:
diff changeset
344 private <T> Template<T> lookupGenericSuperclasses(ParameterizedType targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
345 Type rawType = targetType.getRawType();
cb825acd883a first commit
sugi
parents:
diff changeset
346 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
347
cb825acd883a first commit
sugi
parents:
diff changeset
348 try {
cb825acd883a first commit
sugi
parents:
diff changeset
349 Class<?> superClass = ((Class) rawType).getSuperclass();
cb825acd883a first commit
sugi
parents:
diff changeset
350 if (superClass == null) {
cb825acd883a first commit
sugi
parents:
diff changeset
351 return null;
cb825acd883a first commit
sugi
parents:
diff changeset
352 }
cb825acd883a first commit
sugi
parents:
diff changeset
353
cb825acd883a first commit
sugi
parents:
diff changeset
354 for (; superClass != Object.class; superClass = superClass.getSuperclass()) {
cb825acd883a first commit
sugi
parents:
diff changeset
355 tmpl = lookupGenericTypeImpl0(targetType, superClass);
cb825acd883a first commit
sugi
parents:
diff changeset
356 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
357 register(targetType, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
358 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
359 }
cb825acd883a first commit
sugi
parents:
diff changeset
360 }
cb825acd883a first commit
sugi
parents:
diff changeset
361 } catch (ClassCastException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
362 }
cb825acd883a first commit
sugi
parents:
diff changeset
363
cb825acd883a first commit
sugi
parents:
diff changeset
364 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
365 }
cb825acd883a first commit
sugi
parents:
diff changeset
366
cb825acd883a first commit
sugi
parents:
diff changeset
367 private Template<Type> lookupGenericArrayType(Type targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
368 // TODO GenericArrayType is not a Class<?> => buildArrayTemplate
cb825acd883a first commit
sugi
parents:
diff changeset
369 if (! (targetType instanceof GenericArrayType)) {
cb825acd883a first commit
sugi
parents:
diff changeset
370 return null;
cb825acd883a first commit
sugi
parents:
diff changeset
371 }
cb825acd883a first commit
sugi
parents:
diff changeset
372
cb825acd883a first commit
sugi
parents:
diff changeset
373 GenericArrayType genericArrayType = (GenericArrayType) targetType;
cb825acd883a first commit
sugi
parents:
diff changeset
374 Template<Type> tmpl = lookupGenericArrayTypeImpl(genericArrayType);
cb825acd883a first commit
sugi
parents:
diff changeset
375 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
376 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
377 }
cb825acd883a first commit
sugi
parents:
diff changeset
378
cb825acd883a first commit
sugi
parents:
diff changeset
379 try {
cb825acd883a first commit
sugi
parents:
diff changeset
380 tmpl = parent.lookupGenericArrayTypeImpl(genericArrayType);
cb825acd883a first commit
sugi
parents:
diff changeset
381 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
382 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
383 }
cb825acd883a first commit
sugi
parents:
diff changeset
384 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
385 }
cb825acd883a first commit
sugi
parents:
diff changeset
386
cb825acd883a first commit
sugi
parents:
diff changeset
387 return null;
cb825acd883a first commit
sugi
parents:
diff changeset
388 }
cb825acd883a first commit
sugi
parents:
diff changeset
389
cb825acd883a first commit
sugi
parents:
diff changeset
390 private Template lookupGenericArrayTypeImpl(GenericArrayType genericArrayType) {
cb825acd883a first commit
sugi
parents:
diff changeset
391 String genericArrayTypeName = "" + genericArrayType;
cb825acd883a first commit
sugi
parents:
diff changeset
392 int dim = genericArrayTypeName.split("\\[").length - 1;
cb825acd883a first commit
sugi
parents:
diff changeset
393 if (dim <= 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
394 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
395 String.format("fatal error: type=", genericArrayTypeName));
cb825acd883a first commit
sugi
parents:
diff changeset
396 } else if (dim > 1) {
cb825acd883a first commit
sugi
parents:
diff changeset
397 throw new UnsupportedOperationException(String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
398 "Not implemented template generation of %s", genericArrayTypeName));
cb825acd883a first commit
sugi
parents:
diff changeset
399 }
cb825acd883a first commit
sugi
parents:
diff changeset
400
cb825acd883a first commit
sugi
parents:
diff changeset
401 String genericCompTypeName = "" + genericArrayType.getGenericComponentType();
cb825acd883a first commit
sugi
parents:
diff changeset
402 boolean isPrimitiveType = isPrimitiveType(genericCompTypeName);
cb825acd883a first commit
sugi
parents:
diff changeset
403 StringBuffer sbuf = new StringBuffer();
cb825acd883a first commit
sugi
parents:
diff changeset
404 for (int i = 0; i < dim; i++) {
cb825acd883a first commit
sugi
parents:
diff changeset
405 sbuf.append('[');
cb825acd883a first commit
sugi
parents:
diff changeset
406 }
cb825acd883a first commit
sugi
parents:
diff changeset
407 if (!isPrimitiveType) {
cb825acd883a first commit
sugi
parents:
diff changeset
408 sbuf.append('L');
cb825acd883a first commit
sugi
parents:
diff changeset
409 sbuf.append(toJvmReferenceTypeName(genericCompTypeName));
cb825acd883a first commit
sugi
parents:
diff changeset
410 sbuf.append(';');
cb825acd883a first commit
sugi
parents:
diff changeset
411 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
412 sbuf.append(toJvmPrimitiveTypeName(genericCompTypeName));
cb825acd883a first commit
sugi
parents:
diff changeset
413 }
cb825acd883a first commit
sugi
parents:
diff changeset
414
cb825acd883a first commit
sugi
parents:
diff changeset
415 String jvmArrayClassName = sbuf.toString();
cb825acd883a first commit
sugi
parents:
diff changeset
416 Class jvmArrayClass = null;
cb825acd883a first commit
sugi
parents:
diff changeset
417 ClassLoader cl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
418 try {
cb825acd883a first commit
sugi
parents:
diff changeset
419 cl = Thread.currentThread().getContextClassLoader();
cb825acd883a first commit
sugi
parents:
diff changeset
420 if (cl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
421 jvmArrayClass = cl.loadClass(jvmArrayClassName);
cb825acd883a first commit
sugi
parents:
diff changeset
422 if (jvmArrayClass != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
423 return lookupAfterBuilding(jvmArrayClass);
cb825acd883a first commit
sugi
parents:
diff changeset
424 }
cb825acd883a first commit
sugi
parents:
diff changeset
425 }
cb825acd883a first commit
sugi
parents:
diff changeset
426 } catch (ClassNotFoundException e) {} // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
427
cb825acd883a first commit
sugi
parents:
diff changeset
428 try {
cb825acd883a first commit
sugi
parents:
diff changeset
429 cl = getClass().getClassLoader();
cb825acd883a first commit
sugi
parents:
diff changeset
430 if (cl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
431 jvmArrayClass = cl.loadClass(jvmArrayClassName);
cb825acd883a first commit
sugi
parents:
diff changeset
432 if (jvmArrayClass != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
433 return lookupAfterBuilding(jvmArrayClass);
cb825acd883a first commit
sugi
parents:
diff changeset
434 }
cb825acd883a first commit
sugi
parents:
diff changeset
435 }
cb825acd883a first commit
sugi
parents:
diff changeset
436 } catch (ClassNotFoundException e) {} // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
437
cb825acd883a first commit
sugi
parents:
diff changeset
438 try {
cb825acd883a first commit
sugi
parents:
diff changeset
439 jvmArrayClass = Class.forName(jvmArrayClassName);
cb825acd883a first commit
sugi
parents:
diff changeset
440 if (jvmArrayClass != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
441 return lookupAfterBuilding(jvmArrayClass);
cb825acd883a first commit
sugi
parents:
diff changeset
442 }
cb825acd883a first commit
sugi
parents:
diff changeset
443 } catch (ClassNotFoundException e) {} // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
444
cb825acd883a first commit
sugi
parents:
diff changeset
445 throw new MessageTypeException(String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
446 "cannot find template of %s", jvmArrayClassName));
cb825acd883a first commit
sugi
parents:
diff changeset
447 }
cb825acd883a first commit
sugi
parents:
diff changeset
448
cb825acd883a first commit
sugi
parents:
diff changeset
449 private Template<Type> lookupCache(Type targetType) {
cb825acd883a first commit
sugi
parents:
diff changeset
450 Template<Type> tmpl = cache.get(targetType);
cb825acd883a first commit
sugi
parents:
diff changeset
451 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
452 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
453 }
cb825acd883a first commit
sugi
parents:
diff changeset
454
cb825acd883a first commit
sugi
parents:
diff changeset
455 try {
cb825acd883a first commit
sugi
parents:
diff changeset
456 tmpl = parent.lookupCache(targetType);
cb825acd883a first commit
sugi
parents:
diff changeset
457 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
458 }
cb825acd883a first commit
sugi
parents:
diff changeset
459 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
460 }
cb825acd883a first commit
sugi
parents:
diff changeset
461
cb825acd883a first commit
sugi
parents:
diff changeset
462 private <T> Template<T> lookupAfterBuilding(Class<T> targetClass) {
cb825acd883a first commit
sugi
parents:
diff changeset
463 TemplateBuilder builder = chain.select(targetClass, true);
cb825acd883a first commit
sugi
parents:
diff changeset
464 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
465 if (builder != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
466 // TODO #MN for Android, we should modify here
cb825acd883a first commit
sugi
parents:
diff changeset
467 tmpl = chain.getForceBuilder().loadTemplate(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
468 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
469 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
470 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
471 }
cb825acd883a first commit
sugi
parents:
diff changeset
472 tmpl = buildAndRegister(builder, targetClass, true, null);
cb825acd883a first commit
sugi
parents:
diff changeset
473 }
cb825acd883a first commit
sugi
parents:
diff changeset
474 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
475 }
cb825acd883a first commit
sugi
parents:
diff changeset
476
cb825acd883a first commit
sugi
parents:
diff changeset
477 private <T> Template<T> lookupInterfaceTypes(Class<T> targetClass) {
cb825acd883a first commit
sugi
parents:
diff changeset
478 Class<?>[] infTypes = targetClass.getInterfaces();
cb825acd883a first commit
sugi
parents:
diff changeset
479 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
480 for (Class<?> infType : infTypes) {
cb825acd883a first commit
sugi
parents:
diff changeset
481 tmpl = (Template<T>) cache.get(infType);
cb825acd883a first commit
sugi
parents:
diff changeset
482 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
483 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
484 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
485 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
486 try {
cb825acd883a first commit
sugi
parents:
diff changeset
487 tmpl = (Template<T>) parent.lookupCache(infType);
cb825acd883a first commit
sugi
parents:
diff changeset
488 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
489 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
490 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
491 }
cb825acd883a first commit
sugi
parents:
diff changeset
492 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
493 }
cb825acd883a first commit
sugi
parents:
diff changeset
494 }
cb825acd883a first commit
sugi
parents:
diff changeset
495 }
cb825acd883a first commit
sugi
parents:
diff changeset
496 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
497 }
cb825acd883a first commit
sugi
parents:
diff changeset
498
cb825acd883a first commit
sugi
parents:
diff changeset
499 private <T> Template<T> lookupSuperclasses(Class<T> targetClass) {
cb825acd883a first commit
sugi
parents:
diff changeset
500 Class<?> superClass = targetClass.getSuperclass();
cb825acd883a first commit
sugi
parents:
diff changeset
501 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
502 if (superClass != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
503 for (; superClass != Object.class; superClass = superClass
cb825acd883a first commit
sugi
parents:
diff changeset
504 .getSuperclass()) {
cb825acd883a first commit
sugi
parents:
diff changeset
505 tmpl = (Template<T>) cache.get(superClass);
cb825acd883a first commit
sugi
parents:
diff changeset
506 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
507 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
508 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
509 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
510 try {
cb825acd883a first commit
sugi
parents:
diff changeset
511 tmpl = (Template<T>) parent.lookupCache(superClass);
cb825acd883a first commit
sugi
parents:
diff changeset
512 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
513 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
514 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
515 }
cb825acd883a first commit
sugi
parents:
diff changeset
516 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
517 }
cb825acd883a first commit
sugi
parents:
diff changeset
518 }
cb825acd883a first commit
sugi
parents:
diff changeset
519 }
cb825acd883a first commit
sugi
parents:
diff changeset
520 }
cb825acd883a first commit
sugi
parents:
diff changeset
521 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
522 }
cb825acd883a first commit
sugi
parents:
diff changeset
523
cb825acd883a first commit
sugi
parents:
diff changeset
524 private <T> Template<T> lookupSuperclassInterfaceTypes(Class<T> targetClass) {
cb825acd883a first commit
sugi
parents:
diff changeset
525 Class<?> superClass = targetClass.getSuperclass();
cb825acd883a first commit
sugi
parents:
diff changeset
526 Template<T> tmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
527 if (superClass != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
528 for (; superClass != Object.class; superClass = superClass.getSuperclass()) {
cb825acd883a first commit
sugi
parents:
diff changeset
529 tmpl = (Template<T>) lookupInterfaceTypes(superClass);
cb825acd883a first commit
sugi
parents:
diff changeset
530 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
531 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
532 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
533 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
534 try {
cb825acd883a first commit
sugi
parents:
diff changeset
535 tmpl = (Template<T>) parent.lookupCache(superClass);
cb825acd883a first commit
sugi
parents:
diff changeset
536 if (tmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
537 register(targetClass, tmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
538 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
539 }
cb825acd883a first commit
sugi
parents:
diff changeset
540 } catch (NullPointerException e) { // ignore
cb825acd883a first commit
sugi
parents:
diff changeset
541 }
cb825acd883a first commit
sugi
parents:
diff changeset
542 }
cb825acd883a first commit
sugi
parents:
diff changeset
543 }
cb825acd883a first commit
sugi
parents:
diff changeset
544 }
cb825acd883a first commit
sugi
parents:
diff changeset
545 return tmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
546 }
cb825acd883a first commit
sugi
parents:
diff changeset
547
cb825acd883a first commit
sugi
parents:
diff changeset
548 private synchronized Template buildAndRegister(TemplateBuilder builder,
cb825acd883a first commit
sugi
parents:
diff changeset
549 final Class targetClass, final boolean hasAnnotation,
cb825acd883a first commit
sugi
parents:
diff changeset
550 final FieldList flist) {
cb825acd883a first commit
sugi
parents:
diff changeset
551 Template newTmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
552 Template oldTmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
553 try {
cb825acd883a first commit
sugi
parents:
diff changeset
554 if (cache.containsKey(targetClass)) {
cb825acd883a first commit
sugi
parents:
diff changeset
555 oldTmpl = cache.get(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
556 }
cb825acd883a first commit
sugi
parents:
diff changeset
557 newTmpl = new TemplateReference(this, targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
558 cache.put(targetClass, newTmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
559 if (builder == null) {
cb825acd883a first commit
sugi
parents:
diff changeset
560 builder = chain.select(targetClass, hasAnnotation);
cb825acd883a first commit
sugi
parents:
diff changeset
561 }
cb825acd883a first commit
sugi
parents:
diff changeset
562 newTmpl = flist != null ?
cb825acd883a first commit
sugi
parents:
diff changeset
563 builder.buildTemplate(targetClass, flist) : builder.buildTemplate(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
564 return newTmpl;
cb825acd883a first commit
sugi
parents:
diff changeset
565 } catch (Exception e) {
cb825acd883a first commit
sugi
parents:
diff changeset
566 if (oldTmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
567 cache.put(targetClass, oldTmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
568 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
569 cache.remove(targetClass);
cb825acd883a first commit
sugi
parents:
diff changeset
570 }
cb825acd883a first commit
sugi
parents:
diff changeset
571 newTmpl = null;
cb825acd883a first commit
sugi
parents:
diff changeset
572 if (e instanceof MessageTypeException) {
cb825acd883a first commit
sugi
parents:
diff changeset
573 throw (MessageTypeException) e;
cb825acd883a first commit
sugi
parents:
diff changeset
574 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
575 throw new MessageTypeException(e);
cb825acd883a first commit
sugi
parents:
diff changeset
576 }
cb825acd883a first commit
sugi
parents:
diff changeset
577 } finally {
cb825acd883a first commit
sugi
parents:
diff changeset
578 if (newTmpl != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
579 cache.put(targetClass, newTmpl);
cb825acd883a first commit
sugi
parents:
diff changeset
580 }
cb825acd883a first commit
sugi
parents:
diff changeset
581 }
cb825acd883a first commit
sugi
parents:
diff changeset
582 }
cb825acd883a first commit
sugi
parents:
diff changeset
583
cb825acd883a first commit
sugi
parents:
diff changeset
584 private static boolean isPrimitiveType(String genericCompTypeName) {
cb825acd883a first commit
sugi
parents:
diff changeset
585 return (genericCompTypeName.equals("byte")
cb825acd883a first commit
sugi
parents:
diff changeset
586 || genericCompTypeName.equals("short")
cb825acd883a first commit
sugi
parents:
diff changeset
587 || genericCompTypeName.equals("int")
cb825acd883a first commit
sugi
parents:
diff changeset
588 || genericCompTypeName.equals("long")
cb825acd883a first commit
sugi
parents:
diff changeset
589 || genericCompTypeName.equals("float")
cb825acd883a first commit
sugi
parents:
diff changeset
590 || genericCompTypeName.equals("double")
cb825acd883a first commit
sugi
parents:
diff changeset
591 || genericCompTypeName.equals("boolean")
cb825acd883a first commit
sugi
parents:
diff changeset
592 || genericCompTypeName.equals("char"));
cb825acd883a first commit
sugi
parents:
diff changeset
593 }
cb825acd883a first commit
sugi
parents:
diff changeset
594
cb825acd883a first commit
sugi
parents:
diff changeset
595 private static String toJvmReferenceTypeName(String typeName) {
cb825acd883a first commit
sugi
parents:
diff changeset
596 // delete "class " from class name
cb825acd883a first commit
sugi
parents:
diff changeset
597 // e.g. "class Foo" to "Foo" by this method
cb825acd883a first commit
sugi
parents:
diff changeset
598 return typeName.substring(6);
cb825acd883a first commit
sugi
parents:
diff changeset
599 }
cb825acd883a first commit
sugi
parents:
diff changeset
600
cb825acd883a first commit
sugi
parents:
diff changeset
601 private static String toJvmPrimitiveTypeName(String typeName) {
cb825acd883a first commit
sugi
parents:
diff changeset
602 if (typeName.equals("byte")) {
cb825acd883a first commit
sugi
parents:
diff changeset
603 return "B";
cb825acd883a first commit
sugi
parents:
diff changeset
604 } else if (typeName.equals("short")) {
cb825acd883a first commit
sugi
parents:
diff changeset
605 return "S";
cb825acd883a first commit
sugi
parents:
diff changeset
606 } else if (typeName.equals("int")) {
cb825acd883a first commit
sugi
parents:
diff changeset
607 return "I";
cb825acd883a first commit
sugi
parents:
diff changeset
608 } else if (typeName.equals("long")) {
cb825acd883a first commit
sugi
parents:
diff changeset
609 return "J";
cb825acd883a first commit
sugi
parents:
diff changeset
610 } else if (typeName.equals("float")) {
cb825acd883a first commit
sugi
parents:
diff changeset
611 return "F";
cb825acd883a first commit
sugi
parents:
diff changeset
612 } else if (typeName.equals("double")) {
cb825acd883a first commit
sugi
parents:
diff changeset
613 return "D";
cb825acd883a first commit
sugi
parents:
diff changeset
614 } else if (typeName.equals("boolean")) {
cb825acd883a first commit
sugi
parents:
diff changeset
615 return "Z";
cb825acd883a first commit
sugi
parents:
diff changeset
616 } else if (typeName.equals("char")) {
cb825acd883a first commit
sugi
parents:
diff changeset
617 return "C";
cb825acd883a first commit
sugi
parents:
diff changeset
618 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
619 throw new MessageTypeException(String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
620 "fatal error: type=%s", typeName));
cb825acd883a first commit
sugi
parents:
diff changeset
621 }
cb825acd883a first commit
sugi
parents:
diff changeset
622 }
cb825acd883a first commit
sugi
parents:
diff changeset
623 }