Mercurial > hg > Members > sugi > MessagePack-java
diff src/main/java/org/msgpack/template/builder/BeansBuildContext.java @ 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/BeansBuildContext.java Sat Oct 18 15:06:15 2014 +0900 @@ -0,0 +1,189 @@ +// +// 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.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import org.msgpack.*; +import org.msgpack.template.*; + +import javassist.CannotCompileException; +import javassist.CtClass; +import javassist.CtConstructor; +import javassist.CtNewConstructor; +import javassist.NotFoundException; + +@SuppressWarnings("rawtypes") +public class BeansBuildContext extends BuildContext<BeansFieldEntry> { + protected BeansFieldEntry[] entries; + + protected Class<?> origClass; + + protected String origName; + + protected Template<?>[] templates; + + public BeansBuildContext(JavassistTemplateBuilder director) { + super(director); + } + + public Template buildTemplate(Class<?> targetClass, + BeansFieldEntry[] entries, Template[] templates) { + this.entries = entries; + this.templates = templates; + this.origClass = targetClass; + this.origName = origClass.getName(); + return build(origName); + } + + protected void setSuperClass() throws CannotCompileException, NotFoundException { + tmplCtClass.setSuperclass(director.getCtClass( + JavassistTemplateBuilder.JavassistTemplate.class.getName())); + } + + protected void buildConstructor() throws CannotCompileException, + NotFoundException { + // Constructor(Class targetClass, Template[] templates) + CtConstructor newCtCons = CtNewConstructor.make( + new CtClass[] { + director.getCtClass(Class.class.getName()), + director.getCtClass(Template.class.getName() + "[]") + }, new CtClass[0], tmplCtClass); + tmplCtClass.addConstructor(newCtCons); + } + + protected Template buildInstance(Class<?> c) throws NoSuchMethodException, + InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor<?> cons = c.getConstructor(new Class[] { Class.class, Template[].class }); + Object tmpl = cons.newInstance(new Object[] { origClass, templates }); + return (Template) tmpl; + } + + protected void buildMethodInit() { + } + + @Override + protected String buildWriteMethodBody() { + resetStringBuilder(); + buildString("{"); + + buildString("if($2 == null) {"); + buildString(" if($3) {"); + buildString(" throw new %s(\"Attempted to write null\");", MessageTypeException.class.getName()); + buildString(" }"); + buildString(" $1.writeNil();"); + buildString(" return;"); + buildString("}"); + + buildString("%s _$$_t = (%s)$2;", origName, origName); + buildString("$1.writeArrayBegin(%d);", entries.length); + + for (int i = 0; i < entries.length; i++) { + BeansFieldEntry e = entries[i]; + if (!e.isAvailable()) { + buildString("$1.writeNil();"); + continue; + } + Class<?> type = e.getType(); + if (type.isPrimitive()) { + buildString("$1.%s(_$$_t.%s());", primitiveWriteName(type), e.getGetterName()); + } else { + buildString("if(_$$_t.%s() == null) {", e.getGetterName()); + if (e.isNotNullable()) { + buildString("throw new %s();", MessageTypeException.class.getName()); + } else { + buildString("$1.writeNil();"); + } + buildString("} else {"); + buildString(" this.templates[%d].write($1, _$$_t.%s());", i, e.getGetterName()); + buildString("}"); + } + } + + buildString("$1.writeArrayEnd();"); + buildString("}"); + return getBuiltString(); + } + + @Override + protected String buildReadMethodBody() { + resetStringBuilder(); + buildString("{ "); + + buildString("if(!$3 && $1.trySkipNil()) {"); + buildString(" return null;"); + buildString("}"); + + buildString("%s _$$_t;", origName); + buildString("if($2 == null) {"); + buildString(" _$$_t = new %s();", origName); + buildString("} else {"); + buildString(" _$$_t = (%s)$2;", origName); + buildString("}"); + + buildString("$1.readArrayBegin();"); + + for (int i = 0; i < entries.length; i++) { + BeansFieldEntry e = entries[i]; + + if (!e.isAvailable()) { + buildString("$1.skip();"); // TODO #MN + continue; + } + + if (e.isOptional()) { + buildString("if($1.trySkipNil()) {"); + buildString("_$$_t.%s(null);", e.getSetterName()); + buildString("} else {"); + } + + Class<?> type = e.getType(); + if (type.isPrimitive()) { + buildString("_$$_t.%s( $1.%s() );", e.getSetterName(), primitiveReadName(type)); + } else { + buildString( + "_$$_t.%s( (%s)this.templates[%d].read($1, _$$_t.%s()) );", + e.getSetterName(), e.getJavaTypeName(), i, e.getGetterName()); + } + + if (e.isOptional()) { + buildString("}"); + } + } + + buildString("$1.readArrayEnd();"); + buildString("return _$$_t;"); + + buildString("}"); + + return getBuiltString(); + } + + @Override + public void writeTemplate(Class<?> targetClass, BeansFieldEntry[] entries, + Template[] templates, String directoryName) { + throw new UnsupportedOperationException(targetClass.getName()); + } + + @Override + public Template loadTemplate(Class<?> targetClass, + BeansFieldEntry[] entries, Template[] templates) { + return null; + } +}