/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.web.internal; import static org.solmix.api.servlet.ServletManager.SERVLET_NAME; import static org.solmix.api.servlet.ServletManager.SERVLET_PATTERN; import java.util.ArrayList; import java.util.List; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.solmix.web.internal.handler.ServletHandler; /** * * @author solmix.f@gmail.com * @version 110035 2012-4-17 */ public class ServletManagerTracker extends ServiceTracker<Servlet, Servlet> { // TODO: use servlet (&(objectclass=javax.servlet.Servlet)(pattern=*)) private static final String SERVLET_SERVICE_NAME = Servlet.class.getName(); private final List<ServletHandler> handlers = new ArrayList<ServletHandler>(); private final BundleContext context; private final ServletContext servletContext; /** * @param context * @param clazz * @param customizer */ public ServletManagerTracker(BundleContext context, ServletContext servletContext) { super(context, SERVLET_SERVICE_NAME, null); this.context = context; this.servletContext = servletContext; } @Override public Servlet addingService(ServiceReference<Servlet> reference) { super.addingService(reference); return createServlet(reference); } public Servlet getDefaultServlet() { /* Servlet servlet = new StaticResourceServlet(""); try { servlet.init(new SlxServletConfig(this.servletContext, null, "")); } catch (ServletException e) { return null; }*/ return null; } /** * @param reference */ private synchronized Servlet createServlet(ServiceReference<Servlet> reference) { Servlet servlet = context.getService(reference); String name = (String) reference.getProperty(SERVLET_NAME); String pattern = (String) reference.getProperty(SERVLET_PATTERN); if (servlet == null) return null; if (name == null && pattern == null) { return null; } if (name != null && pattern == null) throw new IllegalArgumentException("A registed-Servlet must register with a property named <" + SERVLET_PATTERN + ">"); try { ServletHandler handler = new ServletHandler(this.servletContext, servlet, reference, pattern); checkInsert(handler); handler.init(); } catch (ServletException e) { e.printStackTrace(); } return servlet; } private void checkInsert(ServletHandler handler) { for (int i = 0; i < handlers.size(); i++) { ServletHandler h = handlers.get(i); if (h.subMatches(handler)) { handlers.add(i, handler); break; } } handlers.add(handler); } public Servlet getServlet(String url) { ServletHandler target = ServletHandler.matche(url, handlers); if (target != null) { return target.getServlet(); } return null; } @Override public void removedService(ServiceReference<Servlet> reference, Servlet service) { // fixed bug. super.removedService(reference, service); String pattern = (String) reference.getProperty(SERVLET_PATTERN); if (pattern == null) return; synchronized (handlers) { ServletHandler waitRemove = null; for (ServletHandler handler : handlers) { if (pattern.equals(handler.getPattern())) { waitRemove = handler; break; } } if (waitRemove != null) handlers.remove(waitRemove); } } }