/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can * select the license that you prefer but you may not use this file except in * compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet S.A.S. */ package org.restlet.ext.osgi; import java.util.HashSet; import org.restlet.Context; import org.restlet.Restlet; import org.restlet.routing.Router; import org.restlet.routing.TemplateRoute; /** * This class provides an implementation of {@link RouterProvider}. You register * this class as an OSGi declarative service. The service declaration should * look like: * <p> * * <pre> * {@code * <?xml version="1.0" encoding="UTF-8"?> * <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.example.app.router"> * <implementation class="org.restlet.ext.osgi.BaseRouterProvider"/> * <service> * <provide interface="org.restlet.ext.osgi.RouterProvider"/> * </service> * </scr:component> * } * </pre> * * </p> * <p> * The referenced services are: * <ul> * <li>FilterProvider - optional - policy="static" cardinality="1..1"</li> * <li>DefaultResourceProvider - optional - policy="dynamic" cardinality="0..1"</li> * <li>DefaultRouterProvider - optional - policy="dynamic" cardinality="0..1"</li> * <li>DirectoryProvider - optional - policy="dynamic" cardinality="0..n"</li> * <li>ResourceProvider - optional - policy="dynamic" cardinality="0..n"</li> * </ul> * </p> * <p> * The provided services are: * <ul> * <li>FilterProvider</li> * </ul> * </p> * * @author Bryan Hunt * */ public class BaseRouterProvider extends BaseRestletProvider implements RouterProvider { private RestletProvider defaultRestletProvider; private HashSet<DirectoryProvider> directoryProviders = new HashSet<DirectoryProvider>(); private HashSet<ResourceProvider> resourceProviders = new HashSet<ResourceProvider>(); private Router router; private void attachDirectory(DirectoryProvider directoryProvider) { router.attach(directoryProvider.getPath(), directoryProvider.getInboundRoot(router.getContext())); } private void attachResource(ResourceProvider resourceProvider) { for (String path : resourceProvider.getPaths()) { TemplateRoute templateRoute = router.attach(path, resourceProvider.getInboundRoot(router.getContext())); templateRoute.setMatchingMode(resourceProvider.getMatchingMode()); } } /** * Called by OSGi DS to inject the default resource provider service * * @param resourceProvider * the default resource provider */ public void bindDefaultResourceProvider(ResourceProvider resourceProvider) { defaultRestletProvider = resourceProvider; if (router != null) router.attachDefault(resourceProvider.getInboundRoot(router .getContext())); } /** * Called by OSGi DS to inject the default router provider service * * @param routerProvider * the default router provider */ public void bindDefaultRouterProvider(RouterProvider routerProvider) { defaultRestletProvider = routerProvider; if (router != null) router.attachDefault(routerProvider.getInboundRoot(router .getContext())); } /** * Called by OSGi DS to inject the directory provider service * * @param directoryProvider * the directory provider */ public void bindDirectoryProvider(DirectoryProvider directoryProvider) { directoryProviders.add(directoryProvider); if (router != null) attachDirectory(directoryProvider); } /** * Called by OSGi DS to inject the resource provider service * * @param resourceProvider * the resource provider */ public void bindResourceProvider(ResourceProvider resourceProvider) { resourceProviders.add(resourceProvider); if (router != null) attachResource(resourceProvider); } /** * * @param the * restlet application context * @return the newly created router instance */ protected Router createRouter(Context context) { return new Router(context); } @Override protected Restlet getFilteredRestlet() { return router; } @Override public Restlet getInboundRoot(Context context) { if (router == null) { router = createRouter(context); for (ResourceProvider resourceProvider : resourceProviders) attachResource(resourceProvider); for (DirectoryProvider directoryProvider : directoryProviders) attachDirectory(directoryProvider); if (defaultRestletProvider != null) router.attachDefault(defaultRestletProvider .getInboundRoot(context)); } Restlet inboundRoot = super.getInboundRoot(context); return inboundRoot != null ? inboundRoot : router; } /** * Called by OSGi DS to un-inject the default resource provider service * * @param resourceProvider * the default resource provider */ public void unbindDefaultResourceProvider(ResourceProvider resourceProvider) { if (defaultRestletProvider == resourceProvider) { defaultRestletProvider = null; if (router != null) router.detach(resourceProvider.getInboundRoot(router .getContext())); } } /** * Called by OSGi DS to un-inject the default router provider service * * @param routerProvider * the default router provider */ public void unbindDefaultRouterProvider(RouterProvider routerProvider) { if (defaultRestletProvider == routerProvider) { defaultRestletProvider = routerProvider; if (router != null) router.detach(routerProvider.getInboundRoot(router.getContext())); } } /** * Called by OSGi DS to un-inject the directory provider service * * @param directoryProvider * the directory provider */ public void unbindDirectoryProvider(DirectoryProvider directoryProvider) { if (directoryProviders.remove(directoryProvider)) { if (router != null) router.detach(directoryProvider.getInboundRoot(router .getContext())); } } /** * Called by OSGi DS to un-inject the resource provider service * * @param resourceProvider * the resource provider */ public void unbindResourceProvider(ResourceProvider resourceProvider) { if (resourceProviders.remove(resourceProvider)) { if (router != null) router.detach(resourceProvider.getInboundRoot(router .getContext())); } } }