diff --git a/java/src/main/java/org/msgpack/template/TemplateRegistry.java b/java/src/main/java/org/msgpack/template/TemplateRegistry.java index 4c4f87b6..5d869a06 100644 --- a/java/src/main/java/org/msgpack/template/TemplateRegistry.java +++ b/java/src/main/java/org/msgpack/template/TemplateRegistry.java @@ -29,7 +29,6 @@ import org.msgpack.Template; public class TemplateRegistry { private static Map map; private static Map genericMap; - private static BuilderSelectorRegistry builderSelectorRegistry; static { @@ -41,38 +40,43 @@ public class TemplateRegistry { public static void register(Class target) { TemplateBuilder builder = builderSelectorRegistry.select(target); - if(builder != null){ + if (builder != null) { register(target,builder.buildTemplate(target)); - }else{ + } else { register(target,builderSelectorRegistry.getForceBuilder().buildTemplate(target)); } } public static void register(Class target, FieldOption implicitOption) { TemplateBuilder builder = builderSelectorRegistry.select(target); - if(builder != null && builder instanceof CustomTemplateBuilder){ + if (builder != null && builder instanceof CustomTemplateBuilder) { register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, implicitOption)); - }else{ + } else { throw new TemplateBuildException("Cannot build template with filed option"); } } public static void register(Class target, FieldList flist) throws NoSuchFieldException { TemplateBuilder builder = builderSelectorRegistry.select(target); - if(builder != null && builder instanceof CustomTemplateBuilder){ + if (builder != null && builder instanceof CustomTemplateBuilder) { register(target, ((CustomTemplateBuilder)builder).buildTemplate(target, flist)); - }else{ + } else { throw new TemplateBuildException("Cannot build template with filed list"); } } public static synchronized void register(Type rawType, Template tmpl) { - if(rawType instanceof ParameterizedType) { + if (rawType instanceof ParameterizedType) { rawType = ((ParameterizedType)rawType).getRawType(); } map.put(rawType, tmpl); } + public static boolean unregister(Class target) { + Template tmpl = map.remove(target); + return tmpl != null; + } + public static synchronized void registerGeneric(Type rawType, GenericTemplate gtmpl) { if(rawType instanceof ParameterizedType) { rawType = ((ParameterizedType)rawType).getRawType(); @@ -81,22 +85,27 @@ public class TemplateRegistry { } public static synchronized Template lookup(Type targetType) { - return lookupImpl(targetType, false, true); + return lookupImpl(targetType, true, false, true); } public static synchronized Template lookup(Type targetType, boolean forceBuild) { - return lookupImpl(targetType, forceBuild, true); + return lookupImpl(targetType, true, forceBuild, true); + } + + public static synchronized Template lookup(Type targetType, boolean forceLoad, boolean forceBuild) { + return lookupImpl(targetType, forceLoad, forceBuild, true); } public static synchronized Template tryLookup(Type targetType) { - return lookupImpl(targetType, false, false); + return lookupImpl(targetType, true, false, false); } public static synchronized Template tryLookup(Type targetType, boolean forceBuild) { - return lookupImpl(targetType, forceBuild, false); + return lookupImpl(targetType, true, forceBuild, false); } - private static synchronized Template lookupImpl(Type targetType, boolean forceBuild, boolean fallbackDefault) { + private static synchronized Template lookupImpl(Type targetType, + boolean forceLoad, boolean forceBuild, boolean fallbackDefault) { Template tmpl; if(targetType instanceof ParameterizedType) { @@ -115,10 +124,13 @@ public class TemplateRegistry { // find match TemplateBuilder TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetType); - if(builder != null){ - tmpl = builder.loadTemplate(targetType); - if (tmpl != null) { - return tmpl; + if (builder != null) { + if (forceLoad) { + tmpl = builder.loadTemplate(targetType); + if (tmpl != null) { + register(targetType, tmpl); + return tmpl; + } } tmpl = builder.buildTemplate(targetType); diff --git a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java index af99e06c..d1d23f6c 100644 --- a/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java +++ b/java/src/main/java/org/msgpack/util/TemplatePrecompiler.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.Properties; import org.msgpack.template.builder.BuilderSelectorRegistry; +import org.msgpack.template.builder.JavassistTemplateBuilder; import org.msgpack.template.builder.TemplateBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,35 +30,39 @@ import org.slf4j.LoggerFactory; public class TemplatePrecompiler { private static final Logger LOG = LoggerFactory.getLogger(TemplatePrecompiler.class); - //private static final String SRC = "msgpack.template.srcdir"; + //public static final String SRC = "msgpack.template.srcdir"; - private static final String DIST = "msgpack.template.distdir"; + public static final String DIST = "msgpack.template.distdir"; - //private static final String DEFAULT_SRC = "."; + //public static final String DEFAULT_SRC = "."; - private static final String DEFAULT_DIST = "."; + public static final String DEFAULT_DIST = "."; + + private static TemplatePrecompiler INSTANCE = null; private TemplatePrecompiler() { } - public void saveTemplates(final String[] classFileNames) throws IOException { + public static void saveTemplates(final String[] classFileNames) throws IOException { throw new UnsupportedOperationException("Not supported yet.");// TODO } - public void saveTemplateClass(Class targetClass) throws IOException { + public static void saveTemplateClass(Class targetClass) throws IOException { + if (INSTANCE != null) { + INSTANCE = new TemplatePrecompiler(); + } LOG.info("Saving template of " + targetClass.getName() + "..."); Properties props = System.getProperties(); String distDirName = getDirName(props, DIST, DEFAULT_DIST); if (targetClass.isEnum()) { throw new UnsupportedOperationException("Enum not supported yet: " + targetClass.getName()); } else { - TemplateBuilder builder = BuilderSelectorRegistry.getInstance().select(targetClass); - builder.writeTemplate(targetClass, distDirName); + new JavassistTemplateBuilder().writeTemplate(targetClass, distDirName); } LOG.info("Saved .class file of template class of " + targetClass.getName()); } - private String getDirName(Properties props, String dirName, String defaultDirName) + private static String getDirName(Properties props, String dirName, String defaultDirName) throws IOException { String dName = props.getProperty(dirName, defaultDirName); File d = new File(dName); @@ -68,7 +73,6 @@ public class TemplatePrecompiler { } public static void main(final String[] args) throws Exception { - TemplatePrecompiler compiler = new TemplatePrecompiler();// TODO - compiler.saveTemplates(args); + TemplatePrecompiler.saveTemplates(args); } } diff --git a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java index 9ac94ef7..b938ab20 100644 --- a/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java +++ b/java/src/test/java/org/msgpack/template/TestTemplateBuilderPackUnpack.java @@ -1,7 +1,5 @@ package org.msgpack.template; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.nio.ByteBuffer; @@ -15,16 +13,13 @@ import org.junit.Test; import org.msgpack.MessagePack; import org.msgpack.MessagePackable; -import org.msgpack.MessagePacker; import org.msgpack.MessageTypeException; import org.msgpack.MessageUnpackable; import org.msgpack.Packer; -import org.msgpack.Template; import org.msgpack.Unpacker; import org.msgpack.annotation.MessagePackMessage; import org.msgpack.annotation.MessagePackOrdinalEnum; import org.msgpack.annotation.Optional; -import org.msgpack.template.TestTemplateBuilderPackConvert.SampleInterface; import org.msgpack.template.builder.BuilderSelectorRegistry; import org.msgpack.template.builder.TemplateBuilder; diff --git a/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java b/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java new file mode 100644 index 00000000..e99c5da1 --- /dev/null +++ b/java/src/test/java/org/msgpack/util/TestTemplatePrecompiler.java @@ -0,0 +1,110 @@ +package org.msgpack.util; + +import org.junit.Test; +import static org.junit.Assert.*; +import org.msgpack.MessagePack; +import org.msgpack.MessageTypeException; +import org.msgpack.template.TemplateRegistry; + +public class TestTemplatePrecompiler { + + @Test + public void testPrimitiveTypeFields00() throws Exception { + System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes"); + Class c = PrimitiveTypeFieldsClass.class; + TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class); + + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + src.f0 = (byte) 0; + src.f1 = 1; + src.f2 = 2; + src.f3 = 3; + src.f4 = 4; + src.f5 = 5; + src.f6 = false; + + try { + MessagePack.pack(src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + assertTrue(TemplateRegistry.unregister(c)); + } + try { + TemplateRegistry.lookup(c, true, true); + byte[] raw = MessagePack.pack(src); + PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + //assertEquals(src.f4, dst.f4); + //assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } finally { + TemplateRegistry.unregister(c); + } + } + + @Test + public void testPrimitiveTypeFields01() throws Exception { + System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes"); + Class c = PrimitiveTypeFieldsClass.class; + TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class); + + PrimitiveTypeFieldsClass src = new PrimitiveTypeFieldsClass(); + + try { + MessagePack.pack(src); + fail(); + } catch (Exception e) { + assertTrue(e instanceof MessageTypeException); + assertTrue(TemplateRegistry.unregister(c)); + } + try { + TemplateRegistry.lookup(c, true, true); + byte[] raw = MessagePack.pack(src); + PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src.f0, dst.f0); + assertEquals(src.f1, dst.f1); + assertEquals(src.f2, dst.f2); + assertEquals(src.f3, dst.f3); + //assertEquals(src.f4, dst.f4); + //assertEquals(src.f5, dst.f5); + assertEquals(src.f6, dst.f6); + } finally { + TemplateRegistry.unregister(c); + } + } + + @Test + public void testPrimitiveTypeFields02() throws Exception { + System.getProperties().setProperty(TemplatePrecompiler.DIST, "./target/test-classes"); + Class c = PrimitiveTypeFieldsClass.class; + TemplatePrecompiler.saveTemplateClass(PrimitiveTypeFieldsClass.class); + + PrimitiveTypeFieldsClass src = null; + MessagePack.pack(src); + try { + TemplateRegistry.lookup(c, true, true); + byte[] raw = MessagePack.pack(src); + PrimitiveTypeFieldsClass dst = MessagePack.unpack(raw, PrimitiveTypeFieldsClass.class); + assertEquals(src, dst); + } finally { + TemplateRegistry.unregister(c); + } + } + + public static class PrimitiveTypeFieldsClass { + public byte f0; + public short f1; + public int f2; + public long f3; + public float f4; + public double f5; + public boolean f6; + + public PrimitiveTypeFieldsClass() { + } + } +}