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

restx.RestxRouter Maven / Gradle / Ivy

There is a newer version: 1.2.0-rc2
Show newest version
package restx;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import restx.endpoint.*;
import restx.entity.MatchedEntityRoute;
import restx.jackson.JsonEntityRouteBuilder;
import restx.jackson.StdJsonProducerEntityRoute;
import restx.security.PermissionFactory;

import java.io.IOException;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * User: xavierhanin
 * Date: 1/19/13
 * Time: 12:19 AM
 */
public class RestxRouter {
    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private String groupName = "default";
        private String name = "default";
        private ObjectWriter writer;
        private ObjectReader reader;
        private EndpointParameterMapperRegistry registry;
        private List routes = Lists.newArrayList();

        public Builder name(final String name) {
            this.name = name;
            return this;
        }

        public Builder groupName(final String groupName) {
            this.groupName = groupName;
            return this;
        }

        public Builder withMapper(ObjectMapper mapper) {
            if (writer == null) {
                writer = mapper.writer();
            }
            if (reader == null) {
                reader = mapper.reader();
            }
            return this;
        }

        public Builder withObjectWriter(ObjectWriter writer) {
            this.writer = writer;
            return this;
        }

        public Builder withObjectReader(ObjectReader reader) {
            this.reader = reader;
            return this;
        }

        public Builder withEndpointParameterMapperRegistry(EndpointParameterMapperRegistry registry) {
            this.registry = registry;
            return this;
        }

        public Builder addRoute(RestxRoute route) {
            routes.add(route);
            return this;
        }

        public  Builder GET(String path, Class outputType, final MatchedEntityRoute route) {
            return addRoute("GET", path, outputType, route);
        }

        public  Builder DELETE(String path, Class outputType, final MatchedEntityRoute route) {
            return addRoute("DELETE", path, outputType, route);
        }

        public  Builder HEAD(String path, Class outputType, final MatchedEntityRoute route) {
            return addRoute("HEAD", path, outputType, route);
        }

        public  Builder OPTIONS(String path, Class outputType, final MatchedEntityRoute route) {
            return addRoute("OPTIONS", path, outputType, route);
        }

        public  Builder addRoute(String method, String path, Class outputType, final MatchedEntityRoute route) {
            return addRoute(path, Endpoint.of(method, path), outputType, route);
        }

        /**
         * @deprecated Prefer to use addRoute(String, Endpoint, PermissionFactory, Class<O>, MatchedEntityRoute<Void, O>)
         * in order to avoid NPEs when checking permissions through permissionFactory
         */
        public  Builder addRoute(String name, Endpoint endpoint, Class outputType, final MatchedEntityRoute route) {
            return addRoute(name, endpoint, (PermissionFactory)null, outputType, route);
        }

        public  Builder addRoute(String name, Endpoint endpoint, PermissionFactory permissionFactory, Class outputType, final MatchedEntityRoute route) {
            routes.add(new StdJsonProducerEntityRoute(name, outputType, writer.withType(outputType), endpoint, permissionFactory, registry) {
                @Override
                protected Optional doRoute(RestxRequest restxRequest, RestxResponse response, RestxRequestMatch match, Void i) throws IOException {
                    return route.route(restxRequest, match, i);
                }
            });
            return this;
        }

        public  Builder PUT(String path, Class inputType, Class outputType, MatchedEntityRoute route) {
            return addRoute("PUT", path, inputType, outputType, route);
        }

        public  Builder POST(String path, Class inputType, Class outputType, MatchedEntityRoute route) {
            return addRoute("POST", path, inputType, outputType, route);
        }

        public  Builder addRoute(String method, String path, Class inputType, Class outputType, MatchedEntityRoute route) {
            return addRoute(path, new Endpoint(method, path), inputType, outputType, route);
        }

        public  Builder addRoute(String name, Endpoint endpoint,
                                       Class inputType, Class outputType, MatchedEntityRoute route) {
            routes.add(new JsonEntityRouteBuilder()
                    .withObjectWriter(outputType, writer)
                    .withObjectReader(inputType, reader.withType(inputType))
                    .name(name)
                    .registry(registry)
                    .endpoint(endpoint)
                    .matchedEntityRoute(route)
                    .build()
            );
            return this;
        }

        public RestxRouter build() {
            return new RestxRouter(groupName, name, ImmutableList.copyOf(routes));
        }
    }

    private final ImmutableList routes;
    private final String name;
    private final String groupName;

    public RestxRouter(String name, RestxRoute... routes) {
        this("default", name, routes);
    }

    public RestxRouter(String groupName, String name, RestxRoute... routes) {
        this(groupName, name, ImmutableList.copyOf(routes));
    }

    public RestxRouter(String groupName, String name, ImmutableList routes) {
        this.groupName = checkNotNull(groupName);
        this.name = checkNotNull(name);
        this.routes = checkNotNull(routes);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        toString(sb, "");
        return sb.toString();
    }

    public void toString(StringBuilder sb, String indent) {
        sb.append(indent).append(name).append("[RestxRouter] {\n");
        for (RestxRoute route : routes) {
            sb.append(indent).append("    ").append(route).append("\n");
        }
        sb.append(indent).append("}");
    }

    public int getNbRoutes() {
        return routes.size();
    }

    public String getGroupName() {
        return groupName;
    }

    public ImmutableList getRoutes() {
        return routes;
    }

    public String getName() {
        return name;
    }
}