1717//
1818package org .msgpack .template ;
1919
20+ import java .util .ArrayList ;
2021import java .util .Collection ;
2122import java .util .List ;
2223import java .util .Map ;
@@ -62,6 +63,8 @@ public class TemplateRegistry {
6263
6364 private Map <Type , GenericTemplate > genericCache ;
6465
66+ private Map <Type , List <TemplateReference >> templateReferences ;
67+
6568 public TemplateRegistry () {
6669 this (null );
6770 }
@@ -70,6 +73,7 @@ public TemplateRegistry(TemplateRegistry registry) {
7073 parent = registry ;
7174 cache = new HashMap <Type , Template <Type >>();
7275 genericCache = new HashMap <Type , GenericTemplate >();
76+ templateReferences = new HashMap <Type , List <TemplateReference >>();
7377 if (parent == null ) {
7478 registerTemplates ();
7579 chain = new TemplateBuilderChain ();
@@ -79,6 +83,29 @@ public TemplateRegistry(TemplateRegistry registry) {
7983 }
8084 }
8185
86+ private boolean notBuilding (Type targetType ) {
87+ return !templateReferences .containsKey (targetType );
88+ }
89+
90+ private void startBuilding (Type targetType ) {
91+ List <TemplateReference > list = new ArrayList <TemplateReference >();
92+ templateReferences .put (targetType , list );
93+ }
94+
95+ private Template getTemplateReference (Type targetType ) {
96+ List <TemplateReference > list = templateReferences .get (targetType );
97+ TemplateReference tmpl = new TemplateReference ();
98+ list .add (tmpl );
99+ return tmpl ;
100+ }
101+
102+ private void finishBuilding (Type targetType , Template actualTemplate ) {
103+ List <TemplateReference > list = templateReferences .remove (targetType );
104+ for (TemplateReference tmpl : list ) {
105+ tmpl .setTemplate (actualTemplate );
106+ }
107+ }
108+
82109 private void registerTemplates () {
83110 register (boolean .class , BooleanTemplate .getInstance ());
84111 register (Boolean .class , BooleanTemplate .getInstance ());
@@ -123,7 +150,15 @@ public void register(final Class<?> targetClass, final FieldList flist) {
123150 if (flist == null ) {
124151 throw new NullPointerException ("FieldList object is null" );
125152 }
126- register (targetClass , chain .select (targetClass , false ).buildTemplate (targetClass , flist ));
153+ Template <?> tmpl ;
154+ if (notBuilding (targetClass )) {
155+ startBuilding (targetClass );
156+ tmpl = chain .select (targetClass , false ).buildTemplate (targetClass , flist );
157+ finishBuilding (targetClass , tmpl );
158+ } else {
159+ tmpl = getTemplateReference (targetClass );
160+ }
161+ register (targetClass , tmpl );
127162 }
128163
129164 public synchronized void register (final Type targetType , final Template tmpl ) {
@@ -173,6 +208,18 @@ public synchronized Template tryLookup(Type targetType, final boolean forceBuild
173208
174209 private synchronized Template lookupImpl (Type targetType , final boolean forceLoad , final boolean forceBuild ) {
175210 Template tmpl ;
211+ if (notBuilding (targetType )) {
212+ startBuilding (targetType );
213+ tmpl = lookupImpl0 (targetType , forceLoad , forceBuild );
214+ finishBuilding (targetType , tmpl );
215+ } else {
216+ tmpl = getTemplateReference (targetType );
217+ }
218+ return tmpl ;
219+ }
220+
221+ private synchronized Template lookupImpl0 (Type targetType , final boolean forceLoad , final boolean forceBuild ) {
222+ Template tmpl ;
176223
177224 if (targetType instanceof ParameterizedType ) {
178225 ParameterizedType pType = (ParameterizedType ) targetType ;
0 commit comments