001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.msgpack;
018
019import static org.apache.juneau.collections.JsonMap.*;
020import static org.apache.juneau.common.utils.Utils.*;
021
022import java.lang.annotation.*;
023import java.util.*;
024import java.util.concurrent.*;
025
026import org.apache.juneau.*;
027import org.apache.juneau.collections.*;
028import org.apache.juneau.internal.*;
029import org.apache.juneau.serializer.*;
030import org.apache.juneau.utils.*;
031
032/**
033 * Serializes POJO models to MessagePack.
034 *
035 * <h5 class='section'>Media types:</h5>
036 *
037 * Handles <c>Accept</c> types:  <bc>octal/msgpack</bc>
038 * <p>
039 * Produces <c>Content-Type</c> types: <bc>octal/msgpack</bc>
040 *
041 * <h5 class='section'>Notes:</h5><ul>
042 *    <li class='note'>This class is thread safe and reusable.
043 * </ul>
044 *
045 * <h5 class='section'>See Also:</h5><ul>
046 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MessagePackBasics">MessagePack Basics</a>
047
048 * </ul>
049 */
050public class MsgPackSerializer extends OutputStreamSerializer implements MsgPackMetaProvider {
051
052   //-------------------------------------------------------------------------------------------------------------------
053   // Static
054   //-------------------------------------------------------------------------------------------------------------------
055
056   /** Default serializer, all default settings.*/
057   public static final MsgPackSerializer DEFAULT = new MsgPackSerializer(create());
058
059   /** Default serializer, all default settings, spaced-hex string output.*/
060   public static final MsgPackSerializer DEFAULT_SPACED_HEX = new SpacedHex(create());
061
062   /** Default serializer, all default settings, spaced-hex string output.*/
063   public static final MsgPackSerializer DEFAULT_BASE64 = new Base64(create());
064
065   /**
066    * Creates a new builder for this object.
067    *
068    * @return A new builder.
069    */
070   public static Builder create() {
071      return new Builder();
072   }
073
074   //-------------------------------------------------------------------------------------------------------------------
075   // Static subclasses
076   //-------------------------------------------------------------------------------------------------------------------
077
078   /** Default serializer, spaced-hex string output. */
079   public static class SpacedHex extends MsgPackSerializer {
080
081      /**
082       * Constructor.
083       *
084       * @param builder The builder for this object.
085       */
086      public SpacedHex(Builder builder) {
087         super(builder.binaryFormat(BinaryFormat.SPACED_HEX));
088      }
089   }
090
091   /** Default serializer, BASE64 string output. */
092   public static class Base64 extends MsgPackSerializer {
093
094      /**
095       * Constructor.
096       *
097       * @param builder The builder for this object.
098       */
099      public Base64(Builder builder) {
100         super(builder.binaryFormat(BinaryFormat.BASE64));
101      }
102   }
103
104   //-------------------------------------------------------------------------------------------------------------------
105   // Builder
106   //-------------------------------------------------------------------------------------------------------------------
107
108   /**
109    * Builder class.
110    */
111   public static class Builder extends OutputStreamSerializer.Builder {
112
113      private static final Cache<HashKey,MsgPackSerializer> CACHE = Cache.of(HashKey.class, MsgPackSerializer.class).build();
114
115      boolean addBeanTypesMsgPack;
116
117      /**
118       * Constructor, default settings.
119       */
120      protected Builder() {
121         produces("octal/msgpack");
122         addBeanTypesMsgPack = env("MsgPackSerializer.addBeanTypesMsgPack", false);
123      }
124
125      /**
126       * Copy constructor.
127       *
128       * @param copyFrom The bean to copy from.
129       */
130      protected Builder(MsgPackSerializer copyFrom) {
131         super(copyFrom);
132      }
133
134      /**
135       * Copy constructor.
136       *
137       * @param copyFrom The builder to copy from.
138       */
139      protected Builder(Builder copyFrom) {
140         super(copyFrom);
141      }
142
143      @Override /* Context.Builder */
144      public Builder copy() {
145         return new Builder(this);
146      }
147
148      @Override /* Context.Builder */
149      public MsgPackSerializer build() {
150         return cache(CACHE).build(MsgPackSerializer.class);
151      }
152
153      @Override /* Context.Builder */
154      public HashKey hashKey() {
155         return HashKey.of(
156            super.hashKey(),
157            addBeanTypesMsgPack
158         );
159      }
160
161      //-----------------------------------------------------------------------------------------------------------------
162      // Properties
163      //-----------------------------------------------------------------------------------------------------------------
164
165      /**
166       * Add <js>"_type"</js> properties when needed.
167       *
168       * <p>
169       * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred
170       * through reflection.
171       *
172       * <p>
173       * When present, this value overrides the {@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()} setting and is
174       * provided to customize the behavior of specific serializers in a {@link SerializerSet}.
175       *
176       * @return This object.
177       */
178      public Builder addBeanTypesMsgPack() {
179         return addBeanTypesMsgPack(true);
180      }
181
182      /**
183       * Same as {@link #addBeanTypesMsgPack()} but allows you to explicitly specify the value.
184       *
185       * @param value The value for this setting.
186       * @return This object.
187       */
188      public Builder addBeanTypesMsgPack(boolean value) {
189         addBeanTypesMsgPack = value;
190         return this;
191      }
192      @Override /* Overridden from Builder */
193      public Builder annotations(Annotation...values) {
194         super.annotations(values);
195         return this;
196      }
197
198      @Override /* Overridden from Builder */
199      public Builder apply(AnnotationWorkList work) {
200         super.apply(work);
201         return this;
202      }
203
204      @Override /* Overridden from Builder */
205      public Builder applyAnnotations(Object...from) {
206         super.applyAnnotations(from);
207         return this;
208      }
209
210      @Override /* Overridden from Builder */
211      public Builder applyAnnotations(Class<?>...from) {
212         super.applyAnnotations(from);
213         return this;
214      }
215
216      @Override /* Overridden from Builder */
217      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
218         super.cache(value);
219         return this;
220      }
221
222      @Override /* Overridden from Builder */
223      public Builder debug() {
224         super.debug();
225         return this;
226      }
227
228      @Override /* Overridden from Builder */
229      public Builder debug(boolean value) {
230         super.debug(value);
231         return this;
232      }
233
234      @Override /* Overridden from Builder */
235      public Builder impl(Context value) {
236         super.impl(value);
237         return this;
238      }
239
240      @Override /* Overridden from Builder */
241      public Builder type(Class<? extends org.apache.juneau.Context> value) {
242         super.type(value);
243         return this;
244      }
245
246      @Override /* Overridden from Builder */
247      public Builder beanClassVisibility(Visibility value) {
248         super.beanClassVisibility(value);
249         return this;
250      }
251
252      @Override /* Overridden from Builder */
253      public Builder beanConstructorVisibility(Visibility value) {
254         super.beanConstructorVisibility(value);
255         return this;
256      }
257
258      @Override /* Overridden from Builder */
259      public Builder beanContext(BeanContext value) {
260         super.beanContext(value);
261         return this;
262      }
263
264      @Override /* Overridden from Builder */
265      public Builder beanContext(BeanContext.Builder value) {
266         super.beanContext(value);
267         return this;
268      }
269
270      @Override /* Overridden from Builder */
271      public Builder beanDictionary(java.lang.Class<?>...values) {
272         super.beanDictionary(values);
273         return this;
274      }
275
276      @Override /* Overridden from Builder */
277      public Builder beanFieldVisibility(Visibility value) {
278         super.beanFieldVisibility(value);
279         return this;
280      }
281
282      @Override /* Overridden from Builder */
283      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
284         super.beanInterceptor(on, value);
285         return this;
286      }
287
288      @Override /* Overridden from Builder */
289      public Builder beanMapPutReturnsOldValue() {
290         super.beanMapPutReturnsOldValue();
291         return this;
292      }
293
294      @Override /* Overridden from Builder */
295      public Builder beanMethodVisibility(Visibility value) {
296         super.beanMethodVisibility(value);
297         return this;
298      }
299
300      @Override /* Overridden from Builder */
301      public Builder beanProperties(Map<String,Object> values) {
302         super.beanProperties(values);
303         return this;
304      }
305
306      @Override /* Overridden from Builder */
307      public Builder beanProperties(Class<?> beanClass, String properties) {
308         super.beanProperties(beanClass, properties);
309         return this;
310      }
311
312      @Override /* Overridden from Builder */
313      public Builder beanProperties(String beanClassName, String properties) {
314         super.beanProperties(beanClassName, properties);
315         return this;
316      }
317
318      @Override /* Overridden from Builder */
319      public Builder beanPropertiesExcludes(Map<String,Object> values) {
320         super.beanPropertiesExcludes(values);
321         return this;
322      }
323
324      @Override /* Overridden from Builder */
325      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
326         super.beanPropertiesExcludes(beanClass, properties);
327         return this;
328      }
329
330      @Override /* Overridden from Builder */
331      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
332         super.beanPropertiesExcludes(beanClassName, properties);
333         return this;
334      }
335
336      @Override /* Overridden from Builder */
337      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
338         super.beanPropertiesReadOnly(values);
339         return this;
340      }
341
342      @Override /* Overridden from Builder */
343      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
344         super.beanPropertiesReadOnly(beanClass, properties);
345         return this;
346      }
347
348      @Override /* Overridden from Builder */
349      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
350         super.beanPropertiesReadOnly(beanClassName, properties);
351         return this;
352      }
353
354      @Override /* Overridden from Builder */
355      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
356         super.beanPropertiesWriteOnly(values);
357         return this;
358      }
359
360      @Override /* Overridden from Builder */
361      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
362         super.beanPropertiesWriteOnly(beanClass, properties);
363         return this;
364      }
365
366      @Override /* Overridden from Builder */
367      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
368         super.beanPropertiesWriteOnly(beanClassName, properties);
369         return this;
370      }
371
372      @Override /* Overridden from Builder */
373      public Builder beansRequireDefaultConstructor() {
374         super.beansRequireDefaultConstructor();
375         return this;
376      }
377
378      @Override /* Overridden from Builder */
379      public Builder beansRequireSerializable() {
380         super.beansRequireSerializable();
381         return this;
382      }
383
384      @Override /* Overridden from Builder */
385      public Builder beansRequireSettersForGetters() {
386         super.beansRequireSettersForGetters();
387         return this;
388      }
389
390      @Override /* Overridden from Builder */
391      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
392         super.dictionaryOn(on, values);
393         return this;
394      }
395
396      @Override /* Overridden from Builder */
397      public Builder disableBeansRequireSomeProperties() {
398         super.disableBeansRequireSomeProperties();
399         return this;
400      }
401
402      @Override /* Overridden from Builder */
403      public Builder disableIgnoreMissingSetters() {
404         super.disableIgnoreMissingSetters();
405         return this;
406      }
407
408      @Override /* Overridden from Builder */
409      public Builder disableIgnoreTransientFields() {
410         super.disableIgnoreTransientFields();
411         return this;
412      }
413
414      @Override /* Overridden from Builder */
415      public Builder disableIgnoreUnknownNullBeanProperties() {
416         super.disableIgnoreUnknownNullBeanProperties();
417         return this;
418      }
419
420      @Override /* Overridden from Builder */
421      public Builder disableInterfaceProxies() {
422         super.disableInterfaceProxies();
423         return this;
424      }
425
426      @Override /* Overridden from Builder */
427      public <T> Builder example(Class<T> pojoClass, T o) {
428         super.example(pojoClass, o);
429         return this;
430      }
431
432      @Override /* Overridden from Builder */
433      public <T> Builder example(Class<T> pojoClass, String json) {
434         super.example(pojoClass, json);
435         return this;
436      }
437
438      @Override /* Overridden from Builder */
439      public Builder findFluentSetters() {
440         super.findFluentSetters();
441         return this;
442      }
443
444      @Override /* Overridden from Builder */
445      public Builder findFluentSetters(Class<?> on) {
446         super.findFluentSetters(on);
447         return this;
448      }
449
450      @Override /* Overridden from Builder */
451      public Builder ignoreInvocationExceptionsOnGetters() {
452         super.ignoreInvocationExceptionsOnGetters();
453         return this;
454      }
455
456      @Override /* Overridden from Builder */
457      public Builder ignoreInvocationExceptionsOnSetters() {
458         super.ignoreInvocationExceptionsOnSetters();
459         return this;
460      }
461
462      @Override /* Overridden from Builder */
463      public Builder ignoreUnknownBeanProperties() {
464         super.ignoreUnknownBeanProperties();
465         return this;
466      }
467
468      @Override /* Overridden from Builder */
469      public Builder ignoreUnknownEnumValues() {
470         super.ignoreUnknownEnumValues();
471         return this;
472      }
473
474      @Override /* Overridden from Builder */
475      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
476         super.implClass(interfaceClass, implClass);
477         return this;
478      }
479
480      @Override /* Overridden from Builder */
481      public Builder implClasses(Map<Class<?>,Class<?>> values) {
482         super.implClasses(values);
483         return this;
484      }
485
486      @Override /* Overridden from Builder */
487      public Builder interfaceClass(Class<?> on, Class<?> value) {
488         super.interfaceClass(on, value);
489         return this;
490      }
491
492      @Override /* Overridden from Builder */
493      public Builder interfaces(java.lang.Class<?>...value) {
494         super.interfaces(value);
495         return this;
496      }
497
498      @Override /* Overridden from Builder */
499      public Builder locale(Locale value) {
500         super.locale(value);
501         return this;
502      }
503
504      @Override /* Overridden from Builder */
505      public Builder mediaType(MediaType value) {
506         super.mediaType(value);
507         return this;
508      }
509
510      @Override /* Overridden from Builder */
511      public Builder notBeanClasses(java.lang.Class<?>...values) {
512         super.notBeanClasses(values);
513         return this;
514      }
515
516      @Override /* Overridden from Builder */
517      public Builder notBeanPackages(String...values) {
518         super.notBeanPackages(values);
519         return this;
520      }
521
522      @Override /* Overridden from Builder */
523      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
524         super.propertyNamer(value);
525         return this;
526      }
527
528      @Override /* Overridden from Builder */
529      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
530         super.propertyNamer(on, value);
531         return this;
532      }
533
534      @Override /* Overridden from Builder */
535      public Builder sortProperties() {
536         super.sortProperties();
537         return this;
538      }
539
540      @Override /* Overridden from Builder */
541      public Builder sortProperties(java.lang.Class<?>...on) {
542         super.sortProperties(on);
543         return this;
544      }
545
546      @Override /* Overridden from Builder */
547      public Builder stopClass(Class<?> on, Class<?> value) {
548         super.stopClass(on, value);
549         return this;
550      }
551
552      @Override /* Overridden from Builder */
553      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
554         super.swap(normalClass, swappedClass, swapFunction);
555         return this;
556      }
557
558      @Override /* Overridden from Builder */
559      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
560         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
561         return this;
562      }
563
564      @Override /* Overridden from Builder */
565      public Builder swaps(Object...values) {
566         super.swaps(values);
567         return this;
568      }
569
570      @Override /* Overridden from Builder */
571      public Builder swaps(Class<?>...values) {
572         super.swaps(values);
573         return this;
574      }
575
576      @Override /* Overridden from Builder */
577      public Builder timeZone(TimeZone value) {
578         super.timeZone(value);
579         return this;
580      }
581
582      @Override /* Overridden from Builder */
583      public Builder typeName(Class<?> on, String value) {
584         super.typeName(on, value);
585         return this;
586      }
587
588      @Override /* Overridden from Builder */
589      public Builder typePropertyName(String value) {
590         super.typePropertyName(value);
591         return this;
592      }
593
594      @Override /* Overridden from Builder */
595      public Builder typePropertyName(Class<?> on, String value) {
596         super.typePropertyName(on, value);
597         return this;
598      }
599
600      @Override /* Overridden from Builder */
601      public Builder useEnumNames() {
602         super.useEnumNames();
603         return this;
604      }
605
606      @Override /* Overridden from Builder */
607      public Builder useJavaBeanIntrospector() {
608         super.useJavaBeanIntrospector();
609         return this;
610      }
611
612      @Override /* Overridden from Builder */
613      public Builder detectRecursions() {
614         super.detectRecursions();
615         return this;
616      }
617
618      @Override /* Overridden from Builder */
619      public Builder detectRecursions(boolean value) {
620         super.detectRecursions(value);
621         return this;
622      }
623
624      @Override /* Overridden from Builder */
625      public Builder ignoreRecursions() {
626         super.ignoreRecursions();
627         return this;
628      }
629
630      @Override /* Overridden from Builder */
631      public Builder ignoreRecursions(boolean value) {
632         super.ignoreRecursions(value);
633         return this;
634      }
635
636      @Override /* Overridden from Builder */
637      public Builder initialDepth(int value) {
638         super.initialDepth(value);
639         return this;
640      }
641
642      @Override /* Overridden from Builder */
643      public Builder maxDepth(int value) {
644         super.maxDepth(value);
645         return this;
646      }
647
648      @Override /* Overridden from Builder */
649      public Builder accept(String value) {
650         super.accept(value);
651         return this;
652      }
653
654      @Override /* Overridden from Builder */
655      public Builder addBeanTypes() {
656         super.addBeanTypes();
657         return this;
658      }
659
660      @Override /* Overridden from Builder */
661      public Builder addBeanTypes(boolean value) {
662         super.addBeanTypes(value);
663         return this;
664      }
665
666      @Override /* Overridden from Builder */
667      public Builder addRootType() {
668         super.addRootType();
669         return this;
670      }
671
672      @Override /* Overridden from Builder */
673      public Builder addRootType(boolean value) {
674         super.addRootType(value);
675         return this;
676      }
677
678      @Override /* Overridden from Builder */
679      public Builder keepNullProperties() {
680         super.keepNullProperties();
681         return this;
682      }
683
684      @Override /* Overridden from Builder */
685      public Builder keepNullProperties(boolean value) {
686         super.keepNullProperties(value);
687         return this;
688      }
689
690      @Override /* Overridden from Builder */
691      public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) {
692         super.listener(value);
693         return this;
694      }
695
696      @Override /* Overridden from Builder */
697      public Builder produces(String value) {
698         super.produces(value);
699         return this;
700      }
701
702      @Override /* Overridden from Builder */
703      public Builder sortCollections() {
704         super.sortCollections();
705         return this;
706      }
707
708      @Override /* Overridden from Builder */
709      public Builder sortCollections(boolean value) {
710         super.sortCollections(value);
711         return this;
712      }
713
714      @Override /* Overridden from Builder */
715      public Builder sortMaps() {
716         super.sortMaps();
717         return this;
718      }
719
720      @Override /* Overridden from Builder */
721      public Builder sortMaps(boolean value) {
722         super.sortMaps(value);
723         return this;
724      }
725
726      @Override /* Overridden from Builder */
727      public Builder trimEmptyCollections() {
728         super.trimEmptyCollections();
729         return this;
730      }
731
732      @Override /* Overridden from Builder */
733      public Builder trimEmptyCollections(boolean value) {
734         super.trimEmptyCollections(value);
735         return this;
736      }
737
738      @Override /* Overridden from Builder */
739      public Builder trimEmptyMaps() {
740         super.trimEmptyMaps();
741         return this;
742      }
743
744      @Override /* Overridden from Builder */
745      public Builder trimEmptyMaps(boolean value) {
746         super.trimEmptyMaps(value);
747         return this;
748      }
749
750      @Override /* Overridden from Builder */
751      public Builder trimStrings() {
752         super.trimStrings();
753         return this;
754      }
755
756      @Override /* Overridden from Builder */
757      public Builder trimStrings(boolean value) {
758         super.trimStrings(value);
759         return this;
760      }
761
762      @Override /* Overridden from Builder */
763      public Builder uriContext(UriContext value) {
764         super.uriContext(value);
765         return this;
766      }
767
768      @Override /* Overridden from Builder */
769      public Builder uriRelativity(UriRelativity value) {
770         super.uriRelativity(value);
771         return this;
772      }
773
774      @Override /* Overridden from Builder */
775      public Builder uriResolution(UriResolution value) {
776         super.uriResolution(value);
777         return this;
778      }
779
780      @Override /* Overridden from Builder */
781      public Builder binaryFormat(BinaryFormat value) {
782         super.binaryFormat(value);
783         return this;
784      }
785   }
786
787   //-------------------------------------------------------------------------------------------------------------------
788   // Instance
789   //-------------------------------------------------------------------------------------------------------------------
790
791   final boolean
792      addBeanTypesMsgPack;
793
794   private final Map<ClassMeta<?>,MsgPackClassMeta> msgPackClassMetas = new ConcurrentHashMap<>();
795   private final Map<BeanPropertyMeta,MsgPackBeanPropertyMeta> msgPackBeanPropertyMetas = new ConcurrentHashMap<>();
796
797   /**
798    * Constructor.
799    *
800    * @param builder The builder for this object.
801    */
802   public MsgPackSerializer(Builder builder) {
803      super(builder);
804      this.addBeanTypesMsgPack = builder.addBeanTypesMsgPack;
805   }
806
807   @Override /* Context */
808   public Builder copy() {
809      return new Builder(this);
810   }
811
812   @Override /* Context */
813   public MsgPackSerializerSession.Builder createSession() {
814      return MsgPackSerializerSession.create(this);
815   }
816
817   @Override /* Context */
818   public MsgPackSerializerSession getSession() {
819      return createSession().build();
820   }
821
822   //-----------------------------------------------------------------------------------------------------------------
823   // Extended metadata
824   //-----------------------------------------------------------------------------------------------------------------
825
826   @Override /* MsgPackMetaProvider */
827   public MsgPackClassMeta getMsgPackClassMeta(ClassMeta<?> cm) {
828      MsgPackClassMeta m = msgPackClassMetas.get(cm);
829      if (m == null) {
830         m = new MsgPackClassMeta(cm, this);
831         msgPackClassMetas.put(cm, m);
832      }
833      return m;
834   }
835
836   @Override /* MsgPackMetaProvider */
837   public MsgPackBeanPropertyMeta getMsgPackBeanPropertyMeta(BeanPropertyMeta bpm) {
838      if (bpm == null)
839         return MsgPackBeanPropertyMeta.DEFAULT;
840      MsgPackBeanPropertyMeta m = msgPackBeanPropertyMetas.get(bpm);
841      if (m == null) {
842         m = new MsgPackBeanPropertyMeta(bpm.getDelegateFor(), this);
843         msgPackBeanPropertyMetas.put(bpm, m);
844      }
845      return m;
846   }
847
848   //-----------------------------------------------------------------------------------------------------------------
849   // Properties
850   //-----------------------------------------------------------------------------------------------------------------
851
852   @Override
853   protected final boolean isAddBeanTypes() {
854      return addBeanTypesMsgPack || super.isAddBeanTypes();
855   }
856
857   //-----------------------------------------------------------------------------------------------------------------
858   // Other methods
859   //-----------------------------------------------------------------------------------------------------------------
860
861   @Override /* Context */
862   protected JsonMap properties() {
863      return filteredMap("addBeanTypesMsgPack", addBeanTypesMsgPack);
864   }
865}