|
@@ -0,0 +1,219 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
|
|
+ * @copyright Ranides Atterwim
|
|
|
|
|
+ * @license WTFPL
|
|
|
|
|
+ * @url http://ranides.net/projects/assira
|
|
|
|
|
+ */
|
|
|
|
|
+package net.ranides.assira.reflection.impl;
|
|
|
|
|
+
|
|
|
|
|
+import java.lang.annotation.Annotation;
|
|
|
|
|
+import java.lang.annotation.IncompleteAnnotationException;
|
|
|
|
|
+import java.lang.reflect.Parameter;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
+import java.util.function.Supplier;
|
|
|
|
|
+import javax.jws.WebMethod;
|
|
|
|
|
+import javax.jws.WebParam;
|
|
|
|
|
+import javax.jws.WebResult;
|
|
|
|
|
+import javax.jws.WebService;
|
|
|
|
|
+import net.ranides.assira.collection.maps.Cache;
|
|
|
|
|
+import net.ranides.assira.collection.maps.MapCollectors;
|
|
|
|
|
+import net.ranides.assira.collection.query.CQueryBuilder;
|
|
|
|
|
+import net.ranides.assira.generic.LazyReference;
|
|
|
|
|
+import net.ranides.assira.reflection.IAnnotations;
|
|
|
|
|
+import net.ranides.assira.reflection.IArgument;
|
|
|
|
|
+import net.ranides.assira.reflection.IArguments;
|
|
|
|
|
+import net.ranides.assira.reflection.IAttribute;
|
|
|
|
|
+import net.ranides.assira.reflection.IClass;
|
|
|
|
|
+import net.ranides.assira.reflection.IContext;
|
|
|
|
|
+import net.ranides.assira.reflection.IMethod;
|
|
|
|
|
+import net.ranides.assira.reflection.WSMethod;
|
|
|
|
|
+import net.ranides.assira.reflection.WSModel;
|
|
|
|
|
+import net.ranides.assira.text.StringTraits;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author ranides
|
|
|
|
|
+ */
|
|
|
|
|
+public class WSInpsector implements WSModel {
|
|
|
|
|
+
|
|
|
|
|
+ private static final Cache<IClass<?>,WSModel> CACHE = new Cache<>();
|
|
|
|
|
+
|
|
|
|
|
+ private final IClass<?> type;
|
|
|
|
|
+ private final String name;
|
|
|
|
|
+ private final String targetNamespace;
|
|
|
|
|
+ private final String service;
|
|
|
|
|
+ private final String port;
|
|
|
|
|
+ private final String location;
|
|
|
|
|
+ private final Map<String, WSMethod> methods;
|
|
|
|
|
+
|
|
|
|
|
+ private WSInpsector(IClass<?> type) {
|
|
|
|
|
+ this.type = type;
|
|
|
|
|
+ WebService serviceInfo = type.annotation(WebService.class)
|
|
|
|
|
+ .orElseThrow(() -> new IncompleteAnnotationException(WebParam.class, type.name()));
|
|
|
|
|
+
|
|
|
|
|
+ name = serviceInfo.name();
|
|
|
|
|
+ targetNamespace = serviceInfo.targetNamespace();
|
|
|
|
|
+ service = serviceInfo.serviceName();
|
|
|
|
|
+ port = serviceInfo.portName();
|
|
|
|
|
+ location = serviceInfo.wsdlLocation();
|
|
|
|
|
+
|
|
|
|
|
+ methods = type.methods()
|
|
|
|
|
+ .require(IAttribute.PUBLIC)
|
|
|
|
|
+ .require(WebMethod.class)
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(RWSMethod::new)
|
|
|
|
|
+ .filter(m -> !m.exclude)
|
|
|
|
|
+ .collect(MapCollectors.unique(m -> m.operation()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static WSModel resolve(IClass<?> type) {
|
|
|
|
|
+ return CACHE.get(type, () -> new WSInpsector(type));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Map<String, WSMethod> methods() {
|
|
|
|
|
+ return methods;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Optional<WSMethod> method(String name) {
|
|
|
|
|
+ return Optional.ofNullable(methods.get(name));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String name() {
|
|
|
|
|
+ return name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String port() {
|
|
|
|
|
+ return port;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String service() {
|
|
|
|
|
+ return service;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String namespace() {
|
|
|
|
|
+ return targetNamespace;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String location() {
|
|
|
|
|
+ return location;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IClass<?> type() {
|
|
|
|
|
+ return type;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class RWSMethod extends RMethod implements WSMethod {
|
|
|
|
|
+
|
|
|
|
|
+ final String resultname;
|
|
|
|
|
+ final String action;
|
|
|
|
|
+ final String operation;
|
|
|
|
|
+ final boolean exclude;
|
|
|
|
|
+ final Supplier<IArguments> arguments;
|
|
|
|
|
+
|
|
|
|
|
+ RWSMethod(IMethod method) {
|
|
|
|
|
+ super(false, method.context(), method.reflective(), null);
|
|
|
|
|
+ WebMethod info = method.annotation(WebMethod.class).get();
|
|
|
|
|
+ this.operation = or(info.operationName(), method.name());
|
|
|
|
|
+ this.action = info.action();
|
|
|
|
|
+ this.exclude = info.exclude();
|
|
|
|
|
+ this.resultname = or(method.annotation(WebResult.class).map(WebResult::name).orElse(""), returns().shortname());
|
|
|
|
|
+ this.arguments = LazyReference.concurrent(() -> {
|
|
|
|
|
+ IArguments args = method.arguments();
|
|
|
|
|
+ return FElements.newArguments(AHints.EMPTY, args.count(), args.stream().map(WSArgument::new));
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IArguments arguments() {
|
|
|
|
|
+ return arguments.get();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String action() {
|
|
|
|
|
+ return action;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String operation() {
|
|
|
|
|
+ return operation;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String resultname() {
|
|
|
|
|
+ return resultname;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static String or(String a, String b) {
|
|
|
|
|
+ return StringTraits.isEmpty(a) ? b : a;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class WSArgument implements IArgument {
|
|
|
|
|
+
|
|
|
|
|
+ private final IArgument that;
|
|
|
|
|
+ private final Optional<String> name;
|
|
|
|
|
+
|
|
|
|
|
+ public WSArgument(IArgument that) {
|
|
|
|
|
+ this.that = that;
|
|
|
|
|
+ this.name = that.annotation(WebParam.class).map(WebParam::name);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IArguments collect() {
|
|
|
|
|
+ return FElements.newArguments(AHints.EMPTY, 1, CQueryBuilder.of(this));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IClass<?> type() {
|
|
|
|
|
+ return that.type();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IMethod parent() {
|
|
|
|
|
+ return that.parent();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Parameter reflective() {
|
|
|
|
|
+ return that.reflective();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IContext context() {
|
|
|
|
|
+ return that.context();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public String name() {
|
|
|
|
|
+ return name.orElse(that.name());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Set<IAttribute> attributes() {
|
|
|
|
|
+ return that.attributes();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public IAnnotations annotations() {
|
|
|
|
|
+ return that.annotations();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public <A extends Annotation> Optional<A> annotation(Class<A> type) {
|
|
|
|
|
+ return that.annotation(type);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|