0
|
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.reflect.Constructor;
|
|
21 import java.lang.reflect.InvocationTargetException;
|
|
22
|
|
23 import org.msgpack.*;
|
|
24 import org.msgpack.template.*;
|
|
25
|
|
26 import javassist.CannotCompileException;
|
|
27 import javassist.CtClass;
|
|
28 import javassist.CtConstructor;
|
|
29 import javassist.CtNewConstructor;
|
|
30 import javassist.NotFoundException;
|
|
31
|
|
32 @SuppressWarnings("rawtypes")
|
|
33 public class BeansBuildContext extends BuildContext<BeansFieldEntry> {
|
|
34 protected BeansFieldEntry[] entries;
|
|
35
|
|
36 protected Class<?> origClass;
|
|
37
|
|
38 protected String origName;
|
|
39
|
|
40 protected Template<?>[] templates;
|
|
41
|
|
42 public BeansBuildContext(JavassistTemplateBuilder director) {
|
|
43 super(director);
|
|
44 }
|
|
45
|
|
46 public Template buildTemplate(Class<?> targetClass,
|
|
47 BeansFieldEntry[] entries, Template[] templates) {
|
|
48 this.entries = entries;
|
|
49 this.templates = templates;
|
|
50 this.origClass = targetClass;
|
|
51 this.origName = origClass.getName();
|
|
52 return build(origName);
|
|
53 }
|
|
54
|
|
55 protected void setSuperClass() throws CannotCompileException, NotFoundException {
|
|
56 tmplCtClass.setSuperclass(director.getCtClass(
|
|
57 JavassistTemplateBuilder.JavassistTemplate.class.getName()));
|
|
58 }
|
|
59
|
|
60 protected void buildConstructor() throws CannotCompileException,
|
|
61 NotFoundException {
|
|
62 // Constructor(Class targetClass, Template[] templates)
|
|
63 CtConstructor newCtCons = CtNewConstructor.make(
|
|
64 new CtClass[] {
|
|
65 director.getCtClass(Class.class.getName()),
|
|
66 director.getCtClass(Template.class.getName() + "[]")
|
|
67 }, new CtClass[0], tmplCtClass);
|
|
68 tmplCtClass.addConstructor(newCtCons);
|
|
69 }
|
|
70
|
|
71 protected Template buildInstance(Class<?> c) throws NoSuchMethodException,
|
|
72 InstantiationException, IllegalAccessException, InvocationTargetException {
|
|
73 Constructor<?> cons = c.getConstructor(new Class[] { Class.class, Template[].class });
|
|
74 Object tmpl = cons.newInstance(new Object[] { origClass, templates });
|
|
75 return (Template) tmpl;
|
|
76 }
|
|
77
|
|
78 protected void buildMethodInit() {
|
|
79 }
|
|
80
|
|
81 @Override
|
|
82 protected String buildWriteMethodBody() {
|
|
83 resetStringBuilder();
|
|
84 buildString("{");
|
|
85
|
|
86 buildString("if($2 == null) {");
|
|
87 buildString(" if($3) {");
|
|
88 buildString(" throw new %s(\"Attempted to write null\");", MessageTypeException.class.getName());
|
|
89 buildString(" }");
|
|
90 buildString(" $1.writeNil();");
|
|
91 buildString(" return;");
|
|
92 buildString("}");
|
|
93
|
|
94 buildString("%s _$$_t = (%s)$2;", origName, origName);
|
|
95 buildString("$1.writeArrayBegin(%d);", entries.length);
|
|
96
|
|
97 for (int i = 0; i < entries.length; i++) {
|
|
98 BeansFieldEntry e = entries[i];
|
|
99 if (!e.isAvailable()) {
|
|
100 buildString("$1.writeNil();");
|
|
101 continue;
|
|
102 }
|
|
103 Class<?> type = e.getType();
|
|
104 if (type.isPrimitive()) {
|
|
105 buildString("$1.%s(_$$_t.%s());", primitiveWriteName(type), e.getGetterName());
|
|
106 } else {
|
|
107 buildString("if(_$$_t.%s() == null) {", e.getGetterName());
|
|
108 if (e.isNotNullable()) {
|
|
109 buildString("throw new %s();", MessageTypeException.class.getName());
|
|
110 } else {
|
|
111 buildString("$1.writeNil();");
|
|
112 }
|
|
113 buildString("} else {");
|
|
114 buildString(" this.templates[%d].write($1, _$$_t.%s());", i, e.getGetterName());
|
|
115 buildString("}");
|
|
116 }
|
|
117 }
|
|
118
|
|
119 buildString("$1.writeArrayEnd();");
|
|
120 buildString("}");
|
|
121 return getBuiltString();
|
|
122 }
|
|
123
|
|
124 @Override
|
|
125 protected String buildReadMethodBody() {
|
|
126 resetStringBuilder();
|
|
127 buildString("{ ");
|
|
128
|
|
129 buildString("if(!$3 && $1.trySkipNil()) {");
|
|
130 buildString(" return null;");
|
|
131 buildString("}");
|
|
132
|
|
133 buildString("%s _$$_t;", origName);
|
|
134 buildString("if($2 == null) {");
|
|
135 buildString(" _$$_t = new %s();", origName);
|
|
136 buildString("} else {");
|
|
137 buildString(" _$$_t = (%s)$2;", origName);
|
|
138 buildString("}");
|
|
139
|
|
140 buildString("$1.readArrayBegin();");
|
|
141
|
|
142 for (int i = 0; i < entries.length; i++) {
|
|
143 BeansFieldEntry e = entries[i];
|
|
144
|
|
145 if (!e.isAvailable()) {
|
|
146 buildString("$1.skip();"); // TODO #MN
|
|
147 continue;
|
|
148 }
|
|
149
|
|
150 if (e.isOptional()) {
|
|
151 buildString("if($1.trySkipNil()) {");
|
|
152 buildString("_$$_t.%s(null);", e.getSetterName());
|
|
153 buildString("} else {");
|
|
154 }
|
|
155
|
|
156 Class<?> type = e.getType();
|
|
157 if (type.isPrimitive()) {
|
|
158 buildString("_$$_t.%s( $1.%s() );", e.getSetterName(), primitiveReadName(type));
|
|
159 } else {
|
|
160 buildString(
|
|
161 "_$$_t.%s( (%s)this.templates[%d].read($1, _$$_t.%s()) );",
|
|
162 e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName());
|
|
163 }
|
|
164
|
|
165 if (e.isOptional()) {
|
|
166 buildString("}");
|
|
167 }
|
|
168 }
|
|
169
|
|
170 buildString("$1.readArrayEnd();");
|
|
171 buildString("return _$$_t;");
|
|
172
|
|
173 buildString("}");
|
|
174
|
|
175 return getBuiltString();
|
|
176 }
|
|
177
|
|
178 @Override
|
|
179 public void writeTemplate(Class<?> targetClass, BeansFieldEntry[] entries,
|
|
180 Template[] templates, String directoryName) {
|
|
181 throw new UnsupportedOperationException(targetClass.getName());
|
|
182 }
|
|
183
|
|
184 @Override
|
|
185 public Template loadTemplate(Class<?> targetClass,
|
|
186 BeansFieldEntry[] entries, Template[] templates) {
|
|
187 return null;
|
|
188 }
|
|
189 }
|