| /******************************************************************************* |
| * Copyright (c) 2007, 2013 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.equinox.http.registry.internal; |
| |
| import java.lang.reflect.Method; |
| import java.util.*; |
| import javax.servlet.*; |
| import javax.servlet.Filter; |
| import org.eclipse.core.runtime.IContributor; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.osgi.framework.*; |
| import org.osgi.service.http.*; |
| import org.osgi.service.packageadmin.PackageAdmin; |
| |
| public class HttpRegistryManager { |
| |
| class ResourcesContribution { |
| String alias; |
| String baseName; |
| String httpContextId; |
| IContributor contributor; |
| |
| public ResourcesContribution(String alias, String baseName, String httpContextId, IContributor contributor) { |
| this.alias = alias; |
| this.baseName = baseName; |
| this.httpContextId = httpContextId; |
| this.contributor = contributor; |
| } |
| } |
| |
| class ServletContribution { |
| String alias; |
| Servlet servlet; |
| Dictionary initparams; |
| String httpContextId; |
| IContributor contributor; |
| |
| public ServletContribution(String alias, Servlet servlet, Dictionary initparams, String httpContextId, IContributor contributor) { |
| this.alias = alias; |
| this.servlet = servlet; |
| this.initparams = initparams; |
| this.httpContextId = httpContextId; |
| this.contributor = contributor; |
| } |
| } |
| |
| class FilterContribution { |
| String alias; |
| javax.servlet.Filter filter; |
| Dictionary initparams; |
| String httpContextId; |
| IContributor contributor; |
| |
| public FilterContribution(String alias, javax.servlet.Filter filter, Dictionary initparams, String httpContextId, IContributor contributor) { |
| this.alias = alias; |
| this.filter = filter; |
| this.initparams = initparams; |
| this.httpContextId = httpContextId; |
| this.contributor = contributor; |
| } |
| } |
| |
| class HttpContextContribution { |
| HttpContext context; |
| IContributor contributor; |
| |
| public HttpContextContribution(HttpContext context, IContributor contributor) { |
| this.context = context; |
| this.contributor = contributor; |
| } |
| } |
| |
| private HttpContextManager httpContextManager; |
| private ServletManager servletManager; |
| private FilterManager filterManager; |
| private ResourceManager resourceManager; |
| private HttpService httpService; |
| private PackageAdmin packageAdmin; |
| private Map contexts = new HashMap(); |
| private Map filters = new HashMap(); |
| private Map servlets = new HashMap(); |
| private Map resources = new HashMap(); |
| private Set registered = new HashSet(); |
| |
| public HttpRegistryManager(ServiceReference reference, HttpService httpService, PackageAdmin packageAdmin, IExtensionRegistry registry) { |
| this.httpService = httpService; |
| this.packageAdmin = packageAdmin; |
| |
| httpContextManager = new HttpContextManager(this, registry); |
| filterManager = new FilterManager(this, reference, registry); |
| servletManager = new ServletManager(this, reference, registry); |
| resourceManager = new ResourceManager(this, reference, registry); |
| } |
| |
| public void start() { |
| httpContextManager.start(); |
| filterManager.start(); |
| servletManager.start(); |
| resourceManager.start(); |
| } |
| |
| public void stop() { |
| resourceManager.stop(); |
| servletManager.stop(); |
| filterManager.stop(); |
| httpContextManager.stop(); |
| } |
| |
| public synchronized boolean addResourcesContribution(String alias, String baseName, String httpContextId, IContributor contributor) { |
| if (resources.containsKey(alias) || servlets.containsKey(alias)) { |
| System.err.println("ERROR: Duplicate alias. Failed to register resource for [alias=\"" + alias + "\", contributor=\"" + contributor + "\"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return false; |
| } |
| |
| ResourcesContribution contribution = new ResourcesContribution(alias, baseName, httpContextId, contributor); |
| resources.put(alias, contribution); |
| if (httpContextId == null || contexts.containsKey(httpContextId)) |
| registerResources(contribution); |
| |
| return true; |
| } |
| |
| public synchronized boolean addServletContribution(String alias, Servlet servlet, Dictionary initparams, String httpContextId, IContributor contributor) { |
| if (resources.containsKey(alias) || servlets.containsKey(alias)) { |
| System.err.println("ERROR: Duplicate alias. Failed to register servlet for [alias=\"" + alias + "\", contributor=\"" + contributor + "\"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return false; |
| } |
| |
| ServletContribution contribution = new ServletContribution(alias, servlet, initparams, httpContextId, contributor); |
| servlets.put(alias, contribution); |
| if (httpContextId == null || contexts.containsKey(httpContextId)) |
| registerServlet(contribution); |
| |
| return true; |
| } |
| |
| public synchronized void removeContribution(String alias) { |
| resources.remove(alias); |
| servlets.remove(alias); |
| unregister(alias); |
| } |
| |
| public synchronized boolean addFilterContribution(String alias, javax.servlet.Filter filter, Dictionary initparams, String httpContextId, IContributor contributor) { |
| FilterContribution contribution = new FilterContribution(alias, filter, initparams, httpContextId, contributor); |
| return registerFilter(contribution); |
| } |
| |
| public synchronized void removeFilterContribution(Filter filter) { |
| unregisterFilter(filter); |
| } |
| |
| public synchronized HttpContext getHttpContext(String httpContextId, Bundle bundle) { |
| HttpContextContribution contribution = (HttpContextContribution) contexts.get(httpContextId); |
| if (contribution == null) |
| return null; |
| |
| if (System.getSecurityManager() != null) { |
| Bundle httpContextBundle = getBundle(contribution.contributor); |
| AdminPermission resourcePermission = new AdminPermission(httpContextBundle, "resource"); //$NON-NLS-1$ |
| if (!bundle.hasPermission(resourcePermission)) |
| return null; |
| } |
| return contribution.context; |
| } |
| |
| public synchronized boolean addHttpContextContribution(String httpContextId, HttpContext context, IContributor contributor) { |
| if (contexts.containsKey(httpContextId)) { |
| System.err.println("ERROR: Duplicate HttpContextId. Failed to register HttpContext for [httpContextId=\"" + httpContextId + "\", contributor=\"" + contributor + "\"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return false; |
| } |
| |
| contexts.put(httpContextId, new HttpContextContribution(context, contributor)); |
| for (Iterator it = filters.values().iterator(); it.hasNext();) { |
| FilterContribution contribution = (FilterContribution) it.next(); |
| if (httpContextId.equals(contribution.httpContextId)) |
| registerFilter(contribution); |
| } |
| |
| for (Iterator it = resources.values().iterator(); it.hasNext();) { |
| ResourcesContribution contribution = (ResourcesContribution) it.next(); |
| if (httpContextId.equals(contribution.httpContextId)) |
| registerResources(contribution); |
| } |
| |
| for (Iterator it = servlets.values().iterator(); it.hasNext();) { |
| ServletContribution contribution = (ServletContribution) it.next(); |
| if (httpContextId.equals(contribution.httpContextId)) |
| registerServlet(contribution); |
| } |
| return true; |
| } |
| |
| public synchronized void removeHttpContextContribution(String httpContextId) { |
| if (contexts.remove(httpContextId) != null) { |
| for (Iterator it = resources.values().iterator(); it.hasNext();) { |
| ResourcesContribution contribution = (ResourcesContribution) it.next(); |
| if (httpContextId.equals(contribution.httpContextId)) |
| unregister(contribution.alias); |
| } |
| |
| for (Iterator it = servlets.values().iterator(); it.hasNext();) { |
| ServletContribution contribution = (ServletContribution) it.next(); |
| if (httpContextId.equals(contribution.httpContextId)) |
| unregister(contribution.alias); |
| } |
| } |
| } |
| |
| public DefaultRegistryHttpContext createDefaultRegistryHttpContext() { |
| try { |
| HttpContext defaultContext = httpService.createDefaultHttpContext(); |
| return new DefaultRegistryHttpContext(defaultContext); |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| return null; |
| } |
| |
| public Bundle getBundle(IContributor contributor) { |
| return getBundle(contributor.getName()); |
| } |
| |
| public Bundle getBundle(String symbolicName) { |
| Bundle[] bundles = packageAdmin.getBundles(symbolicName, null); |
| if (bundles == null) |
| return null; |
| //Return the first bundle that is not installed or uninstalled |
| for (int i = 0; i < bundles.length; i++) { |
| if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) { |
| return bundles[i]; |
| } |
| } |
| return null; |
| } |
| |
| private void registerResources(ResourcesContribution contribution) { |
| HttpContext context = getHttpContext(contribution.httpContextId, contribution.contributor); |
| if (context == null) |
| return; |
| try { |
| httpService.registerResources(contribution.alias, contribution.baseName, context); |
| registered.add(contribution.alias); |
| } catch (NamespaceException e) { |
| // TODO: should log this |
| e.printStackTrace(); |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| } |
| |
| private void registerServlet(ServletContribution contribution) { |
| HttpContext context = getHttpContext(contribution.httpContextId, contribution.contributor); |
| if (context == null) |
| return; |
| try { |
| httpService.registerServlet(contribution.alias, contribution.servlet, contribution.initparams, context); |
| registered.add(contribution.alias); |
| } catch (NamespaceException e) { |
| // TODO: should log this |
| e.printStackTrace(); |
| } catch (ServletException e) { |
| // TODO: should log this |
| e.printStackTrace(); |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| } |
| |
| private void unregister(String alias) { |
| if (registered.remove(alias)) { |
| try { |
| httpService.unregister(alias); |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| } |
| } |
| |
| private boolean registerFilter(FilterContribution contribution) { |
| HttpContext context = getHttpContext(contribution.httpContextId, contribution.contributor); |
| if (context == null) |
| return false; |
| |
| Method registerFilterMethod = null; |
| try { |
| // First, try the Equinox http service method |
| registerFilterMethod = httpService.getClass().getMethod("registerFilter", new Class[] {String.class, Filter.class, Dictionary.class, HttpContext.class}); //$NON-NLS-1$ |
| registerFilterMethod.invoke(httpService, new Object[] {contribution.alias, contribution.filter, contribution.initparams, context}); |
| return true; |
| } catch (NoSuchMethodException e) { |
| // Give the pax-web HttpService impl a try |
| try { |
| registerFilterMethod = httpService.getClass().getMethod("registerFilter", new Class[] {Filter.class, String[].class, String[].class, Dictionary.class, HttpContext.class}); //$NON-NLS-1$ |
| registerFilterMethod.invoke(httpService, new Object[] {contribution.filter, new String[] {contribution.alias}, null, contribution.initparams, context}); |
| return true; |
| } catch (Throwable t) { |
| // TODO: should log this |
| // for now ignore |
| } |
| // TODO: should log this |
| e.printStackTrace(); |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| return false; |
| } |
| |
| private void unregisterFilter(Filter filter) { |
| try { |
| Method unregisterFilterMethod = httpService.getClass().getMethod("unregisterFilter", new Class[] {Filter.class}); //$NON-NLS-1$ |
| unregisterFilterMethod.invoke(httpService, new Object[] {filter}); |
| } catch (NoSuchMethodException t) { |
| // TODO: should log this |
| // for now ignore |
| } catch (Throwable t) { |
| // TODO: should log this |
| t.printStackTrace(); |
| } |
| } |
| |
| private HttpContext getHttpContext(String httpContextId, IContributor contributor) { |
| if (httpContextId == null) { |
| DefaultRegistryHttpContext defaultContext = createDefaultRegistryHttpContext(); |
| if (defaultContext == null) |
| return null; |
| |
| defaultContext.addResourceMapping(getBundle(contributor), null); |
| return defaultContext; |
| } |
| |
| HttpContextContribution contribution = (HttpContextContribution) contexts.get(httpContextId); |
| if (System.getSecurityManager() != null) { |
| Bundle contributorBundle = getBundle(contributor); |
| Bundle httpContextBundle = getBundle(contribution.contributor); |
| AdminPermission resourcePermission = new AdminPermission(httpContextBundle, "resource"); //$NON-NLS-1$ |
| if (!contributorBundle.hasPermission(resourcePermission)) |
| return null; |
| } |
| return contribution.context; |
| } |
| } |