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

aQute.openapi.provider.OpenAPIBase Maven / Gradle / Ivy

package aQute.openapi.provider;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.WeakHashMap;
import java.util.function.Function;

import javax.servlet.http.HttpServletResponse;

import aQute.lib.exceptions.Exceptions;
import aQute.openapi.util.WWWUtils;

public abstract class OpenAPIBase {

	final Map,Object> securities = Collections.synchronizedMap(new WeakHashMap<>());

	public interface Codec {
		String encode(Object object, OutputStream out) throws Exception;

		 T decode(Class type, InputStream in, String mime, Function,X> instantiator) throws Exception;

		 List decodeList(Class type, InputStream in, String mime, Function,X> instantiator)
				throws Exception;

		 void addStringHandler(Class type, Function toString, Function fromString);

		String getContentType();

	}

	public static class MimeWrapper {
		public MimeWrapper(String mimeType, byte[] data) {
			this.mimeType = mimeType;
			this.data = data;
		}

		public final String	mimeType;
		public final byte[]	data;
	}

	public enum Method {
		GET, PUT, DELETE, POST, PATCH, HEAD, OPTIONS;
	}

	public static class DoNotTouchResponse extends RuntimeException {
		private static final long serialVersionUID = 1L;
	}

	public static class Response extends RuntimeException {
		private static final long	serialVersionUID	= 1L;
		final Map	headers				= new HashMap<>();;
		final int					resultCode;
		final Object				result;

		public Response(int resultCode, String reason) {
			super(resultCode + ":" + reason);
			this.resultCode = resultCode;
			this.result = null;
		}

		public Response(int resultCode, Object result) {
			super(resultCode + "");
			this.resultCode = resultCode;
			this.result = result;
		}

		public Response(int resultCode, String reason, Throwable ex) {
			super(resultCode + ":" + reason, ex);
			this.resultCode = resultCode;
			this.result = null;
		}

		public Response addHeader(String header, String value) {

			assert !headers.containsKey(header);

			headers.put(header, value);
			return this;
		}

		public Object getResult() {
			return result;
		}
	}

	public static class ConflictResponse extends Response {
		private static final long serialVersionUID = 1L;

		public ConflictResponse(String reason) {
			super(HttpServletResponse.SC_CONFLICT, reason);
		}

		public ConflictResponse(Object result) {
			super(HttpServletResponse.SC_CONFLICT, result);
		}

