package org.yamcs.api; import java.util.HashMap; import java.util.Map; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpRequest; /** * Syntactic sugar around a media type string. Contains predefined ones, but is * open-ended for when we support dynamic rest handlers better. */ public final class MediaType { static final Map<String, MediaType> knownTypes = new HashMap<>(); public static final MediaType OCTET_STREAM = new MediaType("application/octet-stream"); public static final MediaType CSV = new MediaType("text/csv"); public static final MediaType JAVA_SERIALIZED_OBJECT = new MediaType("application/x-java-serialized-object"); public static final MediaType JSON = new MediaType("application/json"); public static final MediaType PROTOBUF = new MediaType("application/protobuf"); public static final MediaType PLAIN_TEXT = new MediaType("plain/text"); public static final MediaType ANY = new MediaType("*/*"); private final String typeString; private MediaType(String typeString) { if (typeString == null) { throw new NullPointerException("typeString must not be null"); } this.typeString = typeString; knownTypes.put(typeString, this); } public boolean is(String typeString) { return typeString != null && this.typeString.equals(typeString); } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof MediaType)) return false; return typeString.equals(((MediaType) obj).typeString); } @Override public int hashCode() { return typeString.hashCode(); } @Override public String toString() { return typeString; } /** * Returns one of the static members (OCTET_STREAM, CSV, etc) if this is a known type or a new object if the type is unknown. * * @param typeString * @return the MediaType object corresponding to the type string */ public static MediaType from(String typeString) { MediaType mt = knownTypes.get(typeString); if(mt!=null) return mt; return new MediaType(typeString); } /** * @param req * @return the Content-Type header if present or JSON by default if the Content-Type header is not present. */ public static MediaType getContentType(HttpRequest req) { String declaredContentType = req.headers().get(HttpHeaderNames.CONTENT_TYPE); if(declaredContentType!=null) { return MediaType.from(declaredContentType); } return MediaType.JSON; } /** * @param req * @return the Accept header if present and not set to ANY or Content-Type header if present or JSON if none of the headers is present or the Accept is present and set to ANY. */ public static MediaType getAcceptType(HttpRequest req) { String acceptType = req.headers().get(HttpHeaderNames.ACCEPT); if(acceptType!=null) { MediaType r = MediaType.from(acceptType); if(r==MediaType.ANY) { return getContentType(req); } else { return r; } } else { return getContentType(req); } } }