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.rest.httppart; 018 019import static org.apache.juneau.common.utils.StringUtils.*; 020 021import java.util.*; 022import java.util.function.*; 023 024import org.apache.http.*; 025import org.apache.juneau.annotation.*; 026import org.apache.juneau.assertions.*; 027import org.apache.juneau.http.part.*; 028 029/** 030 * Implementation of a named object. 031 * 032 * <h5 class='section'>See Also:</h5><ul> 033 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HttpParts">HTTP Parts</a> 034 * </ul> 035 */ 036@BeanIgnore 037public class BasicNamedAttribute implements NamedAttribute { 038 039 //----------------------------------------------------------------------------------------------------------------- 040 // Static 041 //----------------------------------------------------------------------------------------------------------------- 042 043 /** 044 * Static creator. 045 * 046 * @param name The parameter name. 047 * @param value The parameter value. 048 * @return A new {@link BasicPart} object. 049 */ 050 public static BasicNamedAttribute of(String name, Object value) { 051 return new BasicNamedAttribute(name, value); 052 } 053 054 /** 055 * Creates a {@link BasicNamedAttribute} from a name/value pair string (e.g. <js>"Foo: bar"</js>) 056 * 057 * @param pair The pair string. 058 * @return A new {@link NameValuePair} object. 059 */ 060 public static BasicNamedAttribute ofPair(String pair) { 061 if (pair == null) 062 return null; 063 int i = pair.indexOf(':'); 064 if (i == -1) 065 i = pair.indexOf('='); 066 if (i == -1) 067 return of(pair, ""); 068 return of(pair.substring(0,i).trim(), pair.substring(i+1).trim()); 069 } 070 071 /** 072 * Static creator with delayed value. 073 * 074 * <p> 075 * Value is re-evaluated on each call to {@link #getValue()}. 076 * 077 * @param name The parameter name. 078 * @param value The parameter value supplier. 079 * @return A new {@link BasicPart} object. 080 */ 081 public static BasicNamedAttribute of(String name, Supplier<?> value) { 082 return new BasicNamedAttribute(name, value); 083 } 084 085 //----------------------------------------------------------------------------------------------------------------- 086 // Instance 087 //----------------------------------------------------------------------------------------------------------------- 088 089 private final String name; 090 private final Object value; 091 092 /** 093 * Constructor. 094 * 095 * @param name The parameter name. 096 * @param value The POJO to serialize to the parameter value. 097 */ 098 public BasicNamedAttribute(String name, Object value) { 099 this.name = name; 100 this.value = value; 101 } 102 103 /** 104 * Copy constructor. 105 * 106 * @param copyOf The object to copy. 107 */ 108 protected BasicNamedAttribute(BasicNamedAttribute copyOf) { 109 this.name = copyOf.name; 110 this.value = copyOf.value; 111 } 112 113 /** 114 * Provides an object for performing assertions against the name of this pair. 115 * 116 * @return An object for performing assertions against the name of this pair. 117 */ 118 public FluentStringAssertion<BasicNamedAttribute> assertName() { 119 return new FluentStringAssertion<>(getName(), this); 120 } 121 122 /** 123 * Provides an object for performing assertions against the value of this pair. 124 * 125 * @return An object for performing assertions against the value of this pair. 126 */ 127 public FluentObjectAssertion<Object,BasicNamedAttribute> assertValue() { 128 return new FluentObjectAssertion<>(getValue(), this); 129 } 130 131 @Override /* NameValuePair */ 132 public String getName() { 133 return name; 134 } 135 136 @Override /* NameValuePair */ 137 public Object getValue() { 138 return unwrap(value); 139 } 140 141 /** 142 * Returns <jk>true</jk> if the value exists. 143 * 144 * <p> 145 * This is a shortcut for calling <c>asString().isPresent()</c>. 146 * 147 * @return <jk>true</jk> if the value exists. 148 */ 149 public boolean isPresent() { 150 return getValue() != null; 151 } 152 153 /** 154 * If a value is present, returns the value, otherwise throws {@link NoSuchElementException}. 155 * 156 * <p> 157 * This is a shortcut for calling <c>asString().get()</c>. 158 * 159 * @return The value if present. 160 */ 161 public Object get() { 162 Object o = getValue(); 163 if (o == null) 164 throw new NoSuchElementException(); 165 return o; 166 } 167 168 /** 169 * If a value is present, returns the value, otherwise returns other. 170 * 171 * <p> 172 * This is a shortcut for calling <c>asString().orElse(<jv>other</jv>)</c>. 173 * 174 * @param other The other value. 175 * @return The value if present or the other value if not. 176 */ 177 public Object orElse(Object other) { 178 Object o = getValue(); 179 return o != null ? o : other; 180 } 181 182 @Override /* Object */ 183 public String toString() { 184 return urlEncode(getName()) + "=" + getValue(); 185 } 186 187 private Object unwrap(Object o) { 188 while (o instanceof Supplier) 189 o = ((Supplier<?>)o).get(); 190 return o; 191 } 192}