All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.rest.httppart.RequestHttpPart Maven / Gradle / Ivy

// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.rest.httppart;

import static org.apache.juneau.httppart.HttpPartType.*;
import static org.apache.juneau.internal.CollectionUtils.*;

import java.lang.reflect.*;
import java.time.*;
import java.util.*;
import java.util.regex.*;

import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.assertions.*;
import org.apache.juneau.http.*;
import org.apache.juneau.http.part.*;
import org.apache.juneau.http.response.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.oapi.*;
import org.apache.juneau.parser.ParseException;
import org.apache.juneau.reflect.*;
import org.apache.juneau.rest.*;

/**
 * Represents a single HTTP part on an HTTP request.
 *
 * Parent of the following classes:
 * 
    *
  • {@link RequestHeader} *
  • {@link RequestQueryParam} *
  • {@link RequestFormParam} *
  • {@link RequestPathParam} *
* *
See Also:
*/ @FluentSetters public class RequestHttpPart { private final HttpPartType partType; private final String name; private final RestRequest request; private HttpPartParserSession parser; private HttpPartSchema schema; String value; /** * Constructor. * * @param partType The HTTP part type. * @param request The request object. * @param name The part name. * @param value The part value. */ public RequestHttpPart(HttpPartType partType, RestRequest request, String name, String value) { this.partType = partType; this.request = request; this.name = name; this.value = value; parser(null); } //------------------------------------------------------------------------------------------------------------------ // Setters //------------------------------------------------------------------------------------------------------------------ /** * Specifies the part schema for this part. * *

* Used by schema-based part parsers such as {@link OpenApiParser}. * * @param value * The part schema. * @return This object. */ @FluentSetter public RequestHttpPart schema(HttpPartSchema value) { this.schema = value; return this; } /** * Specifies the part parser to use for this part. * *

* If not specified, uses the part parser defined on the client by calling {@link org.apache.juneau.rest.RestContext.Builder#partParser()}. * * @param value * The new part parser to use for this part. *
If null, {@link SimplePartParser#DEFAULT} will be used. * @return This object. */ @FluentSetter public RequestHttpPart parser(HttpPartParserSession value) { this.parser = value == null ? SimplePartParser.DEFAULT_SESSION : value; return this; } /** * Sets a default value for this part. * * @param def The default value. * @return This object. */ public RequestHttpPart def(String def) { if (value == null) value = def; return this; } //------------------------------------------------------------------------------------------------------------------ // Retrievers //------------------------------------------------------------------------------------------------------------------ /** * Returns the value of this part. * * @return The value of this part. */ public String getValue() { return value; } /** * Returns true if this part exists on the request. * *

* This is a shortened form for calling asString().isPresent(). * * @return true if this part exists on the request. */ public boolean isPresent() { return asString().isPresent(); } /** * If a value is present, returns the value, otherwise throws {@link NoSuchElementException}. * *

* This is a shortened form for calling asString().get(). * * @return The value if present. */ public String get() { return asString().get(); } /** * Return the value if present, otherwise return other. * *

* This is a shortened form for calling asString().orElse(other). * * @param other The value to be returned if there is no value present, may be null. * @return The value, if present, otherwise other. */ public String orElse(String other) { return asString().orElse(other); } /** * Returns the value of this part as a string. * * @return The value of this part as a string, or {@link Optional#empty()} if the part was not present. */ public Optional asString() { return optional(getValue()); } /** * Converts this part to the specified POJO type using the request {@link HttpPartParser} and optional schema. * *

* See Complex Data Types for information on defining complex generic types of {@link Map Maps} and {@link Collection Collections}. * * @param The type to convert to. * @param type The type to convert to. * @param args The type parameters. * @return The converted type, or {@link Optional#empty()} if the part is not present. * @throws BasicHttpException If value could not be parsed. */ public Optional as(Type type, Type...args) throws BasicHttpException { return as(request.getBeanSession().getClassMeta(type, args)); } /** * Converts this part to the specified POJO type using the request {@link HttpPartParser} and optional schema. * *

* If the specified type is an HTTP part type (extends from {@link org.apache.http.Header}/{@link NameValuePair}), then looks for * one of the following constructors: *

    *
  • public T(String name, String value); *
* *

* If it doesn't find one of those constructors, then it parses it into the specified type using the part parser. * * @param The type to convert to. * @param type The type to convert to. * @return The converted type, or {@link Optional#empty()} if the part is not present. * @throws BasicHttpException If value could not be parsed. */ public Optional as(Class type) throws BasicHttpException { return as(request.getBeanSession().getClassMeta(type)); } /** * Converts this part to the specified POJO type using the request {@link HttpPartParser} and optional schema. * *

* If the specified type is an HTTP part type (extends from {@link org.apache.http.Header}/{@link NameValuePair}), then looks for * one of the following constructors: *

    *
  • public T(String name, String value); *
* *

* If it doesn't find one of those constructors, then it parses it into the specified type using the part parser. * * @param The type to convert to. * @param type The type to convert to. * @return The converted type, or {@link Optional#empty()} if the part is not present. * @throws BasicHttpException If value could not be parsed. */ public Optional as(ClassMeta type) throws BasicHttpException { try { if (HttpParts.isHttpPart(partType, type)) { ConstructorInfo cc = HttpParts.getConstructor(type).orElse(null); if (cc != null) { if (! isPresent()) return empty(); if (cc.hasParamTypes(String.class)) return optional(cc.invoke(get())); if (cc.hasParamTypes(String.class, String.class)) return optional(cc.invoke(getName(), get())); } } return optional(parser.parse(HEADER, schema, orElse(null), type)); } catch (ParseException e) { throw new BadRequest(e, "Could not parse {0} parameter ''{1}''.", partType.toString().toLowerCase(), getName()); } } /** * Matches the specified pattern against this part value. * *

Example:
*

* Matcher matcher = request * .getHeader("Content-Type") * .asMatcher(Pattern.compile("application/(.*)")); * * if (matcher.matches()) { * String mediaType = matcher.group(1); * } *

* * @param pattern The regular expression pattern to match. * @return The matcher. * @throws BasicHttpException If a connection error occurred. */ public Matcher asMatcher(Pattern pattern) throws BasicHttpException { return pattern.matcher(orElse("")); } /** * Matches the specified pattern against this part value. * *
Example:
*

* Matcher matcher = request * .getHeader("Content-Type") * .asMatcher("application/(.*)"); * * if (matcher.matches()) { * String mediaType = matcher.group(1); * } *

* * @param regex The regular expression pattern to match. * @return The matcher. * @throws BasicHttpException If a connection error occurred. */ public Matcher asMatcher(String regex) throws BasicHttpException { return asMatcher(regex, 0); } /** * Matches the specified pattern against this part value. * *
Example:
*

* Matcher matcher = request * .getHeader("Content-Type") * .asMatcher("application/(.*)", CASE_INSENSITIVE); * * if (matcher.matches()) { * String mediaType = matcher.group(1); * } *

* * @param regex The regular expression pattern to match. * @param flags Pattern match flags. See {@link Pattern#compile(String, int)}. * @return The matcher. * @throws BasicHttpException If a connection error occurred. */ public Matcher asMatcher(String regex, int flags) throws BasicHttpException { return asMatcher(Pattern.compile(regex, flags)); } /** * Returns the value of this parameter as an integer. * * @return The value of this parameter as an integer, or {@link Optional#empty()} if the parameter was not present. */ public Optional asInteger() { return asIntegerPart().asInteger(); } /** * Returns the value of this parameter as a boolean. * * @return The value of this parameter as a boolean, or {@link Optional#empty()} if the parameter was not present. */ public Optional asBoolean() { return asBooleanPart().asBoolean(); } /** * Returns the value of this parameter as a long. * * @return The value of this parameter as a long, or {@link Optional#empty()} if the parameter was not present. */ public Optional asLong() { return asLongPart().asLong(); } /** * Returns the value of this parameter as a date. * * @return The value of this parameter as a date, or {@link Optional#empty()} if the parameter was not present. */ public Optional asDate() { return asDatePart().asZonedDateTime(); } /** * Returns the value of this parameter as a list from a comma-delimited string. * * @return The value of this parameter as a list from a comma-delimited string, or {@link Optional#empty()} if the parameter was not present. */ public Optional> asCsvArray() { return asCsvArrayPart().asList(); } /** * Returns the value of this parameter as a {@link BasicCsvArrayPart}. * * @return The value of this parameter as a {@link BasicCsvArrayPart}, never null. */ public BasicCsvArrayPart asCsvArrayPart() { return new BasicCsvArrayPart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicDatePart}. * * @return The value of this parameter as a {@link BasicDatePart}, never null. */ public BasicDatePart asDatePart() { return new BasicDatePart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicIntegerPart}. * * @return The value of this parameter as a {@link BasicIntegerPart}, never null. */ public BasicIntegerPart asIntegerPart() { return new BasicIntegerPart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicBooleanPart}. * * @return The value of this parameter as a {@link BasicBooleanPart}, never null. */ public BasicBooleanPart asBooleanPart() { return new BasicBooleanPart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicLongPart}. * * @return The value of this parameter as a {@link BasicLongPart}, never null. */ public BasicLongPart asLongPart() { return new BasicLongPart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicStringPart}. * * @return The value of this parameter as a {@link BasicStringPart}, never null. */ public BasicStringPart asStringPart() { return new BasicStringPart(getName(), getValue()); } /** * Returns the value of this parameter as a {@link BasicUriPart}. * * @return The value of this parameter as a {@link BasicUriPart}, never null. */ public BasicUriPart asUriPart() { return new BasicUriPart(getName(), getValue()); } //------------------------------------------------------------------------------------------------------------------ // Assertions //------------------------------------------------------------------------------------------------------------------ /** * Provides the ability to perform fluent-style assertions on this parameter. * *
Examples:
*

* request * .getQueryParam("foo") * .assertString().contains("bar"); *

* *

* The assertion test returns the original object allowing you to chain multiple requests like so: *

* String foo = request * .getQueryParam("foo") * .assertString().contains("bar") * .asString().get(); *

* * @return A new fluent assertion object. */ public FluentStringAssertion assertString() { return new FluentStringAssertion<>(orElse(null), this); } /** * Provides the ability to perform fluent-style assertions on an integer parameter. * *
Examples:
*

* request * .getQueryParam("age") * .assertInteger().isGreaterThan(1); *

* * @return A new fluent assertion object. */ public FluentIntegerAssertion assertInteger() { return new FluentIntegerAssertion<>(asIntegerPart().asInteger().orElse(null), this); } /** * Provides the ability to perform fluent-style assertions on a long parameter. * *
Examples:
*

* request * .getQueryParam("length") * .assertLong().isLessThan(100000); *

* * @return A new fluent assertion object. */ public FluentLongAssertion assertLong() { return new FluentLongAssertion<>(asLongPart().asLong().orElse(null), this); } /** * Provides the ability to perform fluent-style assertions on a date parameter. * *
Examples:
*

* request * .getQueryParam("time") * .assertDate().isAfterNow(); *

* * @return A new fluent assertion object. */ public FluentZonedDateTimeAssertion assertDate() { return new FluentZonedDateTimeAssertion<>(asDatePart().asZonedDateTime().orElse(null), this); } /** * Provides the ability to perform fluent-style assertions on comma-separated string parameters. * *
Examples:
*

* request * .getQueryParam("allow") * .assertCsvArray().contains("GET"); *

* * @return A new fluent assertion object. */ public FluentListAssertion assertCsvArray() { return new FluentListAssertion<>(asCsvArrayPart().asList().orElse(null), this); } /** * Returns the request that created this part. * * @return The request that created this part. */ protected RestRequest getRequest() { return request; } /** * Gets the name of this part. * * @return The name of this part, never null. */ public String getName() { return name; } @Override /* Object */ public String toString() { return getName() + "=" + getValue(); } // // }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy