Skip to content

Commit

Permalink
Put duplicated methods into a common superclass
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <jan.supol@oracle.com>
  • Loading branch information
jansupol committed Feb 22, 2024
1 parent f86cdf0 commit 4ca1e78
Show file tree
Hide file tree
Showing 3 changed files with 474 additions and 555 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -67,7 +67,7 @@
*
* @author Marek Potociar
*/
public abstract class InboundMessageContext {
public abstract class InboundMessageContext extends MessageHeaderMethods {

private static final InputStream EMPTY = new InputStream() {

Expand Down Expand Up @@ -100,7 +100,6 @@ public boolean markSupported() {
private final boolean translateNce;
private MessageBodyWorkers workers;
private final Configuration configuration;
private final RuntimeDelegate runtimeDelegateDecorator;
private LazyValue<MediaType> contentTypeCache;
private LazyValue<List<AcceptableMediaType>> acceptTypeCache;

Expand Down Expand Up @@ -166,11 +165,11 @@ public InboundMessageContext(Configuration configuration) {
* as required by JAX-RS specification on the server side.
*/
public InboundMessageContext(Configuration configuration, boolean translateNce) {
super(configuration);
this.headers = new GuardianStringKeyMultivaluedMap<>(HeaderUtils.createInbound());
this.entityContent = new EntityContent();
this.translateNce = translateNce;
this.configuration = configuration;
runtimeDelegateDecorator = RuntimeDelegateDecorator.configured(configuration);

contentTypeCache = contentTypeCache();
acceptTypeCache = acceptTypeCache();
Expand Down Expand Up @@ -319,42 +318,9 @@ public String getHeaderString(String name) {
return buffer.toString();
}

/**
* Get a single typed header value.
*
* @param name header name.
* @param converter from string conversion function. Is expected to throw {@link ProcessingException}
* if conversion fails.
* @param convertNull if {@code true} this method calls the provided converter even for {@code null}. Otherwise this
* method returns the {@code null} without calling the converter.
* @return value of the header, or (possibly converted) {@code null} if not present.
*/
private <T> T singleHeader(String name, Function<String, T> converter, boolean convertNull) {
final List<String> values = this.headers.get(name);

if (values == null || values.isEmpty()) {
return convertNull ? converter.apply(null) : null;
}
if (values.size() > 1) {
throw new HeaderValueException(LocalizationMessages.TOO_MANY_HEADER_VALUES(name, values.toString()),
HeaderValueException.Context.INBOUND);
}

Object value = values.get(0);
if (value == null) {
return convertNull ? converter.apply(null) : null;
}

try {
return converter.apply(HeaderUtils.asString(value, runtimeDelegateDecorator));
} catch (ProcessingException ex) {
throw exception(name, value, ex);
}
}

private static HeaderValueException exception(final String headerName, Object headerValue, Exception e) {
return new HeaderValueException(LocalizationMessages.UNABLE_TO_PARSE_HEADER_VALUE(headerName, headerValue), e,
HeaderValueException.Context.INBOUND);
@Override
public HeaderValueException.Context getHeaderValueExceptionContext() {
return HeaderValueException.Context.INBOUND;
}

/**
Expand All @@ -366,24 +332,6 @@ public MultivaluedMap<String, String> getHeaders() {
return this.headers;
}

/**
* Get message date.
*
* @return the message date, otherwise {@code null} if not present.
*/
public Date getDate() {
return singleHeader(HttpHeaders.DATE, new Function<String, Date>() {
@Override
public Date apply(String input) {
try {
return HttpHeaderReader.readDate(input);
} catch (ParseException ex) {
throw new ProcessingException(ex);
}
}
}, false);
}

/**
* Get If-Match header.
*
Expand Down Expand Up @@ -418,42 +366,6 @@ public Set<MatchingEntityTag> getIfNoneMatch() {
}
}

/**
* Get the language of the entity.
*
* @return the language of the entity or {@code null} if not specified.
*/
public Locale getLanguage() {
return singleHeader(HttpHeaders.CONTENT_LANGUAGE, new Function<String, Locale>() {
@Override
public Locale apply(String input) {
try {
return new LanguageTag(input).getAsLocale();
} catch (ParseException e) {
throw new ProcessingException(e);
}
}
}, false);
}

/**
* Get Content-Length value.
*
* @return Content-Length as integer if present and valid number. In other cases returns -1.
*/
public int getLength() {
return singleHeader(HttpHeaders.CONTENT_LENGTH, new Function<String, Integer>() {
@Override
public Integer apply(String input) {
try {
return (input != null && !input.isEmpty()) ? Integer.parseInt(input) : -1;
} catch (NumberFormatException ex) {
throw new ProcessingException(ex);
}
}
}, true);
}

/**
* Get the media type of the entity.
*
Expand Down Expand Up @@ -568,120 +480,6 @@ public List<AcceptableToken> getQualifiedAcceptEncoding() {
}
}

/**
* Get any cookies that accompanied the request.
*
* @return a read-only map of cookie name (String) to {@link javax.ws.rs.core.Cookie}.
*/
public Map<String, Cookie> getRequestCookies() {
List<String> cookies = this.headers.get(HttpHeaders.COOKIE);
if (cookies == null || cookies.isEmpty()) {
return Collections.emptyMap();
}

Map<String, Cookie> result = new HashMap<String, Cookie>();
for (String cookie : cookies) {
if (cookie != null) {
result.putAll(HttpHeaderReader.readCookies(cookie));
}
}
return result;
}

/**
* Get the allowed HTTP methods from the Allow HTTP header.
*
* @return the allowed HTTP methods, all methods will returned as upper case
* strings.
*/
public Set<String> getAllowedMethods() {
final String allowed = getHeaderString(HttpHeaders.ALLOW);
if (allowed == null || allowed.isEmpty()) {
return Collections.emptySet();
}
try {
return new HashSet<String>(HttpHeaderReader.readStringList(allowed.toUpperCase(Locale.ROOT)));
} catch (java.text.ParseException e) {
throw exception(HttpHeaders.ALLOW, allowed, e);
}
}

/**
* Get any new cookies set on the response message.
*
* @return a read-only map of cookie name (String) to a {@link javax.ws.rs.core.NewCookie new cookie}.
*/
public Map<String, NewCookie> getResponseCookies() {
List<String> cookies = this.headers.get(HttpHeaders.SET_COOKIE);
if (cookies == null || cookies.isEmpty()) {
return Collections.emptyMap();
}

Map<String, NewCookie> result = new HashMap<String, NewCookie>();
for (String cookie : cookies) {
if (cookie != null) {
NewCookie newCookie = HttpHeaderReader.readNewCookie(cookie);
String cookieName = newCookie.getName();
if (result.containsKey(cookieName)) {
result.put(cookieName, HeaderUtils.getPreferredCookie(result.get(cookieName), newCookie));
} else {
result.put(cookieName, newCookie);
}
}
}
return result;
}

/**
* Get the entity tag.
*
* @return the entity tag, otherwise {@code null} if not present.
*/
public EntityTag getEntityTag() {
return singleHeader(HttpHeaders.ETAG, new Function<String, EntityTag>() {
@Override
public EntityTag apply(String value) {
return EntityTag.valueOf(value);
}
}, false);
}

/**
* Get the last modified date.
*
* @return the last modified date, otherwise {@code null} if not present.
*/
public Date getLastModified() {
return singleHeader(HttpHeaders.LAST_MODIFIED, new Function<String, Date>() {
@Override
public Date apply(String input) {
try {
return HttpHeaderReader.readDate(input);
} catch (ParseException e) {
throw new ProcessingException(e);
}
}
}, false);
}

/**
* Get the location.
*
* @return the location URI, otherwise {@code null} if not present.
*/
public URI getLocation() {
return singleHeader(HttpHeaders.LOCATION, new Function<String, URI>() {
@Override
public URI apply(String value) {
try {
return URI.create(value);
} catch (IllegalArgumentException ex) {
throw new ProcessingException(ex);
}
}
}, false);
}

/**
* Get the links attached to the message as header.
*
Expand Down Expand Up @@ -726,57 +524,6 @@ public Set<Link> getLinks() {
}
}

/**
* Check if link for relation exists.
*
* @param relation link relation.
* @return {@code true} if the for the relation link exists, {@code false}
* otherwise.
*/
public boolean hasLink(String relation) {
for (Link link : getLinks()) {
List<String> relations = LinkProvider.getLinkRelations(link.getRel());

if (relations != null && relations.contains(relation)) {
return true;
}
}
return false;
}

/**
* Get the link for the relation.
*
* @param relation link relation.
* @return the link for the relation, otherwise {@code null} if not present.
*/
public Link getLink(String relation) {
for (Link link : getLinks()) {
List<String> relations = LinkProvider.getLinkRelations(link.getRel());
if (relations != null && relations.contains(relation)) {
return link;
}
}
return null;
}

/**
* Convenience method that returns a {@link javax.ws.rs.core.Link.Builder Link.Builder}
* for the relation.
*
* @param relation link relation.
* @return the link builder for the relation, otherwise {@code null} if not
* present.
*/
public Link.Builder getLinkBuilder(String relation) {
Link link = getLink(relation);
if (link == null) {
return null;
}

return Link.fromLink(link);
}

// Message entity

/**
Expand Down

0 comments on commit 4ca1e78

Please sign in to comment.