io.ingenieux.lambada.invoker.UserHandlerFactory Maven / Gradle / Ivy
/*
* Copyright (c) 2016 ingenieux Labs
*
* Licensed 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 io.ingenieux.lambada.invoker;
import com.amazonaws.services.lambda.runtime.Context;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
public abstract class UserHandlerFactory {
public abstract UserHandler getUserHandler(Object o, Method m);
public static class NoOpUserHandlerFactory extends UserHandlerFactory {
public UserHandler getUserHandler(Object o, Method m) {
if (0 == m.getParameterCount() && hasReturnType(m, Void.TYPE)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o);
}
};
}
if (hasReturnType(m, Void.TYPE) && hasParameterTypes(m, Context.class)) {
return new UserHandler(o, m) {
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, c);
}
};
}
return null;
}
}
public static class RawUserHandlerFactory extends UserHandlerFactory {
public UserHandler getUserHandler(Object o, Method m) {
if (1 == m.getParameterCount() && hasReturnType(m, Void.TYPE) && hasParameterTypes(m, InputStream.class)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, is);
}
};
}
if (2 == m.getParameterCount() && hasReturnType(m, Void.TYPE) && hasParameterTypes(m, InputStream.class, Context.class)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, is, c);
}
};
}
if (1 == m.getParameterCount() && hasReturnType(m, Void.TYPE) && hasParameterTypes(m, OutputStream.class)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, os);
}
};
}
if (2 == m.getParameterCount() && hasReturnType(m, Void.TYPE) && hasParameterTypes(m, OutputStream.class, Context.class)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, os, c);
}
};
}
if (2 == m.getParameterCount() &&
hasReturnType(m, Void.TYPE) &&
hasParameterTypes(m, InputStream.class, OutputStream.class)) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, is, os);
}
};
}
if (3 == m.getParameterCount() &&
hasReturnType(m, Void.TYPE) &&
hasParameterTypes(m, InputStream.class, OutputStream.class, Context.class)) {
return new UserHandler(o, m) {
public void invoke(InputStream is, OutputStream os, Context c) throws Exception {
m.invoke(o, is, os, c);
}
};
}
return null;
}
}
public static class JacksonAbleUserHandlerFactory extends UserHandlerFactory {
final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public UserHandler getUserHandler(Object o, final Method m) {
if (1 == m.getParameterCount() &&
hasJacksonAbleParameters(m, m.getParameterTypes()[0]) && Void.TYPE.equals(m.getReturnType())) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context ctx) throws Exception {
Object inputArgument = OBJECT_MAPPER.readValue(is, m.getParameterTypes()[0]);
m.invoke(o, inputArgument);
}
};
}
if (1 == m.getParameterCount() && hasJacksonAbleParameters(m, m.getParameterTypes()[0],
m.getReturnType())) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context ctx) throws Exception {
Object inputArgument = OBJECT_MAPPER.readValue(is, m.getParameterTypes()[0]);
Object result = m.invoke(o, inputArgument);
OBJECT_MAPPER.writeValue(os, result);
}
};
}
if (2 == m.getParameterCount() &&
m.getParameterTypes()[1] == Context.class &&
hasJacksonAbleParameters(m, m.getParameterTypes()[0], m.getReturnType())) {
return new UserHandler(o, m) {
@Override
public void invoke(InputStream is, OutputStream os, Context ctx) throws Exception {
Object inputArgument = OBJECT_MAPPER.readValue(is, m.getParameterTypes()[0]);
Object result = m.invoke(o, inputArgument, ctx);
OBJECT_MAPPER.writeValue(os, result);
}
};
}
return null;
}
protected boolean hasJacksonAbleParameters(Method m, Type... types) {
for (Type t : types) {
try {
JavaType javaType = (JavaType) OBJECT_MAPPER.getTypeFactory().constructType(t);
boolean serializeP = OBJECT_MAPPER.canSerialize((Class>) t);
boolean deserializeP = OBJECT_MAPPER.canDeserialize(javaType);
if (! (serializeP && deserializeP))
return false;
} catch (IllegalArgumentException e) {
return false;
}
}
return true;
}
}
protected boolean hasReturnType(Method m, Class> t) {
return m.getReturnType().equals(t);
}
protected boolean hasParameterTypes(Method m, Class>... types) {
int i = 0;
for (Class> t : types) {
if (!t.equals(m.getParameterTypes()[i])) {
return false;
}
i++;
}
return true;
}
private static final UserHandlerFactory[] factories = new UserHandlerFactory[] {
new NoOpUserHandlerFactory(),
new RawUserHandlerFactory(),
new JacksonAbleUserHandlerFactory(),
};
public static UserHandler findUserFactory(Object o, Method m) {
UserHandler h = null;
for (UserHandlerFactory f : factories) {
h = f.getUserHandler(o, m);
if (null != h) {
break;
}
}
return h;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy