001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.msgpack; 014 015import org.apache.juneau.*; 016import org.apache.juneau.annotation.*; 017import org.apache.juneau.serializer.*; 018 019/** 020 * Serializes POJO models to MessagePack. 021 * 022 * <h5 class='section'>Media types:</h5> 023 * 024 * Handles <c>Accept</c> types: <bc>octal/msgpack</bc> 025 * <p> 026 * Produces <c>Content-Type</c> types: <bc>octal/msgpack</bc> 027 */ 028@ConfigurableContext 029public class MsgPackSerializer extends OutputStreamSerializer { 030 031 //------------------------------------------------------------------------------------------------------------------- 032 // Configurable properties 033 //------------------------------------------------------------------------------------------------------------------- 034 035 static final String PREFIX = "MsgPackSerializer"; 036 037 /** 038 * Configuration property: Add <js>"_type"</js> properties when needed. 039 * 040 * <h5 class='section'>Property:</h5> 041 * <ul> 042 * <li><b>Name:</b> <js>"MsgPackSerializer.addBeanTypes.b"</js> 043 * <li><b>Data type:</b> <c>Boolean</c> 044 * <li><b>Default:</b> <jk>false</jk> 045 * <li><b>Session property:</b> <jk>false</jk> 046 * <li><b>Methods:</b> 047 * <ul> 048 * <li class='jm'>{@link MsgPackSerializerBuilder#addBeanTypes(boolean)} 049 * </ul> 050 * </ul> 051 * 052 * <h5 class='section'>Description:</h5> 053 * <p> 054 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 055 * through reflection. 056 * 057 * <p> 058 * When present, this value overrides the {@link #SERIALIZER_addBeanTypes} setting and is 059 * provided to customize the behavior of specific serializers in a {@link SerializerGroup}. 060 */ 061 public static final String MSGPACK_addBeanTypes = PREFIX + ".addBeanTypes.b"; 062 063 064 //------------------------------------------------------------------------------------------------------------------- 065 // Predefined instances 066 //------------------------------------------------------------------------------------------------------------------- 067 068 /** Default serializer, all default settings.*/ 069 public static final MsgPackSerializer DEFAULT = new MsgPackSerializer(PropertyStore.DEFAULT); 070 071 /** Default serializer, all default settings, spaced-hex string output.*/ 072 public static final MsgPackSerializer DEFAULT_SPACED_HEX = new SpacedHex(PropertyStore.DEFAULT); 073 074 /** Default serializer, all default settings, spaced-hex string output.*/ 075 public static final MsgPackSerializer DEFAULT_BASE64 = new Base64(PropertyStore.DEFAULT); 076 077 //------------------------------------------------------------------------------------------------------------------- 078 // Predefined subclasses 079 //------------------------------------------------------------------------------------------------------------------- 080 081 /** Default serializer, spaced-hex string output. */ 082 public static class SpacedHex extends MsgPackSerializer { 083 084 /** 085 * Constructor. 086 * 087 * @param ps The property store containing all the settings for this object. 088 */ 089 public SpacedHex(PropertyStore ps) { 090 super( 091 ps.builder().set(OSSERIALIZER_binaryFormat, BinaryFormat.SPACED_HEX).build() 092 ); 093 } 094 } 095 096 /** Default serializer, BASE64 string output. */ 097 public static class Base64 extends MsgPackSerializer { 098 099 /** 100 * Constructor. 101 * 102 * @param ps The property store containing all the settings for this object. 103 */ 104 public Base64(PropertyStore ps) { 105 super( 106 ps.builder().set(OSSERIALIZER_binaryFormat, BinaryFormat.BASE64).build() 107 ); 108 } 109 } 110 111 //------------------------------------------------------------------------------------------------------------------- 112 // Instance 113 //------------------------------------------------------------------------------------------------------------------- 114 115 private final boolean 116 addBeanTypes; 117 118 /** 119 * Constructor. 120 * 121 * @param ps The property store containing all the settings for this object. 122 */ 123 public MsgPackSerializer(PropertyStore ps) { 124 super(ps, "octal/msgpack", null); 125 this.addBeanTypes = getBooleanProperty(MSGPACK_addBeanTypes, getBooleanProperty(SERIALIZER_addBeanTypes, false)); 126 } 127 128 @Override /* Context */ 129 public MsgPackSerializerBuilder builder() { 130 return new MsgPackSerializerBuilder(getPropertyStore()); 131 } 132 133 /** 134 * Instantiates a new clean-slate {@link MsgPackSerializerBuilder} object. 135 * 136 * <p> 137 * This is equivalent to simply calling <code><jk>new</jk> MsgPackSerializerBuilder()</code>. 138 * 139 * <p> 140 * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies 141 * the settings of the object called on. 142 * 143 * @return A new {@link MsgPackSerializerBuilder} object. 144 */ 145 public static MsgPackSerializerBuilder create() { 146 return new MsgPackSerializerBuilder(); 147 } 148 149 @Override /* Context */ 150 public MsgPackSerializerSession createSession() { 151 return createSession(createDefaultSessionArgs()); 152 } 153 154 @Override /* Serializer */ 155 public MsgPackSerializerSession createSession(SerializerSessionArgs args) { 156 return new MsgPackSerializerSession(this, args); 157 } 158 159 //----------------------------------------------------------------------------------------------------------------- 160 // Properties 161 //----------------------------------------------------------------------------------------------------------------- 162 163 @Override 164 protected final boolean isAddBeanTypes() { 165 return addBeanTypes; 166 } 167 168 //----------------------------------------------------------------------------------------------------------------- 169 // Other methods 170 //----------------------------------------------------------------------------------------------------------------- 171 172 @Override /* Context */ 173 public ObjectMap toMap() { 174 return super.toMap() 175 .append("MsgPackSerializer", new DefaultFilteringObjectMap() 176 .append("addBeanTypes", addBeanTypes) 177 ); 178 } 179}