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 java.util.*; 016import java.util.concurrent.*; 017 018import org.apache.juneau.*; 019import org.apache.juneau.annotation.*; 020import org.apache.juneau.parser.*; 021 022/** 023 * Parses a MessagePack stream into a POJO model. 024 * 025 * <h5 class='topic'>Media types</h5> 026 * 027 * Handles <c>Content-Type</c> types: <bc>octal/msgpack</bc> 028 */ 029@ConfigurableContext 030public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvider, MsgPackCommon { 031 032 //------------------------------------------------------------------------------------------------------------------- 033 // Configurable properties 034 //------------------------------------------------------------------------------------------------------------------- 035 036 static final String PREFIX = "MsgPackParser"; 037 038 //------------------------------------------------------------------------------------------------------------------- 039 // Predefined instances 040 //------------------------------------------------------------------------------------------------------------------- 041 042 /** Default parser, all default settings.*/ 043 public static final MsgPackParser DEFAULT = new MsgPackParser(PropertyStore.DEFAULT); 044 045 /** Default parser, all default settings, string input encoded as spaced-hex.*/ 046 public static final MsgPackParser DEFAULT_SPACED_HEX = new SpacedHex(PropertyStore.DEFAULT); 047 048 /** Default parser, all default settings, string input encoded as BASE64.*/ 049 public static final MsgPackParser DEFAULT_BASE64 = new Base64(PropertyStore.DEFAULT); 050 051 //------------------------------------------------------------------------------------------------------------------- 052 // Predefined subclasses 053 //------------------------------------------------------------------------------------------------------------------- 054 055 /** Default parser, string input encoded as spaced-hex. */ 056 public static class SpacedHex extends MsgPackParser { 057 058 /** 059 * Constructor. 060 * 061 * @param ps The property store containing all the settings for this object. 062 */ 063 public SpacedHex(PropertyStore ps) { 064 super( 065 ps.builder().set(ISPARSER_binaryFormat, BinaryFormat.SPACED_HEX).build() 066 ); 067 } 068 } 069 070 /** Default parser, string input encoded as BASE64. */ 071 public static class Base64 extends MsgPackParser { 072 073 /** 074 * Constructor. 075 * 076 * @param ps The property store containing all the settings for this object. 077 */ 078 public Base64(PropertyStore ps) { 079 super( 080 ps.builder().set(ISPARSER_binaryFormat, BinaryFormat.BASE64).build() 081 ); 082 } 083 } 084 085 //------------------------------------------------------------------------------------------------------------------- 086 // Instance 087 //------------------------------------------------------------------------------------------------------------------- 088 089 private final Map<ClassMeta<?>,MsgPackClassMeta> msgPackClassMetas = new ConcurrentHashMap<>(); 090 private final Map<BeanPropertyMeta,MsgPackBeanPropertyMeta> msgPackBeanPropertyMetas = new ConcurrentHashMap<>(); 091 092 /** 093 * Constructor. 094 * 095 * @param ps The property store containing all the settings for this object. 096 */ 097 public MsgPackParser(PropertyStore ps) { 098 super(ps, "octal/msgpack"); 099 } 100 101 @Override /* Context */ 102 public MsgPackParserBuilder builder() { 103 return new MsgPackParserBuilder(getPropertyStore()); 104 } 105 106 /** 107 * Instantiates a new clean-slate {@link MsgPackParserBuilder} object. 108 * 109 * <p> 110 * This is equivalent to simply calling <code><jk>new</jk> MsgPackParserBuilder()</code>. 111 * 112 * <p> 113 * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies 114 * the settings of the object called on. 115 * 116 * @return A new {@link MsgPackParserBuilder} object. 117 */ 118 public static MsgPackParserBuilder create() { 119 return new MsgPackParserBuilder(); 120 } 121 122 @Override /* Parser */ 123 public MsgPackParserSession createSession() { 124 return createSession(createDefaultSessionArgs()); 125 } 126 127 @Override /* Parser */ 128 public MsgPackParserSession createSession(ParserSessionArgs args) { 129 return new MsgPackParserSession(this, args); 130 } 131 132 //----------------------------------------------------------------------------------------------------------------- 133 // Extended metadata 134 //----------------------------------------------------------------------------------------------------------------- 135 136 @Override /* MsgPackMetaProvider */ 137 public MsgPackClassMeta getMsgPackClassMeta(ClassMeta<?> cm) { 138 MsgPackClassMeta m = msgPackClassMetas.get(cm); 139 if (m == null) { 140 m = new MsgPackClassMeta(cm, this); 141 msgPackClassMetas.put(cm, m); 142 } 143 return m; 144 } 145 146 @Override /* MsgPackMetaProvider */ 147 public MsgPackBeanPropertyMeta getMsgPackBeanPropertyMeta(BeanPropertyMeta bpm) { 148 if (bpm == null) 149 return MsgPackBeanPropertyMeta.DEFAULT; 150 MsgPackBeanPropertyMeta m = msgPackBeanPropertyMetas.get(bpm); 151 if (m == null) { 152 m = new MsgPackBeanPropertyMeta(bpm.getDelegateFor(), this); 153 msgPackBeanPropertyMetas.put(bpm, m); 154 } 155 return m; 156 } 157 158 //----------------------------------------------------------------------------------------------------------------- 159 // Other methods 160 //----------------------------------------------------------------------------------------------------------------- 161 162 @Override /* Context */ 163 public ObjectMap toMap() { 164 return super.toMap() 165 .append("MsgPackParser", new DefaultFilteringObjectMap()); 166 } 167}