/******************************************************************************* * Copyright (c) 2013 AGETO Service GmbH 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: * Gunnar Wagenknecht - initial API and implementation *******************************************************************************/ package org.eclipse.gyrex.admin.ui.internal.servlets; import java.util.ArrayList; import java.util.List; import org.eclipse.gyrex.admin.ui.internal.jetty.AdminServletHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletMapping; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Tracker for {@link IAdminServlet}. */ public class AdminServletTracker extends ServiceTracker<IAdminServlet, AdminServletHolder> { private static final Logger LOG = LoggerFactory.getLogger(AdminServletTracker.class); private final ServletContextHandler contextHandler; public AdminServletTracker(final BundleContext context, final ServletContextHandler contextHandler) { super(context, IAdminServlet.class, null); this.contextHandler = contextHandler; } @Override public AdminServletHolder addingService(final ServiceReference<IAdminServlet> reference) { final IAdminServlet servlet = context.getService(reference); if (servlet == null) return null; final AdminServletHolder holder = new AdminServletHolder(servlet); final Object alias = reference.getProperty("http.alias"); if (alias instanceof String) { String pathSpec = (String) alias; // convert to path spec if (!StringUtils.endsWith(pathSpec, "/*")) { pathSpec = StringUtils.removeEnd(pathSpec, "/") + "/*"; } try { // register servlet contextHandler.getServletHandler().addServlet(holder); // create, remember & register mapping final ServletMapping mapping = new ServletMapping(); mapping.setPathSpec(pathSpec); mapping.setServletName(holder.getName()); holder.setServletMapping(mapping); contextHandler.getServletHandler().addServletMapping(mapping); } catch (final Exception e) { LOG.error("Error registering contributed servlet {} ({}). {}", reference, pathSpec, ExceptionUtils.getRootCauseMessage(e), e); } } return holder; } @Override public void removedService(final ServiceReference<IAdminServlet> reference, final AdminServletHolder holder) { try { // remove mapping final ServletMapping[] mappings = contextHandler.getServletHandler().getServletMappings(); final List<ServletMapping> newMappings = new ArrayList<>(); for (final ServletMapping servletMapping : mappings) { if (servletMapping != holder.getServletMapping()) { newMappings.add(servletMapping); } } contextHandler.getServletHandler().setServletMappings(newMappings.toArray(new ServletMapping[newMappings.size()])); // remove servlet final ServletHolder[] holders = contextHandler.getServletHandler().getServlets(); final List<ServletHolder> newHolders = new ArrayList<>(); for (final ServletHolder servletHolder : holders) { if (holder != servletHolder) { newHolders.add(servletHolder); } } contextHandler.getServletHandler().setServlets(newHolders.toArray(new ServletHolder[newHolders.size()])); } finally { // unget servlet context.ungetService(reference); } } }