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.http; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.util.function.*; 018 019import org.apache.http.*; 020import org.apache.juneau.*; 021import org.apache.juneau.httppart.*; 022import org.apache.juneau.oapi.*; 023import org.apache.juneau.serializer.*; 024import org.apache.juneau.urlencoding.*; 025 026/** 027 * Subclass of {@link NameValuePair} for serializing POJOs as URL-encoded form post entries using the 028 * {@link UrlEncodingSerializer class}. 029 * 030 * <h5 class='section'>Example:</h5> 031 * <p class='bcode w800'> 032 * NameValuePairs params = <jk>new</jk> NameValuePairs() 033 * .append(<jk>new</jk> SerializedNameValuePair(<js>"myPojo"</js>, pojo, UrlEncodingSerializer.<jsf>DEFAULT_SIMPLE</jsf>)) 034 * .append(<jk>new</jk> BasicNameValuePair(<js>"someOtherParam"</js>, <js>"foobar"</js>)); 035 * request.setEntity(<jk>new</jk> UrlEncodedFormEntity(params)); 036 * </p> 037 */ 038public class SerializedHeader extends BasicHeader { 039 private static final long serialVersionUID = 1L; 040 041 private final Object value; 042 private HttpPartSerializerSession serializer; 043 private HttpPartSchema schema = HttpPartSchema.DEFAULT; 044 private boolean skipIfEmpty; 045 046 /** 047 * Instantiates a new instance of this object. 048 * 049 * @return A new instance of this object. 050 */ 051 public static SerializedHeader of(String name, Object value) { 052 return new SerializedHeader(name, value, null, null, false); 053 } 054 055 /** 056 * Instantiates a new instance of this object. 057 * 058 * @return A new instance of this object. 059 */ 060 public static SerializedHeader of(String name, Supplier<?> value) { 061 return new SerializedHeader(name, value, null, null, false); 062 } 063 064 /** 065 * Constructor. 066 * 067 * @param name The HTTP header name name. 068 * @param value The POJO to serialize to the parameter value. 069 * @param serializer 070 * The serializer to use for serializing the value to a string value. 071 * @param schema 072 * The schema object that defines the format of the output. 073 * <br>If <jk>null</jk>, defaults to the schema defined on the serializer. 074 * <br>If that's also <jk>null</jk>, defaults to {@link HttpPartSchema#DEFAULT}. 075 * <br>Only used if serializer is schema-aware (e.g. {@link OpenApiSerializer}). 076 * <br>Can also be a {@link Supplier}. 077 * @param skipIfEmpty If value is a blank string, the value should return as <jk>null</jk>. 078 */ 079 public SerializedHeader(String name, Object value, HttpPartSerializerSession serializer, HttpPartSchema schema, boolean skipIfEmpty) { 080 super(name, value); 081 this.value = value; 082 this.serializer = serializer; 083 this.schema = schema; 084 this.skipIfEmpty = skipIfEmpty; 085 } 086 087 /** 088 * Sets the serializer to use for serializing the value to a string value. 089 * 090 * @param value The new value for this property. 091 * @return This object (for method chaining). 092 */ 093 public SerializedHeader serializer(HttpPartSerializer value) { 094 if (value != null) 095 return serializer(value.createPartSession(null)); 096 return this; 097 } 098 099 /** 100 * Sets the serializer to use for serializing the value to a string value. 101 * 102 * @param value The new value for this property. 103 * @return This object (for method chaining). 104 */ 105 public SerializedHeader serializer(HttpPartSerializerSession value) { 106 return serializer(value, true); 107 } 108 109 /** 110 * Sets the serializer to use for serializing the value to a string value. 111 * 112 * @param value The new value for this property. 113 * @param overwrite If <jk>true</jk>, overwrites the existing value if the old value is <jk>null</jk>. 114 * @return This object (for method chaining). 115 */ 116 public SerializedHeader serializer(HttpPartSerializerSession value, boolean overwrite) { 117 if (overwrite || serializer == null) 118 this.serializer = value; 119 return this; 120 } 121 122 /** 123 * Sets the schema object that defines the format of the output. 124 * 125 * @param value The new value for this property. 126 * @return This object (for method chaining). 127 */ 128 public SerializedHeader schema(HttpPartSchema value) { 129 this.schema = value; 130 return this; 131 } 132 133 /** 134 * Don't serialize this header if the value is <jk>null</jk> or an empty string. 135 * 136 * @return This object (for method chaining). 137 */ 138 public SerializedHeader skipIfEmpty() { 139 return skipIfEmpty(true); 140 } 141 142 /** 143 * Don't serialize this header if the value is <jk>null</jk> or an empty string. 144 * 145 * @param value The new value of this setting. 146 * @return This object (for method chaining). 147 */ 148 public SerializedHeader skipIfEmpty(boolean value) { 149 this.skipIfEmpty = value; 150 return this; 151 } 152 153 @Override /* NameValuePair */ 154 public String getValue() { 155 try { 156 Object v = unwrap(value); 157 HttpPartSchema schema = this.schema == null ? HttpPartSchema.DEFAULT : this.schema; 158 String def = schema.getDefault(); 159 if (v == null) { 160 if (def == null && ! schema.isRequired()) 161 return null; 162 if (def == null && schema.isAllowEmptyValue()) 163 return null; 164 } 165 if (isEmpty(v) && skipIfEmpty && def == null) 166 return null; 167 return serializer == null ? stringify(v) : serializer.serialize(HttpPartType.HEADER, schema, v); 168 } catch (SchemaValidationException e) { 169 throw new BasicRuntimeException(e, "Validation error on request {0} parameter ''{1}''=''{2}''", HttpPartType.HEADER, getName(), value); 170 } catch (SerializeException e) { 171 throw new BasicRuntimeException(e, "Serialization error on request {0} parameter ''{1}''", HttpPartType.HEADER, getName()); 172 } 173 } 174 175 // <FluentSetters> 176 177 // </FluentSetters> 178}