Java tutorial
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2013 ForgeRock AS. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://forgerock.org/license/CDDLv1.0.html * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at http://forgerock.org/license/CDDLv1.0.html * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" */ package org.forgerock.openidm.router; import java.util.Collections; import java.util.Dictionary; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.forgerock.json.resource.CollectionResourceProvider; import org.forgerock.json.resource.RequestHandler; import org.forgerock.json.resource.Route; import org.forgerock.json.resource.Router; import org.forgerock.json.resource.RoutingMode; import org.forgerock.json.resource.SingletonResourceProvider; import org.forgerock.openidm.core.ServerConstants; import org.osgi.framework.Constants; /** * A RouteBuilder does ... * */ public final class RouteBuilder { private final Set<RouteItem> routes; private CollectionResourceProvider collection; private SingletonResourceProvider singleton; private RequestHandler handler; private RoutingMode mode = RoutingMode.EQUALS; private String uriTemplate; private RouteBuilder() { this.routes = new HashSet<RouteItem>(); } private RouteBuilder(Set<RouteItem> initial) { this.routes = initial; } public static RouteBuilder newBuilder() { return new RouteBuilder(); } public RouteBuilder withService(Object service) { if (service instanceof CollectionResourceProvider) { return withCollectionResourceProvider((CollectionResourceProvider) service); } else if (service instanceof SingletonResourceProvider) { return withSingletonResourceProvider((SingletonResourceProvider) service); } else if (service instanceof RequestHandler) { return withRequestHandler((RequestHandler) service); } return this; } public RouteBuilder withServiceAndTemplate(Object service, String uriTemplate) { return bind(service, uriTemplate); } public RouteBuilder withServiceAndTemplate(Object service, String[] uriTemplate) { return bind(service, uriTemplate); } public RouteBuilder bind(Object service, Object routerPrefix) { if (null == routerPrefix || null == service) { return this; } if (routerPrefix.getClass().isArray()) { if (routerPrefix.getClass().getComponentType() == String.class) { for (String pattern : (String[]) routerPrefix) { withService(service).withTemplate(pattern).buildNext(); } } } else if (routerPrefix instanceof String) { withService(service).withTemplate((String) routerPrefix).buildNext(); } return this; } public RouteBuilder withTemplate(String uriTemplate) { if (StringUtils.isNotBlank(uriTemplate)) { if ('*' == uriTemplate.charAt(uriTemplate.length() - 1)) { withModeStartsWith().withTemplate(uriTemplate.substring(0, uriTemplate.length() - 1)); } else { this.uriTemplate = uriTemplate; } } return this; } public RouteBuilder verify() { if ((null == collection) && (null == singleton) && (null == handler)) { throw new NullPointerException("Failed because the service is not set"); } if (StringUtils.isBlank(uriTemplate)) { throw new NullPointerException("Failed because the uriTemplate is not set"); } return this; } public RouteBuilder buildNext() { try { verify(); routes.add(new RouteItem(collection, singleton, handler, mode, uriTemplate)); } catch (NullPointerException e) { /* ignore */ } this.collection = null; this.singleton = null; this.handler = null; this.uriTemplate = null; return withModeEquals(); } public boolean isNotEmpty() { return !routes.isEmpty(); } public RouteBuilder withModeEquals() { this.mode = RoutingMode.EQUALS; return this; } public RouteBuilder withModeStartsWith() { this.mode = RoutingMode.STARTS_WITH; return this; } public RouteBuilder seal() { return new RouteBuilder(Collections.unmodifiableSet(buildNext().routes)); } public Dictionary<String, Object> buildServiceProperties() { if (routes.isEmpty()) { return null; } StringBuilder sb = new StringBuilder("Route group of {"); Dictionary<String, Object> properties = new Hashtable<String, Object>(5); properties.put(Constants.SERVICE_VENDOR, ServerConstants.SERVER_VENDOR_NAME); if (routes.size() == 1) { String template = routes.iterator().next().uriTemplate; sb.append(template); properties.put(ServerConstants.ROUTER_PREFIX, template); } else if (routes.size() > 1) { Object[] params = routes.toArray(); for (int i = 0; i < params.length; i++) { params[i] = ((RouteItem) params[i]).uriTemplate; if (i > 0) { sb.append(", "); } sb.append(params[i]); } properties.put(ServerConstants.ROUTER_PREFIX, params); } properties.put(Constants.SERVICE_DESCRIPTION, sb.append("}").toString()); return properties; } public RouteBuilder withCollectionResourceProvider(CollectionResourceProvider service) { this.collection = service; this.singleton = null; this.handler = null; return this; } public RouteBuilder withSingletonResourceProvider(SingletonResourceProvider service) { this.collection = null; this.singleton = service; this.handler = null; return this; } public RouteBuilder withRequestHandler(RequestHandler service) { this.collection = null; this.singleton = null; this.handler = service; return this; } public Route[] register(Router router) { if (routes.isEmpty()) { return new Route[0]; } Set<Route> registered = new HashSet<Route>(); for (RouteItem r : routes) { Route o = r.register(router); if (null != o) { registered.add(o); } } return registered.toArray(new Route[registered.size()]); } private static class RouteItem { private final CollectionResourceProvider collection; private final SingletonResourceProvider singleton; private final RequestHandler handler; private final RoutingMode mode; private final String uriTemplate; private RouteItem(CollectionResourceProvider collection, SingletonResourceProvider singleton, RequestHandler handler, RoutingMode mode, String uriTemplate) { this.collection = collection; this.singleton = singleton; this.handler = handler; this.mode = mode; this.uriTemplate = uriTemplate; } private Route register(Router router) { if (null != router) { if (null != collection) { return router.addRoute(uriTemplate, collection); } else if (null != singleton) { return router.addRoute(uriTemplate, singleton); } else if (null != handler) { return router.addRoute(mode, uriTemplate, handler); } } return null; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } RouteItem routeItem = (RouteItem) o; if (collection != null ? !collection.equals(routeItem.collection) : routeItem.collection != null) { return false; } if (handler != null ? !handler.equals(routeItem.handler) : routeItem.handler != null) { return false; } if (mode != routeItem.mode) { return false; } if (singleton != null ? !singleton.equals(routeItem.singleton) : routeItem.singleton != null) { return false; } if (!uriTemplate.equals(routeItem.uriTemplate)) { return false; } return true; } @Override public int hashCode() { int result = collection != null ? collection.hashCode() : 0; result = 31 * result + (singleton != null ? singleton.hashCode() : 0); result = 31 * result + (handler != null ? handler.hashCode() : 0); result = 31 * result + mode.hashCode(); result = 31 * result + uriTemplate.hashCode(); return result; } } }