		public ConflictResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_CONFLICT, reason, ex);
		}
	}

	public static class BadRequestResponse extends Response {
		private static final long serialVersionUID = 1L;

		public BadRequestResponse(String reason) {
			super(HttpServletResponse.SC_BAD_REQUEST, reason);
		}

		public BadRequestResponse(Object result) {
			super(HttpServletResponse.SC_BAD_REQUEST, result);
		}

		public BadRequestResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_BAD_REQUEST, reason, ex);
		}
	}

	public enum AuthenticationScheme {
		Basic

	}

	public static class UnauthorizedResponse extends Response {
		private static final long serialVersionUID = 1L;

		public UnauthorizedResponse(Object reason, AuthenticationScheme scheme, String realm,
				Map parameters) {
			super(HttpServletResponse.SC_UNAUTHORIZED, reason);
			StringBuilder sb = new StringBuilder();
			sb.append(scheme.toString());
			WWWUtils.property(sb, "realm", realm);
			WWWUtils.properties(sb, parameters);
			headers.put("WWW-Authenticate", sb.toString());
		}

		public UnauthorizedResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_UNAUTHORIZED, reason, ex);
		}
	}

	public static class NotFoundResponse extends Response {
		private static final long serialVersionUID = 1L;

		public NotFoundResponse(String reason) {
			super(HttpServletResponse.SC_NOT_FOUND, reason);
		}

		public NotFoundResponse(Object reason) {
			super(HttpServletResponse.SC_NOT_FOUND, reason);
		}

		public NotFoundResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_NOT_FOUND, reason, ex);
		}
	}

	public static class NoContentResponse extends Response {
		private static final long serialVersionUID = 1L;

		public NoContentResponse(String reason) {
			super(HttpServletResponse.SC_NO_CONTENT, reason);
		}

		public NoContentResponse(Object reason) {
			super(HttpServletResponse.SC_NO_CONTENT, reason);
		}

		public NoContentResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_NO_CONTENT, reason, ex);
		}
	}

	public static class InternalServerErrorResponse extends Response {
		private static final long serialVersionUID = 1L;

		public InternalServerErrorResponse(String reason) {
			super(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, reason);
		}

		public InternalServerErrorResponse(Object reason) {
			super(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, reason);
		}

		public InternalServerErrorResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, reason, ex);
		}
	}

	public static class CreatedResponse extends Response {
		private static final long serialVersionUID = 1L;

		public CreatedResponse(String reason) {
			super(HttpServletResponse.SC_CREATED, reason);
		}

		public CreatedResponse(Object reason) {
			super(HttpServletResponse.SC_CREATED, reason);
		}

		public CreatedResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_CREATED, reason, ex);
		}
	}

	public static class FoundResponse extends Response {
		private static final long serialVersionUID = 1L;

		public FoundResponse(String reason) {
			super(HttpServletResponse.SC_FOUND, reason);
		}

		public FoundResponse(Object reason) {
			super(HttpServletResponse.SC_FOUND, reason);
		}

		public FoundResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_FOUND, reason, ex);
		}
	}

	public static class ForbiddenResponse extends Response {
		private static final long serialVersionUID = 1L;

		public ForbiddenResponse(String reason) {
			super(HttpServletResponse.SC_FORBIDDEN, reason);
		}

		public ForbiddenResponse(Object reason) {
			super(HttpServletResponse.SC_FORBIDDEN, reason);
		}

		public ForbiddenResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_FORBIDDEN, reason, ex);
		}
	}

	public static class GoneResponse extends Response {
		private static final long serialVersionUID = 1L;

		public GoneResponse(Object reason) {
			super(HttpServletResponse.SC_GONE, reason);
		}

		public GoneResponse(String reason) {
			super(HttpServletResponse.SC_GONE, reason);
		}

		public GoneResponse(String reason, Throwable ex) {
			super(HttpServletResponse.SC_GONE, reason, ex);
		}
	}

	public abstract static class RedirectResponse extends Response {
		private static final long	serialVersionUID	= 1L;
		private URI					uri;

		public RedirectResponse(URI uri, int code, String reason) {
			super(code, reason);
			this.uri = uri;
		}

		public URI getUri() {
			return uri;
		}
	}

	public static class MovedTemporarilyResponse extends RedirectResponse {
		private static final long serialVersionUID = 1L;

		public MovedTemporarilyResponse(URI uri, String reason) {
			super(uri, HttpServletResponse.SC_MOVED_TEMPORARILY, reason);
		}
	}

	public static class MovedPermanentlyResponse extends RedirectResponse {
		private static final long serialVersionUID = 1L;

		public MovedPermanentlyResponse(URI uri, String reason) {
			super(uri, HttpServletResponse.SC_MOVED_PERMANENTLY, reason);
		}
	}

	public static class TemporaryRedirectResponse extends RedirectResponse {
		private static final long serialVersionUID = 1L;

		public TemporaryRedirectResponse(URI uri, String reason) {
			super(uri, HttpServletResponse.SC_TEMPORARY_REDIRECT, reason);
		}
	}

	public static class Part {
		final javax.servlet.http.Part part;

		Part(javax.servlet.http.Part part) {
			this.part = part;
		}

		public String getContentType() {
			return part.getContentType();
		}

		public String getHeader(String arg0) {
			return part.getHeader(arg0);
		}

		public Collection getHeaderNames() {
			return part.getHeaderNames();
		}

		public Collection getHeaders(String arg0) {
			return part.getHeaders(arg0);
		}

		public InputStream getInputStream() throws IOException {
			return part.getInputStream();
		}

		public String getName() {
			return part.getName();
		}

		public long getSize() {
			return part.getSize();
		}

		public String getSubmittedFileName() {
			return part.getSubmittedFileName();
		}

	}

	public static class DTO extends org.osgi.dto.DTO {

	}

	final String						prefix;
	final ThreadLocal	contexts	= new ThreadLocal<>();
	final String[]						ops;
	final Class< ? extends OpenAPIBase>	parent;

	public abstract boolean dispatch_(OpenAPIContext context, String[] segments, int index) throws Exception;

	public void before_(OpenAPIContext context) throws Exception {
		contexts.set(context);
	}

	public void after_(OpenAPIContext context) throws Exception {
		contexts.remove();
	}

	protected OpenAPIBase(String prefix, String... ops) {
		this.prefix = prefix;
		this.ops = ops;
		this.parent = null;
	}

	protected OpenAPIBase(String prefix, Class< ? extends OpenAPIBase> parent, String... ops) {
		this.prefix = prefix;
		this.parent = parent;
		this.ops = ops;
	}

	protected OpenAPIContext getOpenAPIContext() {
		return contexts.get();
	}

	public OpenAPIBase.Codec codec_() {
		return OpenAPIRuntime.deflt;
	}

	@Override
	public String toString() {
		return this.getClass().getSimpleName();
	}

	public static Codec createOpenAPICodec() {
		return new CodecWrapper();
	}

	public  T instantiate_(Class type) {
		try {
			return type.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw Exceptions.duck(e);
		}
	}

	@SuppressWarnings("unchecked")
	protected static  void addDateTimeHandler(Codec codec, Class dateAndOrTimeClass, String pattern) {
		if (dateAndOrTimeClass == Instant.class) {
			DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.of("UTC"));
			codec.addStringHandler(Instant.class, df::format, (s) -> Instant.from(df.parse(s)));
		} else if (dateAndOrTimeClass == Date.class) {
			SimpleDateFormat df = new SimpleDateFormat(pattern);
			TimeZone utc = TimeZone.getTimeZone("UTC");
			codec.addStringHandler(Date.class, d -> {
				synchronized (df) {
					df.setTimeZone(utc);
					return df.format(d);
				}
			}, (s) -> {
				try {
					synchronized (df) {
						df.setTimeZone(utc);
						return df.parse(s);
					}
				} catch (ParseException e) {
					throw new RuntimeException(e);
				}
			});
		} else if (TemporalAccessor.class.isAssignableFrom(dateAndOrTimeClass)) {
			Class temporalAccessor = (Class) dateAndOrTimeClass;

			try {
				DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
				MethodHandles.Lookup lookup = MethodHandles.lookup();
				MethodType mt = MethodType.methodType(temporalAccessor, CharSequence.class, DateTimeFormatter.class);
				MethodHandle mh = lookup.findStatic(dateAndOrTimeClass, "parse", mt);
				codec.addStringHandler(temporalAccessor, df::format, (s) -> {
					try {
						return temporalAccessor.cast(mh.invoke(s, df));
					} catch (RuntimeException | Error e) {
						throw e;
					} catch (Throwable e) {
						throw new RuntimeException(e);
					}
				});
			} catch (NoSuchMethodException | IllegalAccessException e1) {
				throw new RuntimeException(e1);
			}
		} else
			throw new IllegalArgumentException("Not a Date class or TemporalAccess " + dateAndOrTimeClass);
	}

	public boolean hasPermission(String action, String... arguments) throws Exception {
		return getOpenAPIContext().hasPermission(action, arguments);
	}

	public void checkPermission(String action, String... arguments) throws Exception {
		getOpenAPIContext().checkPermission(action, arguments);
	}

	public  T getSemanticSecurity(Class type) {
		Object o = securities.get(type);
		if (o == null) {
			o = Proxy.newProxyInstance(type.getClassLoader(), new Class< ? >[] {
					type
			}, new InvocationHandler() {

				@Override
				public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
					String action = method.getName().replace('_', ':');
					String as[] = new String[args.length];
					for (int i = 0; i < as.length; i++)
						as[i] = args[i] == null ? "" : args.toString();

					if (method.getReturnType() == boolean.class)
						return hasPermission(action, as);
					else
						checkPermission(action, as);
					return null;
				}
			});
			securities.put(type, o);
		}
		return type.cast(o);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy